2005-05-26 Jordi Mas i Hernandez <jordi@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeWin32Classic.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2005 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 //
27 //
28
29
30 using System.Drawing;
31 using System.Drawing.Drawing2D;
32 using System.Drawing.Imaging;
33 using System.Drawing.Text;
34
35 namespace System.Windows.Forms
36 {
37
38         internal class ThemeWin32Classic : Theme
39         {               
40                 public override Version Version {\r
41                         get {\r
42                                 return new Version(0, 1, 0, 0);\r
43                         }\r
44                 }\r
45
46
47                 /* Default colors for Win32 classic theme */
48                 uint [] theme_colors = {                                                        /* AARRGGBB */
49                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_SCROLLBAR,                   0xffc0c0c0,
50                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_BACKGROUND,                  0xff008080,
51                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_ACTIVECAPTION,               0xff000080,
52                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_INACTIVECAPTION,             0xff808080,
53                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_MENU,                        0xffc0c0c0,
54                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_WINDOW,                      0xffffffff,
55                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_WINDOWFRAME,                 0xff000000,
56                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_MENUTEXT,                    0xff000000,
57                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_WINDOWTEXT,                  0xff000000,
58                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_CAPTIONTEXT,                 0xffffffff,
59                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_ACTIVEBORDER,                0xffc0c0c0,
60                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_INACTIVEBORDER,              0xffc0c0c0,
61                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_APPWORKSPACE,                0xff808080,
62                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_HIGHLIGHT,                   0xff000080,
63                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_HIGHLIGHTTEXT,               0xffffffff,
64                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_BTNFACE,                     0xffc0c0c0,
65                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_BTNSHADOW,                   0xff808080,
66                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_GRAYTEXT,                    0xff808080,
67                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_BTNTEXT,                     0xff000000,
68                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_INACTIVECAPTIONTEXT,         0xffc0c0c0,
69                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_BTNHIGHLIGHT,                0xffffffff,
70                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_3DDKSHADOW,                  0xff000000,                     
71                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_3DLIGHT,                     0xffe0e0e0,
72                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_INFOTEXT,                    0xff000000,
73                         (uint) XplatUIWin32.GetSysColorIndex.COLOR_INFOBK,                      0xffffffff,
74                   
75                 };              
76                                 
77                 /* Hardcoded colour values not exposed in the API constants in all configurations */
78                 static readonly Color arrow_color = Color.Black;
79                 static readonly Color pen_ticks_color = Color.Black;
80                 static readonly Color progressbarblock_color = Color.FromArgb (255, 0, 0, 128);
81                 static StringFormat string_format_menu_text;
82                 static StringFormat string_format_menu_shortcut;
83                 static StringFormat string_format_menu_menubar_text;
84                 static readonly Rectangle checkbox_rect = new Rectangle (2, 2, 11,11); // Position of the checkbox relative to the item
85                 static ImageAttributes imagedisabled_attributes = null;
86                 const int SEPARATOR_HEIGHT = 5;
87                 const int SM_CXBORDER = 1;
88                 const int SM_CYBORDER = 1;              
89                 const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tab
90                 const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
91
92                 #region Principal Theme Methods
93                 public ThemeWin32Classic ()
94                 {                       
95                         /* Init Default colour array*/
96                         syscolors =  Array.CreateInstance (typeof (Color), (uint) XplatUIWin32.GetSysColorIndex.COLOR_MAXVALUE+1);
97                         
98                         for (int i = 0; i < theme_colors.Length; i +=2) 
99                                 syscolors.SetValue (Color.FromArgb ((int)theme_colors[i+1]), (int) theme_colors[i]);                    
100
101                         defaultWindowBackColor = SystemColors.Window;
102                         defaultWindowForeColor = ColorButtonText;
103                         default_font =  new Font (FontFamily.GenericSansSerif, 8.25f);
104                         
105                         /* Menu string formats */
106                         string_format_menu_text = new StringFormat ();
107                         string_format_menu_text.LineAlignment = StringAlignment.Center;
108                         string_format_menu_text.Alignment = StringAlignment.Near;
109                         string_format_menu_text.HotkeyPrefix = HotkeyPrefix.Show;
110
111                         string_format_menu_shortcut = new StringFormat ();      
112                         string_format_menu_shortcut.LineAlignment = StringAlignment.Center;
113                         string_format_menu_shortcut.Alignment = StringAlignment.Far;
114
115                         string_format_menu_menubar_text = new StringFormat ();
116                         string_format_menu_menubar_text.LineAlignment = StringAlignment.Center;
117                         string_format_menu_menubar_text.Alignment = StringAlignment.Center;
118                         string_format_menu_menubar_text.HotkeyPrefix = HotkeyPrefix.Show;
119                 }       
120
121                 public override void ResetDefaults() {
122                         throw new NotImplementedException("Need to implement ResetDefaults() for Win32 theme");
123                 }
124
125                 public override bool DoubleBufferingSupported {
126                         get {return true; }
127                 }
128                 #endregion      // Principal Theme Methods
129
130                 #region Internal Methods
131                 protected SolidBrush GetControlBackBrush (Color c) {
132                         if (c == DefaultControlBackColor)
133                                 return ResPool.GetSolidBrush (ColorButtonFace);
134                         return new SolidBrush (c);
135                 }
136
137                 protected SolidBrush GetControlForeBrush (Color c) {
138                         if (c == DefaultControlForeColor)
139                                 return ResPool.GetSolidBrush (ColorButtonText);
140                         return new SolidBrush (c);
141                 }
142                 #endregion      // Internal Methods
143
144                 #region OwnerDraw Support
145                 public  override void DrawOwnerDrawBackground (DrawItemEventArgs e)
146                 {
147                         if (e.State == DrawItemState.Selected) {
148                                 e.Graphics.FillRectangle (SystemBrushes.Highlight, e.Bounds);
149                                 return;
150                         }
151
152                         e.Graphics.FillRectangle (GetControlBackBrush (e.BackColor), e.Bounds);
153                 }
154
155                 public  override void DrawOwnerDrawFocusRectangle (DrawItemEventArgs e)
156                 {
157                         if (e.State == DrawItemState.Focus)
158                                 CPDrawFocusRectangle (e.Graphics, e.Bounds, e.ForeColor, e.BackColor);
159                 }
160                 #endregion      // OwnerDraw Support
161
162                 #region ButtonBase
163                 public override void DrawButtonBase(Graphics dc, Rectangle clip_area, ButtonBase button) {
164                         int             width;
165                         int             height;
166                         Rectangle buttonRectangle;
167                         Rectangle borderRectangle;
168
169                         width = button.ClientSize.Width;
170                         height = button.ClientSize.Height;
171                         
172                         dc.FillRectangle(ResPool.GetSolidBrush (button.BackColor), button.ClientRectangle);                     
173                         
174                         // set up the button rectangle
175                         buttonRectangle = button.ClientRectangle;
176                         if (button.has_focus) {
177                                 // shrink the rectangle for the normal button drawing inside the focus rectangle
178                                 borderRectangle = Rectangle.Inflate(buttonRectangle, -1, -1);
179                         } else {
180                                 borderRectangle = buttonRectangle;
181                         }
182
183                         if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
184                                 DrawFlatStyleButton (dc, borderRectangle, button);
185                         } else {
186                                 CPDrawButton(dc, borderRectangle, button.ButtonState);                          
187                         }
188                         
189                         // First, draw the image
190                         if ((button.image != null) || (button.image_list != null)) {
191                                 // Need to draw a picture
192                                 Image   i;
193                                 int     image_x;
194                                 int     image_y;
195                                 int     image_width;
196                                 int     image_height;
197
198                                 if (button.ImageIndex!=-1) {    // We use ImageIndex instead of image_index since it will return -1 if image_list is null
199                                         i = button.image_list.Images[button.image_index];
200                                 } else {
201                                         i = button.image;
202                                 }
203
204                                 image_width = button.image.Width;
205                                 image_height = button.image.Height;
206
207                                 switch(button.image_alignment) {
208                                 case ContentAlignment.TopLeft: {
209                                         image_x=0;
210                                         image_y=0;
211                                         break;
212                                 }
213
214                                 case ContentAlignment.TopCenter: {
215                                         image_x=(width-image_width)/2;
216                                         image_y=0;
217                                         break;
218                                 }
219
220                                 case ContentAlignment.TopRight: {
221                                         image_x=width-image_width;
222                                         image_y=0;
223                                         break;
224                                 }
225
226                                 case ContentAlignment.MiddleLeft: {
227                                         image_x=0;
228                                         image_y=(height-image_height)/2;
229                                         break;
230                                 }
231
232                                 case ContentAlignment.MiddleCenter: {
233                                         image_x=(width-image_width)/2;
234                                         image_y=(height-image_height)/2;
235                                         break;
236                                 }
237
238                                 case ContentAlignment.MiddleRight: {
239                                         image_x=width-image_width;
240                                         image_y=(height-image_height)/2;
241                                         break;
242                                 }
243
244                                 case ContentAlignment.BottomLeft: {
245                                         image_x=0;
246                                         image_y=height-image_height;
247                                         break;
248                                 }
249
250                                 case ContentAlignment.BottomCenter: {
251                                         image_x=(width-image_width)/2;
252                                         image_y=height-image_height;
253                                         break;
254                                 }
255
256                                 case ContentAlignment.BottomRight: {
257                                         image_x=width-image_width;
258                                         image_y=height-image_height;
259                                         break;
260                                 }
261
262                                 default: {
263                                         image_x=0;
264                                         image_y=0;
265                                         break;
266                                 }
267                                 }
268
269                                 if (button.is_pressed) {
270                                         image_x+=1;
271                                         image_y+=1;
272                                 }
273
274                                 if (button.is_enabled) {
275                                         dc.DrawImage(i, image_x, image_y); 
276                                 } else {
277                                         CPDrawImageDisabled(dc, i, image_x, image_y, ColorButtonFace);
278                                 }
279                         }
280                         
281                         // Draw the focus rectangle
282                         if (button.has_focus) {
283                                 if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
284                                         DrawFlatStyleFocusRectangle (dc, button.ClientRectangle, button, button.ForeColor, button.BackColor);
285                                 } else { 
286                                         CPDrawFocusRectangle(dc, button.ClientRectangle, button.ForeColor, button.BackColor);
287                                 }
288                         }
289                         
290                         // Now the text
291                         if (button.text != null && button.text != String.Empty) {
292                                 Rectangle text_rect = Rectangle.Inflate(buttonRectangle, -4, -4);
293
294                                 if (button.is_pressed) {
295                                         text_rect.X++;
296                                         text_rect.Y++;
297                                 }
298
299                                 if (button.is_enabled) {                                        
300                                         dc.DrawString(button.text, button.Font, ResPool.GetSolidBrush (button.ForeColor), text_rect, button.text_format);
301                                         
302                                 } else {
303                                         if (button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup) {
304                                                 dc.DrawString(button.text, button.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorButtonFace)), text_rect, button.text_format);
305                                         } else {
306                                                 CPDrawStringDisabled(dc, button.text, button.Font, ColorButtonText, text_rect, button.text_format);
307                                         }
308                                 }
309                         }
310                 }
311                 
312                 // draw the flat style part of the rectangle
313                 public void DrawFlatStyleButton (Graphics graphics, Rectangle rectangle, ButtonBase button) {
314                         Color rect_back_color = button.BackColor;
315                         Color rect_fore_color = button.ForeColor;
316                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
317                                 
318                         if (button.Enabled) {
319                                 if (button.Capture || button.is_entered) {
320                                         if (button.FlatStyle == FlatStyle.Flat) {
321                                                 // fill the rectangle
322                                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
323                                                 
324                                                 // now draw the outer border
325                                                 if (button.Capture && button.is_entered) {
326                                                         rect_back_color = ControlPaint.LightLight (rect_back_color);
327                                                 } else {
328                                                         rect_back_color = ControlPaint.Light (rect_back_color);
329                                                 }
330                                                 
331                                                 // draw rectangle and fill it
332                                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
333                                                 graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
334                                         } else {
335                                                 // else it must be a popup button
336                                                 
337                                                 if (button.Capture && button.is_entered) {
338                                                         graphics.DrawRectangle(ResPool.GetPen (this.ColorButtonText), trace_rectangle);
339                                                 } else {
340                                                         // draw a 3d border
341                                                         CPDrawBorder3D (graphics, rectangle, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top, button.BackColor); 
342                                                         graphics.DrawLine ( ResPool.GetPen (this.ColorButtonText), trace_rectangle.X, trace_rectangle.Bottom, trace_rectangle.Right, trace_rectangle.Bottom);
343                                                         graphics.DrawLine ( ResPool.GetPen (this.ColorButtonText), trace_rectangle.Right, trace_rectangle.Y, trace_rectangle.Right, trace_rectangle.Bottom);
344                                                 }
345                                         }
346                                         
347                                         // TODO: draw inner focus rectangle
348                                         
349                                 } else {
350                                         // popup has a ButtonColorText forecolor, not a button.ForeCOlor
351                                         if (button.FlatStyle == FlatStyle.Popup) {
352                                                 rect_fore_color = this.ColorButtonText;
353                                         }
354                                         
355                                         // fill then draw outer rect
356                                         graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
357                                         graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
358                                 }
359                                 
360                                 // finally some small tweaks to render radiobutton and checkbox
361                                 CheckBox checkbox = button as CheckBox;
362                                 RadioButton radiobutton = button as RadioButton;
363                                 if ((checkbox != null && checkbox.Checked) ||
364                                         (radiobutton != null && radiobutton.Checked)) {
365                                         if (button.FlatStyle == FlatStyle.Flat && button.is_entered && !button.Capture) {
366                                                 // render the hover for flat flatstyle and cheked
367                                                 graphics.DrawRectangle(ResPool.GetPen (this.ColorButtonText), trace_rectangle);
368                                         } else if (!button.is_entered && !button.Capture) {
369                                                 // render the checked state for popup when unhovered
370                                                 CPDrawBorder3D (graphics, rectangle, Border3DStyle.SunkenInner, Border3DSide.Right | Border3DSide.Bottom, button.BackColor); 
371                                         }
372                                 }
373                         } else {
374                                 // rendering checkbox or radio button style buttons
375                                 CheckBox checkbox = button as CheckBox;
376                                 RadioButton radiobutton = button as RadioButton;
377                                 bool draw_popup_checked = false;
378                                 
379                                 if (button.FlatStyle == FlatStyle.Popup) {
380                                         rect_fore_color = this.ColorButtonText;
381                                 
382                                         // see if we should draw a disabled checked popup button
383                                         draw_popup_checked = ((checkbox != null && checkbox.Checked) ||
384                                                 (radiobutton != null && radiobutton.Checked));
385                                 }
386                                 
387                                 graphics.FillRectangle (ResPool.GetSolidBrush (rect_back_color), rectangle);
388                                 graphics.DrawRectangle(ResPool.GetPen (rect_fore_color), trace_rectangle);
389                                 
390                                 // finally draw the flatstyle checked effect if need
391                                 if (draw_popup_checked) {
392                                         // render the checked state for popup when unhovered
393                                         CPDrawBorder3D (graphics, rectangle, Border3DStyle.SunkenInner, Border3DSide.Right | Border3DSide.Bottom, button.BackColor);
394                                 }
395                         }
396                 }
397
398                 public override Size ButtonBaseDefaultSize {
399                         get {
400                                 return new Size (75, 23);
401                         }
402                 }
403                 #endregion      // ButtonBase
404
405                 #region CheckBox
406                 public override void DrawCheckBox(Graphics dc, Rectangle clip_area, CheckBox checkbox) {
407                         StringFormat            text_format;
408                         Rectangle               client_rectangle;
409                         Rectangle               text_rectangle;
410                         Rectangle               checkbox_rectangle;
411                         SolidBrush              sb;
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                         
577                         // Start drawing
578                         
579                         dc.FillRectangle (ResPool.GetSolidBrush (checkbox.BackColor), checkbox.ClientRectangle);                        
580                         // render as per normal button
581                         if (checkbox.appearance==Appearance.Button) {
582                                 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
583                                         DrawFlatStyleButton(dc, checkbox.ClientRectangle, checkbox);
584                                 } else {
585                                         CPDrawButton(dc, checkbox.ClientRectangle, state);
586                                 }
587                         } else {
588                                 // establish if we are rendering a flat style of some sort
589                                 if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
590                                         DrawFlatStyleCheckBox (dc, checkbox_rectangle, checkbox);
591                                 } else {
592                                         ControlPaint.DrawCheckBox(dc, checkbox_rectangle, state);
593                                 }
594                         }
595                         
596                         // offset the text if it's pressed and a button
597                         if (checkbox.Appearance == Appearance.Button) {
598                                 if (checkbox.Checked || (checkbox.Capture && checkbox.FlatStyle != FlatStyle.Flat)) {
599                                         text_rectangle.X ++;
600                                         text_rectangle.Y ++;
601                                 }
602                                 
603                                 text_rectangle.Inflate(-4, -4);
604                         }
605                         
606                         /* Place the text; to be compatible with Windows place it after the checkbox has been drawn */
607                         if (checkbox.Enabled) {
608                                 sb = ResPool.GetSolidBrush(checkbox.ForeColor);
609                                 dc.DrawString(checkbox.Text, checkbox.Font, sb, text_rectangle, text_format);                           
610                         } else if (checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup) {
611                                 dc.DrawString(checkbox.Text, checkbox.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorButtonFace)), text_rectangle, text_format);
612                         } else {
613                                 CPDrawStringDisabled(dc, checkbox.Text, checkbox.Font, ColorButtonText, text_rectangle, text_format);
614                         }
615
616                         if (checkbox.Focused) {
617                                 if (checkbox.FlatStyle != FlatStyle.Flat) {
618                                         DrawInnerFocusRectangle (dc, Rectangle.Inflate (text_rectangle, -1, -1), checkbox.BackColor);
619                                 } else {
620                                         dc.DrawRectangle (ResPool.GetPen (checkbox.ForeColor), Rectangle.Inflate (text_rectangle, -1, -1));
621                                 }
622                         }
623                 }
624
625                 // renders a checkBox with the Flat and Popup FlatStyle
626                 private void DrawFlatStyleCheckBox (Graphics graphics, Rectangle rectangle, CheckBox checkbox)
627                 {
628                         Pen                     pen;                    
629                         Rectangle       rect;
630                         Rectangle       checkbox_rectangle;
631                         Rectangle       fill_rectangle;
632                         int                     lineWidth;
633                         int                     Scale;
634                         
635                         // set up our rectangles first
636                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered) {
637                                 // clip one pixel from bottom right for non popup rendered checkboxes
638                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-1, 0), Math.Max(rectangle.Height-1,0));
639                                 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));
640                         } else {
641                                 // clip two pixels from bottom right for non popup rendered checkboxes
642                                 checkbox_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max(rectangle.Width-2, 0), Math.Max(rectangle.Height-2,0));
643                                 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));
644                         }       
645                                 
646                         // if disabled render in disabled state
647                         if (checkbox.Enabled) {
648                                 // process the state of the checkbox
649                                 if (checkbox.is_entered || checkbox.Capture) {
650                                         // decide on which background color to use
651                                         if (checkbox.FlatStyle == FlatStyle.Popup && checkbox.is_entered && checkbox.Capture) {
652                                                 graphics.FillRectangle(ResPool.GetSolidBrush (checkbox.BackColor), fill_rectangle);
653                                         } else if (checkbox.FlatStyle == FlatStyle.Flat && !(checkbox.is_entered && checkbox.Capture)) {
654                                                 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.Light(checkbox.BackColor)), fill_rectangle);
655                                         } else {
656                                                 // use regular window background color
657                                                 graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);
658                                         }
659                                         
660                                         // render the outer border
661                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
662                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
663                                         } else {
664                                                 // draw sunken effect
665                                                 CPDrawBorder3D (graphics, checkbox_rectangle, Border3DStyle.SunkenInner, Border3DSide.All, checkbox.BackColor);
666                                         }
667                                 } else {
668                                         graphics.FillRectangle(ResPool.GetSolidBrush (ControlPaint.LightLight (checkbox.BackColor)), fill_rectangle);                           
669                                         
670                                         if (checkbox.FlatStyle == FlatStyle.Flat) {
671                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, checkbox.ForeColor, ButtonBorderStyle.Solid);
672                                         } else {
673                                                 // draw the outer border
674                                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ControlPaint.DarkDark (checkbox.BackColor), ButtonBorderStyle.Solid);
675                                         }                       
676                                 }
677                         } else {
678                                 if (checkbox.FlatStyle == FlatStyle.Popup) {
679                                         graphics.FillRectangle(SystemBrushes.Control, fill_rectangle);
680                                 }       
681                         
682                                 // draw disabled state,
683                                 ControlPaint.DrawBorder(graphics, checkbox_rectangle, ColorButtonShadow, ButtonBorderStyle.Solid);
684                         }               
685                         
686                         /* Make sure we've got at least a line width of 1 */
687                         lineWidth = Math.Max(3, fill_rectangle.Width/3);
688                         Scale=Math.Max(1, fill_rectangle.Width/9);
689                         
690                         // flat style check box is rendered inside a rectangle shifted down by one
691                         rect=new Rectangle(fill_rectangle.X, fill_rectangle.Y+1, fill_rectangle.Width, fill_rectangle.Height);
692                         if (checkbox.Enabled) {
693                                 pen=ResPool.GetPen(checkbox.ForeColor);
694                         } else {
695                                 pen=SystemPens.ControlDark;
696                         }
697
698                         if (checkbox.Checked) {
699                                 /* Need to draw a check-mark */
700                                 for (int i=0; i<lineWidth; i++) {
701                                         graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
702                                         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);
703                                 }
704                         }                                       
705                 }
706
707
708                 #endregion      // CheckBox
709                 
710                 #region CheckedListBox
711                 
712                 public override Rectangle CheckedListBoxCheckRectangle ()
713                 {
714                         return checkbox_rect;
715                 }
716                 
717                 public override void DrawCheckedListBoxItem (CheckedListBox ctrl, DrawItemEventArgs e)
718                 {                       
719                         Color back_color, fore_color;
720                         Rectangle item_rect = e.Bounds;
721                         ButtonState state;
722                         StringFormat string_format = ctrl.GetFormatString ();
723
724                         /* Draw checkbox */             
725
726                         if ((ctrl.Items.GetListBoxItem (e.Index)).State == CheckState.Checked)
727                                 state = ButtonState.Checked;
728                         else
729                                 state = ButtonState.Normal;
730
731                         if (ctrl.ThreeDCheckBoxes == false)
732                                 state |= ButtonState.Flat;
733
734                         ControlPaint.DrawCheckBox (e.Graphics,
735                                 item_rect.X + checkbox_rect.X, item_rect.Y + checkbox_rect.Y,
736                                 checkbox_rect.Width, checkbox_rect.Height,
737                                 state);
738
739                         item_rect.X += checkbox_rect.Width + checkbox_rect.X * 2;
740                         item_rect.Width -= checkbox_rect.Width + checkbox_rect.X * 2;
741                         
742                         /* Draw text*/
743                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
744                                 back_color = ThemeEngine.Current.ColorHilight;
745                                 fore_color = ThemeEngine.Current.ColorHilightText;
746                         }
747                         else {
748                                 back_color = e.BackColor;
749                                 fore_color = e.ForeColor;
750                         }
751                         
752                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
753                                 (back_color), item_rect);
754
755                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
756                                 ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
757                                 item_rect, string_format);
758                                         
759                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
760                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, item_rect,
761                                         fore_color, back_color);
762                         }
763                 }
764                 
765                 #endregion // CheckedListBox
766                 
767                 #region ComboBox
768                 
769                 // Drawing
770                 
771                 public override void DrawComboBoxEditDecorations (Graphics dc, ComboBox ctrl, Rectangle cl)
772                 {                               
773                         dc.DrawLine (ResPool.GetPen (ColorButtonShadow), cl.X, cl.Y, cl.X + cl.Width, cl.Y); //top 
774                         dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), cl.X + 1, cl.Y + 1, cl.X + cl.Width - 2, cl.Y + 1);
775                         dc.DrawLine (ResPool.GetPen (ColorButtonFace), cl.X, cl.Y + cl.Height - 2, cl.X + cl.Width, cl.Y + cl.Height - 2); //down
776                         dc.DrawLine (ResPool.GetPen (ColorButtonHilight), cl.X, cl.Y + cl.Height - 1, cl.X + cl.Width, cl.Y + cl.Height - 1);
777                         dc.DrawLine (ResPool.GetPen (ColorButtonShadow), cl.X, cl.Y, cl.X, cl.Y + cl.Height); //left
778                         dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), cl.X + 1, cl.Y + 1, cl.X + 1, cl.Y + cl.Height - 2); 
779                         dc.DrawLine (ResPool.GetPen (ColorButtonFace), cl.X + cl.Width - 2, cl.Y, cl.X + cl.Width - 2, cl.Y + cl.Height); //right
780                         dc.DrawLine (ResPool.GetPen (ColorButtonHilight), cl.X + cl.Width - 1, cl.Y + 1 , cl.X + cl.Width - 1, cl.Y + cl.Height - 1);                           
781                 }               
782                 
783                 // Sizing                               
784                 public override int DrawComboBoxEditDecorationTop () { return 2;}
785                 public override int DrawComboBoxEditDecorationBottom () { return 2;}
786                 public override int DrawComboBoxEditDecorationRight () { return 2;}
787                 public override int DrawComboBoxEditDecorationLeft () { return 2;}
788                 
789                 private int DrawComboListBoxDecoration (ComboBoxStyle style)
790                 {
791                         if (style == ComboBoxStyle.Simple)
792                                 return 2;
793                         else
794                                 return 1;
795                 }
796                                 
797                 public override int DrawComboListBoxDecorationTop (ComboBoxStyle style) 
798                 {
799                         return DrawComboListBoxDecoration (style);
800                 }
801                 
802                 public override int DrawComboListBoxDecorationBottom (ComboBoxStyle style)
803                 {
804                         return DrawComboListBoxDecoration (style);
805                 }
806                 
807                 public override int DrawComboListBoxDecorationRight (ComboBoxStyle style)
808                 {
809                         return DrawComboListBoxDecoration (style);
810                 }
811                 
812                 public override int DrawComboListBoxDecorationLeft (ComboBoxStyle style)
813                 {
814                         return DrawComboListBoxDecoration (style);
815                 }
816                 
817                 public override void DrawComboListBoxDecorations (Graphics dc, ComboBox ctrl, Rectangle cl)
818                 {
819                         if (ctrl.DropDownStyle == ComboBoxStyle.Simple) {
820                                 DrawComboBoxEditDecorations (dc, ctrl, cl);
821                         }
822                         else {                  
823                                 dc.DrawRectangle (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorWindowFrame),
824                                         cl.X, cl.Y, cl.Width - 1, cl.Height - 1);
825                         }                       
826                 }
827                 
828                 public override void DrawComboBoxItem (ComboBox ctrl, DrawItemEventArgs e)
829                 {
830                         Color back_color, fore_color;
831                         Rectangle text_draw = e.Bounds;
832                         StringFormat string_format = new StringFormat ();
833                         string_format.FormatFlags = StringFormatFlags.LineLimit;
834                         
835                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
836                                 back_color = ThemeEngine.Current.ColorHilight;
837                                 fore_color = ThemeEngine.Current.ColorHilightText;
838                         }
839                         else {
840                                 back_color = e.BackColor;
841                                 fore_color = e.ForeColor;
842                         }                       
843                                                         
844                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (back_color), e.Bounds);
845
846                         if (e.Index != -1) {
847                                 e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
848                                         ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
849                                         text_draw, string_format);
850                         }
851                         
852                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
853                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, e.Bounds, fore_color, back_color);
854                         }
855                 }
856                 
857                 #endregion ComboBox
858                 
859                 #region Datagrid
860                 public override int DataGridPreferredColumnWidth { get { return 75;} }
861                 public override int DataGridMinimumColumnCheckBoxHeight { get { return 16;} }
862                 public override int DataGridMinimumColumnCheckBoxWidth { get { return 16;} }
863                 public override Color DataGridAlternatingBackColor { get { return ColorWindow;} }
864                 public override Color DataGridBackgroundColor { get  { return ColorWindow;} }
865                 public override Color DataGridCaptionBackColor { get  { return ColorActiveTitle;} }
866                 public override Color DataGridCaptionForeColor { get  { return SystemColors.ActiveCaptionText;} }
867                 public override Color DataGridGridLineColor { get { return SystemColors.Control;} }
868                 public override Color DataGridHeaderBackColor { get  { return SystemColors.Control;} }
869                 public override Color DataGridHeaderForeColor { get  { return SystemColors.ControlText;} }
870                 public override Color DataGridLinkColor { get  { return SystemColors.HotTrack;} }
871                 public override Color DataGridLinkHoverColor { get  { return SystemColors.HotTrack;} }
872                 public override Color DataGridParentRowsBackColor { get  { return SystemColors.Control;} }
873                 public override Color DataGridParentRowsForeColor { get  { return SystemColors.WindowText;} }
874                 public override Color DataGridSelectionBackColor { get  { return ColorActiveTitle;} }
875                 public override Color DataGridSelectionForeColor { get  { return ColorTitleText;} }
876                 #endregion // Datagrid
877                 
878                 #region DateTimePicker
879         
880                 public override void DrawDateTimePicker (Graphics dc,  Rectangle clip_rectangle, DateTimePicker dtp) {
881                         // if not showing the numeric updown control then render border
882                         if (!dtp.ShowUpDown && clip_rectangle.IntersectsWith (dtp.ClientRectangle)) {
883                                 // draw the outer border
884                                 Rectangle button_bounds = dtp.ClientRectangle;
885                                 this.CPDrawBorder3D (dc, button_bounds, Border3DStyle.Sunken, Border3DSide.All, dtp.BackColor);
886                                 
887                                 // deflate by the border width
888                                 if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
889                                         button_bounds.Inflate (-2,-2);
890                                         ButtonState state = dtp.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
891                                         this.CPDrawComboButton ( 
892                                           dc, 
893                                           dtp.drop_down_arrow_rect, 
894                                           state);
895                                 }
896                         }
897
898                         // render the date part
899                         if (clip_rectangle.IntersectsWith (dtp.date_area_rect)) {
900                                 // fill the background
901                                 dc.FillRectangle (ResPool.GetSolidBrush (ThemeEngine.Current.ColorWindow), dtp.date_area_rect);
902                                 
903                                 // fill the currently highlighted area
904                                 if (dtp.hilight_date_area != Rectangle.Empty) {
905                                         dc.FillRectangle (ResPool.GetSolidBrush (ThemeEngine.Current.ColorHilight), dtp.hilight_date_area);
906                                 }
907                                 
908                                 // draw the text part
909                                 // TODO: if date format is CUstom then we need to draw the dates as separate parts
910                                 StringFormat text_format = new StringFormat();
911                                 text_format.LineAlignment = StringAlignment.Center;
912                                 text_format.Alignment = StringAlignment.Near;                                   
913                                 dc.DrawString (dtp.Text, dtp.Font, ResPool.GetSolidBrush (dtp.ForeColor), Rectangle.Inflate(dtp.date_area_rect, -1, -1), text_format);
914                         }
915                 }
916                 
917                 #endregion // DateTimePicker
918
919                 #region GroupBox
920                 public override void DrawGroupBox (Graphics dc,  Rectangle area, GroupBox box) {
921                         StringFormat    text_format;
922                         SizeF           size;
923                         int             width;
924                         int             y;
925                         Rectangle       rect;
926
927                         rect = box.ClientRectangle;
928
929                         // Needed once the Dark/Light code below is enabled again
930                         //Color disabled = ColorGrayText;
931                         
932                         Pen pen_light = ResPool.GetPen (Color.FromArgb (255,255,255,255));
933                         Pen pen_dark = ResPool.GetPen (Color.FromArgb (255, 128, 128,128));
934                         
935                         // TODO: When the Light and Dark methods work this code should be activate it
936                         //Pen pen_light = new Pen (ControlPaint.Light (disabled, 1));
937                         //Pen pen_dark = new Pen (ControlPaint.Dark (disabled, 0));
938
939                         dc.FillRectangle (ResPool.GetSolidBrush (box.BackColor), rect);
940
941                         text_format = new StringFormat();
942                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
943
944                         size = dc.MeasureString (box.Text, box.Font);
945                         width = (int) size.Width;
946                         
947                         if (width > box.Width - 16)
948                                 width = box.Width - 16;
949                         
950                         y = box.Font.Height / 2;
951                         
952                         /* Draw group box*/
953                         dc.DrawLine (pen_dark, 0, y, 8, y); // top 
954                         dc.DrawLine (pen_light, 0, y + 1, 8, y + 1);                    
955                         dc.DrawLine (pen_dark, 8 + width, y, box.Width, y);                     
956                         dc.DrawLine (pen_light, 8 + width, y + 1, box.Width, y + 1);
957                         
958                         dc.DrawLine (pen_dark, 0, y + 1, 0, box.Height); // left
959                         dc.DrawLine (pen_light, 1, y + 1, 1, box.Height);                       
960                         
961                         dc.DrawLine (pen_dark, 0, box.Height - 2, box.Width,  box.Height - 2); // bottom
962                         dc.DrawLine (pen_light, 0, box.Height - 1, box.Width,  box.Height - 1);
963                         
964                         dc.DrawLine (pen_dark, box.Width - 2, y,  box.Width - 2, box.Height - 2); // right
965                         dc.DrawLine (pen_light, box.Width - 1, y, box.Width - 1, box.Height - 2);
966                         
967                         
968                         /* Text */
969                         if (box.Enabled) {
970                                 dc.DrawString (box.Text, box.Font, new SolidBrush (box.ForeColor), 10, 0, text_format);
971                         } else {
972                                 CPDrawStringDisabled (dc, box.Text, box.Font, box.ForeColor, 
973                                         new RectangleF (10, 0, width,  box.Font.Height), text_format);
974                         }
975                                 
976                 }
977
978                 public override Size GroupBoxDefaultSize {
979                         get {
980                                 return new Size (200,100);
981                         }
982                 }
983                 #endregion
984
985                 #region HScrollBar
986                 public override Size HScrollBarDefaultSize {
987                         get {
988                                 return new Size (80, this.ScrollBarButtonSize);
989                         }
990                 }
991
992                 #endregion      // HScrollBar
993
994                 #region Label
995                 public  override void DrawLabel (Graphics dc, Rectangle clip_rectangle, Label label) 
996                 {               
997                         dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);
998                         
999                         CPDrawBorderStyle (dc, label.ClientRectangle, label.BorderStyle);               
1000
1001                         if (label.Enabled) {
1002                                 dc.DrawString (label.Text, label.Font, ResPool.GetSolidBrush (label.ForeColor), clip_rectangle, label.string_format);
1003                         } else {
1004                                 ControlPaint.DrawStringDisabled (dc, label.Text, label.Font, label.ForeColor, clip_rectangle, label.string_format);
1005                         }
1006                 
1007                 }
1008
1009                 public override Size LabelDefaultSize {
1010                         get {
1011                                 return new Size (100, 23);
1012                         }
1013                 }
1014                 #endregion      // Label\r
1015 \r
1016                 #region LinkLabel\r
1017                 public  override void DrawLinkLabel (Graphics dc, Rectangle clip_rectangle, LinkLabel label)\r
1018                 {\r
1019                         Color color;\r
1020 \r
1021                         dc.FillRectangle (ResPool.GetSolidBrush (label.BackColor), clip_rectangle);\r
1022                         CPDrawBorderStyle (dc, label.ClientRectangle, label.BorderStyle);                                               
1023 \r
1024                         for (int i = 0; i < label.num_pieces; i++) {
1025                                 
1026                                 if (clip_rectangle.IntersectsWith (label.pieces[i].rect) == false) {
1027                                         continue;
1028                                 }                               
1029                                 \r
1030                                 color = label.GetLinkColor (label.pieces[i], i);\r
1031 \r
1032                                 if (label.pieces[i].link == null)\r
1033                                         dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (Color.Black),\r
1034                                                 label.pieces[i].rect.X, label.pieces[i].rect.Y);\r
1035                                 else\r
1036                                         dc.DrawString (label.pieces[i].text, label.GetPieceFont (label.pieces[i]), ResPool.GetSolidBrush (color),\r
1037                                                 label.pieces[i].rect.X, label.pieces[i].rect.Y);
1038                                                 
1039                                 if (label.pieces[i].focused) {                                  
1040                                         CPDrawFocusRectangle (dc, label.pieces[i].rect, label.ForeColor, label.BackColor);
1041                                 }\r
1042                         }                       
1043                         \r
1044                 }\r
1045                 #endregion      // LinkLabel\r
1046                 #region ListBox
1047                 
1048                 // Drawing              
1049                 public override void DrawListBoxDecorations (Graphics dc, ListBox ctrl)
1050                 {                       
1051                         Rectangle cl = ctrl.LBoxInfo.client_rect;
1052                         
1053                         // Draw decorations
1054                         switch (ctrl.BorderStyle) {
1055                         case BorderStyle.Fixed3D: {                             
1056                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), cl.X, cl.Y, cl.X + cl.Width, cl.Y); //top 
1057                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), cl.X + 1, cl.Y + 1, cl.X + cl.Width - 2, cl.Y + 1);
1058                                 dc.DrawLine (ResPool.GetPen (ColorButtonFace), cl.X, cl.Y + cl.Height - 2, cl.X + cl.Width, cl.Y + cl.Height - 2); //down
1059                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), cl.X, cl.Y + cl.Height - 1, cl.X + cl.Width, cl.Y + cl.Height - 1);
1060                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), cl.X, cl.Y, cl.X, cl.Y + cl.Height); //left
1061                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), cl.X + 1, cl.Y + 1, cl.X + 1, cl.Y + cl.Height - 2); 
1062                                 dc.DrawLine (ResPool.GetPen (ColorButtonFace), cl.X + cl.Width - 2, cl.Y, cl.X + cl.Width - 2, cl.Y + cl.Height); //right
1063                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), cl.X + cl.Width - 1, cl.Y + 1 , cl.X + cl.Width - 1, cl.Y + cl.Height - 1);           
1064                                 break;
1065                         }
1066                         case BorderStyle.FixedSingle:
1067                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), cl.X, cl.Y, cl.Width - 1, cl.Height - 1);
1068                                 break;
1069                         case BorderStyle.None:
1070                         default:
1071                                 break;
1072                         }               
1073                 }               
1074                 
1075                 private int DrawListBoxDecorationSize (BorderStyle border_style)
1076                 {
1077                         switch (border_style) {
1078                                 case BorderStyle.Fixed3D:
1079                                         return 2;
1080                                 case BorderStyle.FixedSingle:                                   
1081                                         return 1;
1082                                 case BorderStyle.None:
1083                                 default:
1084                                         break;
1085                                 }
1086                                 
1087                         return 0;
1088                 }                       
1089                 
1090                 // Sizing                               
1091                 public override int DrawListBoxDecorationTop  (BorderStyle border_style) { return DrawListBoxDecorationSize (border_style);}
1092                 public override int DrawListBoxDecorationBottom  (BorderStyle border_style) { return DrawListBoxDecorationSize (border_style);}
1093                 public override int DrawListBoxDecorationRight (BorderStyle border_style) { return DrawListBoxDecorationSize (border_style);}
1094                 public override int DrawListBoxDecorationLeft (BorderStyle border_style) { return DrawListBoxDecorationSize (border_style);}
1095                 
1096                 public override void DrawListBoxItem (ListBox ctrl, DrawItemEventArgs e)
1097                 {
1098                         Color back_color, fore_color;
1099                         StringFormat string_format = ctrl.GetFormatString ();
1100                         
1101                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1102                                 back_color = ThemeEngine.Current.ColorHilight;
1103                                 fore_color = ThemeEngine.Current.ColorHilightText;
1104                         }
1105                         else {
1106                                 back_color = e.BackColor;
1107                                 fore_color = e.ForeColor;
1108                         }
1109                         
1110                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
1111                                 (back_color), e.Bounds);
1112
1113                         e.Graphics.DrawString (ctrl.GetItemText (ctrl.Items[e.Index]), e.Font,
1114                                 ThemeEngine.Current.ResPool.GetSolidBrush (fore_color),
1115                                 e.Bounds, string_format);
1116                                         
1117                         if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) {
1118                                 ThemeEngine.Current.CPDrawFocusRectangle (e.Graphics, e.Bounds,
1119                                         fore_color, back_color);
1120                         }
1121                 }
1122                 
1123                 #endregion ListBox
1124
1125                 #region ListView
1126                 // Drawing
1127                 public override void DrawListView (Graphics dc, Rectangle clip, ListView control)
1128                 {
1129                         bool details = (control.View == View.Details);
1130
1131                         dc.FillRectangle (ResPool.GetSolidBrush (control.BackColor), clip);
1132
1133                         // border is drawn directly in the Paint method
1134                         if (details && control.HeaderStyle != ColumnHeaderStyle.None) {
1135                                 dc.FillRectangle (ResPool.GetSolidBrush (SystemColors.Control),
1136                                                   0, 0, control.TotalWidth, control.Font.Height + 5);
1137                                 if (control.Columns.Count > 0) {
1138                                         if (control.HeaderStyle == ColumnHeaderStyle.Clickable) {
1139                                                 foreach (ColumnHeader col in control.Columns) {
1140                                                         this.CPDrawButton (dc, col.Rect,
1141                                                                            (col.Pressed ?
1142                                                                             ButtonState.Pushed :
1143                                                                             ButtonState.Normal));
1144                                                         dc.DrawString (col.Text, ThemeEngine.Current.DefaultFont,
1145                                                                        ResPool.GetSolidBrush
1146                                                                        (this.ColorButtonText),
1147                                                                        //col.Rect,
1148                                                                         col.Rect.X + 3,
1149                                                                         col.Rect.Y + col.Rect.Height/2 + 1,
1150                                                                         col.Format);
1151                                                 }
1152                                         }
1153                                         // Non-clickable columns
1154                                         else {
1155                                                 foreach (ColumnHeader col in control.Columns) {
1156                                                         this.CPDrawButton (dc, col.Rect, ButtonState.Flat);
1157                                                         dc.DrawString (col.Text, ThemeEngine.Current.DefaultFont,
1158                                                                        ResPool.GetSolidBrush
1159                                                                        (this.ColorButtonText),
1160                                                                         //col.Rect,
1161                                                                         col.Rect.X + 3,
1162                                                                         col.Rect.Y + col.Rect.Height/2 + 1,
1163                                                                         col.Format);
1164                                                 }
1165                                         }
1166                                 }
1167                         }
1168
1169                         // In case of details view draw the items only if
1170                         // columns are non-zero
1171                         if (!details || control.Columns.Count > 0)
1172                                 foreach (ListViewItem item in control.Items) {
1173                                         if (clip.IntersectsWith (item.EntireRect))
1174                                                 DrawListViewItem (dc, control, item);
1175                                 }
1176
1177                         // draw the gridlines
1178                         if (details && control.GridLines) {
1179                                 int top = (control.HeaderStyle == ColumnHeaderStyle.None) ?
1180                                         2 : control.Font.Height + 2;
1181
1182                                 // draw vertical gridlines
1183                                 foreach (ColumnHeader col in control.Columns)
1184                                         dc.DrawLine (this.ResPool.GetPen (this.ColorButtonFace),
1185                                                      col.Rect.Right, top,
1186                                                      col.Rect.Right, control.TotalHeight);
1187                                 // draw horizontal gridlines
1188                                 ListViewItem last_item = null;
1189                                 foreach (ListViewItem item in control.Items) {
1190                                         dc.DrawLine (this.ResPool.GetPen (this.ColorButtonFace),
1191                                                      item.EntireRect.Left, item.EntireRect.Top,
1192                                                      control.TotalWidth, item.EntireRect.Top);
1193                                         last_item = item;
1194                                 }
1195
1196                                 // draw a line after at the bottom of the last item
1197                                 if (last_item != null) {
1198                                         dc.DrawLine (this.ResPool.GetPen (this.ColorButtonFace),
1199                                                      last_item.EntireRect.Left,
1200                                                      last_item.EntireRect.Bottom,
1201                                                      control.TotalWidth,
1202                                                      last_item.EntireRect.Bottom);
1203                                 }
1204                         }
1205                 }
1206
1207                 // draws the ListViewItem of the given index
1208                 private void DrawListViewItem (Graphics dc, ListView control, ListViewItem item)
1209                 {
1210                         if (control.CheckBoxes) {
1211                                 if (control.StateImageList == null) {
1212                                         // Make sure we've got at least a line width of 1
1213                                         int check_wd = Math.Max (3, item.CheckRect.Width / 6);
1214                                         int scale = Math.Max (1, item.CheckRect.Width / 12);
1215
1216                                         // set the checkbox background
1217                                         dc.FillRectangle (this.ResPool.GetSolidBrush (this.ColorWindow),
1218                                                           item.CheckRect);
1219                                         // define a rectangle inside the border area
1220                                         Rectangle rect = new Rectangle (item.CheckRect.X + 2,
1221                                                                         item.CheckRect.Y + 2,
1222                                                                         item.CheckRect.Width - 4,
1223                                                                         item.CheckRect.Height - 4);
1224                                         Pen pen = new Pen (this.ColorWindowText, 2);
1225                                         dc.DrawRectangle (pen, rect);
1226
1227                                         // Need to draw a check-mark
1228                                         if (item.Checked) {
1229                                                 pen.Width = 1;
1230                                                 // adjustments to get the check-mark at the right place
1231                                                 rect.X ++; rect.Y ++;
1232                                                 // following logic is taken from DrawFrameControl method
1233                                                 for (int i = 0; i < check_wd; i++) {
1234                                                         dc.DrawLine (pen, rect.Left + check_wd / 2,
1235                                                                      rect.Top + check_wd + i,
1236                                                                      rect.Left + check_wd / 2 + 2 * scale,
1237                                                                      rect.Top + check_wd + 2 * scale + i);
1238                                                         dc.DrawLine (pen,
1239                                                                      rect.Left + check_wd / 2 + 2 * scale,
1240                                                                      rect.Top + check_wd + 2 * scale + i,
1241                                                                      rect.Left + check_wd / 2 + 6 * scale,
1242                                                                      rect.Top + check_wd - 2 * scale + i);
1243                                                 }
1244                                         }
1245                                 }
1246                                 else {
1247                                         if (item.Checked && control.StateImageList.Images.Count > 1)
1248                                                 control.StateImageList.Draw (dc,
1249                                                                              item.CheckRect.Location, 1);
1250                                         else if (! item.Checked && control.StateImageList.Images.Count > 0)
1251                                                 control.StateImageList.Draw (dc,
1252                                                                              item.CheckRect.Location, 0);
1253                                 }
1254                         }
1255
1256                         // Item is drawn as a special case, as it is not just text
1257                         if (control.View == View.LargeIcon) {
1258                                 if (item.ImageIndex > -1 &&
1259                                     control.LargeImageList != null &&
1260                                     item.ImageIndex < control.LargeImageList.Images.Count)
1261                                         control.LargeImageList.Draw (dc, item.IconRect.Location,
1262                                                                      item.ImageIndex);
1263                         }
1264                         else {
1265                                 if (item.ImageIndex > -1 &&
1266                                     control.SmallImageList != null &&
1267                                     item.ImageIndex < control.SmallImageList.Images.Count)
1268                                         control.SmallImageList.Draw (dc, item.IconRect.Location,
1269                                                                      item.ImageIndex);
1270                         }
1271
1272                         // draw the item text
1273                         Rectangle text_rect = item.LabelRect;
1274                         // format for the item text
1275                         StringFormat format = new StringFormat ();
1276                         format.LineAlignment = StringAlignment.Center;
1277                         if (control.View == View.LargeIcon)
1278                                 format.Alignment = StringAlignment.Center;
1279                         else
1280                                 format.Alignment = StringAlignment.Near;
1281                         
1282                         if (!control.LabelWrap)
1283                                 format.FormatFlags = StringFormatFlags.NoWrap;
1284                         
1285                         if (item.Selected) {
1286                                 if (control.View == View.Details) {
1287                                         if (control.FullRowSelect) {
1288                                                 // fill the entire rect excluding the checkbox
1289                                                 Rectangle full_rect = item.EntireRect;
1290                                                 full_rect.Location = item.LabelRect.Location;
1291                                                 dc.FillRectangle (this.ResPool.GetSolidBrush
1292                                                                   (this.ColorHilight), full_rect);
1293                                         }
1294                                         else {
1295                                                 Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
1296                                                                                                 item.Font));
1297                                                 text_rect.Width = text_size.Width;
1298                                                 dc.FillRectangle (this.ResPool.GetSolidBrush
1299                                                                   (this.ColorHilight), text_rect);
1300                                         }
1301                                 }
1302                                 else {
1303                                         /*Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
1304                                           item.Font));
1305                                           Point loc = text_rect.Location;
1306                                           loc.X += (text_rect.Width - text_size.Width) / 2;
1307                                           text_rect.Width = text_size.Width;*/
1308                                         dc.FillRectangle (this.ResPool.GetSolidBrush (this.ColorHilight),
1309                                                           text_rect);
1310                                 }
1311                         }
1312                         else
1313                                 dc.FillRectangle (ResPool.GetSolidBrush (item.BackColor), text_rect);
1314
1315                         if (item.Text != null && item.Text.Length > 0) {
1316                                 if (item.Selected)
1317                                         dc.DrawString (item.Text, item.Font, this.ResPool.GetSolidBrush
1318                                                        (this.ColorHilightText), text_rect, format);
1319                                 else
1320                                         dc.DrawString (item.Text, item.Font, this.ResPool.GetSolidBrush
1321                                                        (item.ForeColor), text_rect, format);
1322                         }
1323
1324                         if (control.View == View.Details && control.Columns.Count > 0) {
1325                                 // draw subitems for details view
1326                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
1327                                 int count = (control.Columns.Count < subItems.Count ? 
1328                                              control.Columns.Count : subItems.Count);
1329
1330                                 if (count > 0) {
1331                                         ColumnHeader col;
1332                                         ListViewItem.ListViewSubItem subItem;
1333                                         Rectangle sub_item_rect = item.LabelRect;
1334
1335                                         // set the format for subitems
1336                                         format.FormatFlags = StringFormatFlags.NoWrap;
1337                                         format.Alignment = StringAlignment.Near;
1338
1339                                         // 0th subitem is the item already drawn
1340                                         for (int index = 1; index < count; index++) {
1341                                                 subItem = subItems [index];
1342                                                 col = control.Columns [index];
1343                                                 sub_item_rect.X = col.Rect.Left;
1344                                                 sub_item_rect.Width = col.Wd;
1345
1346                                                 SolidBrush sub_item_back_br = null;
1347                                                 SolidBrush sub_item_fore_br = null;
1348                                                 Font sub_item_font = null;
1349
1350                                                 if (item.UseItemStyleForSubItems) {
1351                                                         sub_item_back_br = this.ResPool.GetSolidBrush
1352                                                                 (item.BackColor);
1353                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
1354                                                                 (item.ForeColor);
1355                                                         sub_item_font = item.Font;
1356                                                 }
1357                                                 else {
1358                                                         sub_item_back_br = this.ResPool.GetSolidBrush
1359                                                                 (subItem.BackColor);
1360                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
1361                                                                 (subItem.ForeColor);
1362                                                         sub_item_font = subItem.Font;
1363                                                 }
1364
1365                                                 // In case of fullrowselect, background is filled
1366                                                 // for the entire rect above
1367                                                 if (item.Selected && control.FullRowSelect) {
1368                                                         if (subItem.Text != null && subItem.Text.Length > 0)
1369                                                                 dc.DrawString (subItem.Text, sub_item_font,
1370                                                                                this.ResPool.GetSolidBrush
1371                                                                                (this.ColorHilightText),
1372                                                                                sub_item_rect, format);
1373                                                 }
1374                                                 else {
1375                                                         dc.FillRectangle (sub_item_back_br, sub_item_rect);
1376                                                         if (subItem.Text != null && subItem.Text.Length > 0)
1377                                                                 dc.DrawString (subItem.Text, sub_item_font,
1378                                                                                sub_item_fore_br,
1379                                                                                sub_item_rect, format);
1380                                                 }
1381                                                 sub_item_rect.X += col.Wd;
1382                                         }
1383                                 }
1384                         }
1385                 }
1386
1387                 // Sizing
1388                 public override Size ListViewCheckBoxSize {
1389                         get { return new Size (16, 16); }
1390                 }
1391
1392                 public override int ListViewColumnHeaderHeight {
1393                         get { return 16; }
1394                 }
1395
1396                 public override int ListViewDefaultColumnWidth {
1397                         get { return 60; }
1398                 }
1399
1400                 public override int ListViewVerticalSpacing {
1401                         get { return 22; }
1402                 }
1403
1404                 public override int ListViewEmptyColumnWidth {
1405                         get { return 10; }
1406                 }
1407
1408                 public override int ListViewHorizontalSpacing {
1409                         get { return 10; }
1410                 }
1411
1412                 public override Size ListViewDefaultSize {
1413                         get { return new Size (121, 97); }
1414                 }
1415                 #endregion      // ListView
1416                 
1417                 #region Menus
1418                 public override void CalcItemSize (Graphics dc, MenuAPI.MENUITEM item, int y, int x, bool menuBar)
1419                 {
1420                         item.rect.Y = y;
1421                         item.rect.X = x;
1422
1423                         if (item.item.Visible == false)
1424                                 return;
1425
1426                         if (item.item.Separator == true) {
1427                                 item.rect.Height = SEPARATOR_HEIGHT / 2;
1428                                 item.rect.Width = -1;
1429                                 return;
1430                         }
1431                         
1432                         if (item.item.MeasureEventDefined) {
1433                                 MeasureItemEventArgs mi = new MeasureItemEventArgs (dc, item.pos);
1434                                 item.item.PerformMeasureItem (mi);
1435                                 item.rect.Height = mi.ItemHeight;
1436                                 item.rect.Width = mi.ItemWidth;
1437                                 return;
1438                         } else {                
1439
1440                                 SizeF size;
1441                                 size =  dc.MeasureString (item.item.Text, ThemeEngine.Current.MenuFont);
1442                                 item.rect.Width = (int) size.Width;
1443                                 item.rect.Height = (int) size.Height;
1444         
1445                                 if (!menuBar) {
1446         
1447                                         if (item.item.Shortcut != Shortcut.None && item.item.ShowShortcut) {
1448                                                 item.item.XTab = ThemeEngine.Current.MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
1449                                                 size =  dc.MeasureString (" " + item.item.GetShortCutText (), ThemeEngine.Current.MenuFont);
1450                                                 item.rect.Width += MENU_TAB_SPACE + (int) size.Width;
1451                                         }
1452         
1453                                         item.rect.Width += 4 + (ThemeEngine.Current.MenuCheckSize.Width * 2);
1454                                 }
1455                                 else {
1456                                         item.rect.Width += MENU_BAR_ITEMS_SPACE;
1457                                         x += item.rect.Width;
1458                                 }
1459         
1460                                 if (item.rect.Height < ThemeEngine.Current.MenuHeight)
1461                                         item.rect.Height = ThemeEngine.Current.MenuHeight;
1462                                 }
1463                 }
1464                 
1465                 // Updates the menu rect and returns the height
1466                 public override int CalcMenuBarSize (Graphics dc, IntPtr hMenu, int width)
1467                 {
1468                         int x = 0;
1469                         int i = 0;
1470                         int y = 0;
1471                         MenuAPI.MENU menu = MenuAPI.GetMenuFromID (hMenu);
1472                         menu.Height = 0;
1473                         MenuAPI.MENUITEM item;
1474
1475                         while (i < menu.items.Count) {
1476
1477                                 item = (MenuAPI.MENUITEM) menu.items[i];
1478                                 CalcItemSize (dc, item, y, x, true);
1479                                 i = i + 1;
1480
1481                                 if (x + item.rect.Width > width) {
1482                                         item.rect.X = 0;
1483                                         y += item.rect.Height;
1484                                         item.rect.Y = y;
1485                                         x = 0;
1486                                 }
1487
1488                                 x += item.rect.Width;
1489                                 item.item.MenuBar = true;                               
1490
1491                                 if (y + item.rect.Height > menu.Height)
1492                                         menu.Height = item.rect.Height + y;
1493                         }
1494
1495                         menu.Width = width;                                             
1496                         return menu.Height;
1497                 }
1498
1499                 
1500                 public override void CalcPopupMenuSize (Graphics dc, IntPtr hMenu)
1501                 {
1502                         int x = 3;
1503                         int start = 0;
1504                         int i, n, y, max;
1505
1506                         MenuAPI.MENU menu = MenuAPI.GetMenuFromID (hMenu);
1507                         menu.Height = 0;
1508
1509                         while (start < menu.items.Count) {
1510                                 y = 2;
1511                                 max = 0;
1512                                 for (i = start; i < menu.items.Count; i++) {
1513                                         MenuAPI.MENUITEM item = (MenuAPI.MENUITEM) menu.items[i];
1514
1515                                         if ((i != start) && (item.item.Break || item.item.BarBreak))
1516                                                 break;
1517
1518                                         CalcItemSize (dc, item, y, x, false);
1519                                         y += item.rect.Height;
1520
1521                                         if (item.rect.Width > max)
1522                                                 max = item.rect.Width;
1523                                 }
1524
1525                                 // Reemplace the -1 by the menu width (separators)
1526                                 for (n = start; n < i; n++, start++) {
1527                                         MenuAPI.MENUITEM item = (MenuAPI.MENUITEM) menu.items[n];
1528                                         item.rect.Width = max;
1529                                 }
1530
1531                                 if (y > menu.Height)
1532                                         menu.Height = y;
1533
1534                                 x+= max;
1535                         }
1536
1537                         menu.Width = x;
1538
1539                         //space for border
1540                         menu.Width += 2;
1541                         menu.Height += 2;
1542
1543                         menu.Width += SM_CXBORDER;
1544                         menu.Height += SM_CYBORDER;
1545                 }
1546                 
1547                 // Draws a menu bar in a window
1548                 public override void DrawMenuBar (Graphics dc, IntPtr hMenu, Rectangle rect)
1549                 {
1550                         MenuAPI.MENU menu = MenuAPI.GetMenuFromID (hMenu);                      
1551                         Rectangle item_rect;
1552
1553                         if (menu.Height == 0)
1554                                 ThemeEngine.Current.CalcMenuBarSize (dc, hMenu, rect.Width);
1555                                 
1556                         rect.Height = menu.Height;
1557                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (menu.Wnd.BackColor), rect);
1558                                                 
1559                         for (int i = 0; i < menu.items.Count; i++) {
1560                                 MenuAPI.MENUITEM it = (MenuAPI.MENUITEM) menu.items[i];
1561                                 item_rect = it.rect;
1562                                 item_rect.X += rect.X;
1563                                 item_rect.Y += rect.Y;
1564                                 it.item.MenuHeight = menu.Height;
1565                                 it.item.PerformDrawItem (new DrawItemEventArgs (dc, ThemeEngine.Current.MenuFont,
1566                                                 item_rect, i, it.item.Status));                 
1567                                 
1568                         }                               
1569                 }               
1570                 
1571                 public override void DrawMenuItem (MenuItem item, DrawItemEventArgs e)
1572                 {
1573                         StringFormat string_format;
1574                         Rectangle rect_text = e.Bounds;
1575
1576                         if (item.Visible == false)
1577                                 return;
1578
1579                         if (item.MenuBar) {
1580                                 string_format = string_format_menu_menubar_text;
1581                         }
1582                         else {
1583                                 string_format = string_format_menu_text;
1584                         }               
1585
1586                         if (item.Separator == true) {
1587                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonShadow),
1588                                         e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
1589
1590                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonHilight),
1591                                         e.Bounds.X, e.Bounds.Y + 1, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + 1);
1592
1593                                 return;
1594                         }
1595
1596                         if (!item.MenuBar)
1597                                 rect_text.X += ThemeEngine.Current.MenuCheckSize.Width;
1598
1599                         if (item.BarBreak) { /* Draw vertical break bar*/
1600                                 Rectangle rect = e.Bounds;
1601                                 rect.Y++;
1602                                 rect.Width = 3;
1603                                 rect.Height = item.MenuHeight - 6;
1604
1605                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonShadow),
1606                                         rect.X, rect.Y , rect.X, rect.Y + rect.Height);
1607
1608                                 e.Graphics.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonHilight),
1609                                         rect.X + 1, rect.Y , rect.X +1, rect.Y + rect.Height);
1610                         }                       
1611                         
1612                         Color color_text;
1613                         Color color_back;
1614                         
1615                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1616                                 color_text = ThemeEngine.Current.ColorHilightText;
1617                                 color_back = ThemeEngine.Current.ColorHilight;
1618                         }
1619                         else {
1620                                 color_text = ThemeEngine.Current.ColorMenuText;
1621                                 color_back = ThemeEngine.Current.ColorMenu;
1622                         }
1623
1624                         /* Draw background */
1625                         Rectangle rect_back = e.Bounds;
1626                         rect_back.X++;
1627                         rect_back.Width -=2;
1628                         e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color_back), rect_back);
1629                         
1630                         if (item.Enabled) {
1631                                 e.Graphics.DrawString (item.Text, e.Font,
1632                                         ThemeEngine.Current.ResPool.GetSolidBrush (color_text),
1633                                         rect_text, string_format);
1634
1635                                 if (!item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut) {
1636                                         string str = item.GetShortCutText ();
1637                                         Rectangle rect = rect_text;
1638                                         rect.X = item.XTab;
1639                                         rect.Width -= item.XTab;
1640
1641                                         e.Graphics.DrawString (str, e.Font, ThemeEngine.Current.ResPool.GetSolidBrush (color_text),
1642                                                 rect, string_format_menu_shortcut);
1643                                 }
1644                         }
1645                         else {
1646                                 ControlPaint.DrawStringDisabled (e.Graphics, item.Text, e.Font, 
1647                                         Color.Black, rect_text, string_format);
1648                         }
1649
1650                         /* Draw arrow */
1651                         if (item.MenuBar == false && item.IsPopup) {
1652
1653                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
1654                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
1655                                 Bitmap  bmp = new Bitmap (cx, cy);
1656                                 Graphics gr = Graphics.FromImage (bmp);
1657                                 Rectangle rect_arrow = new Rectangle (0, 0, cx, cy);
1658                                 ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Arrow);
1659                                 bmp.MakeTransparent ();
1660                                 
1661                                 if (item.Enabled) {
1662                                         e.Graphics.DrawImage (bmp, e.Bounds.X + e.Bounds.Width - cx,
1663                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2));
1664                                 } else {
1665                                         ControlPaint.DrawImageDisabled (e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
1666                                                 e.Bounds.Y + ((e.Bounds.Height - cy) /2),  color_back);
1667                                 }
1668  
1669                                 gr.Dispose ();
1670                                 bmp.Dispose ();
1671                         }
1672
1673                         /* Draw checked or radio */
1674                         if (item.MenuBar == false && item.Checked) {
1675
1676                                 Rectangle area = e.Bounds;
1677                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
1678                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
1679                                 Bitmap  bmp = new Bitmap (cx, cy);
1680                                 Graphics gr = Graphics.FromImage (bmp);
1681                                 Rectangle rect_arrow = new Rectangle (0, 0, cx, cy);
1682
1683                                 if (item.RadioCheck)
1684                                         ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Bullet);
1685                                 else
1686                                         ControlPaint.DrawMenuGlyph (gr, rect_arrow, MenuGlyph.Checkmark);
1687
1688                                 bmp.MakeTransparent ();
1689                                 e.Graphics.DrawImage (bmp, area.X, e.Bounds.Y + ((e.Bounds.Height - cy) / 2));
1690
1691                                 gr.Dispose ();
1692                                 bmp.Dispose ();
1693                         }                       
1694                 }               
1695                         
1696                 public override void DrawPopupMenu (Graphics dc, IntPtr hMenu, Rectangle cliparea, Rectangle rect)
1697                 {
1698                         MenuAPI.MENU menu = MenuAPI.GetMenuFromID (hMenu);
1699
1700                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush
1701                                 (ThemeEngine.Current.ColorMenu), cliparea);
1702
1703                         /* Draw menu borders */
1704                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorHilightText),
1705                                 rect.X, rect.Y, rect.X + rect.Width, rect.Y);
1706
1707                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorHilightText),
1708                                 rect.X, rect.Y, rect.X, rect.Y + rect.Height);
1709
1710                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonShadow),
1711                                 rect.X + rect.Width - 1 , rect.Y , rect.X + rect.Width - 1, rect.Y + rect.Height);
1712
1713                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonDkShadow),
1714                                 rect.X + rect.Width, rect.Y , rect.X + rect.Width, rect.Y + rect.Height);
1715
1716                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonShadow),
1717                                 rect.X , rect.Y + rect.Height - 1 , rect.X + rect.Width - 1, rect.Y + rect.Height -1);
1718
1719                         dc.DrawLine (ThemeEngine.Current.ResPool.GetPen (ThemeEngine.Current.ColorButtonDkShadow),
1720                                 rect.X , rect.Y + rect.Height, rect.X + rect.Width - 1, rect.Y + rect.Height);
1721
1722                         for (int i = 0; i < menu.items.Count; i++)
1723                                 if (cliparea.IntersectsWith (((MenuAPI.MENUITEM) menu.items[i]).rect)) {
1724                                         MenuAPI.MENUITEM it = (MenuAPI.MENUITEM) menu.items[i];
1725                                         it.item.MenuHeight = menu.Height;
1726                                         it.item.PerformDrawItem (new DrawItemEventArgs (dc, ThemeEngine.Current.MenuFont,
1727                                                 it.rect, i, it.item.Status));
1728                         }
1729                 }
1730                 
1731                 #endregion // Menus
1732
1733                 #region MonthCalendar
1734
1735                 // draw the month calendar
1736                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) \r
1737                 {
1738                         Rectangle client_rectangle = mc.ClientRectangle;
1739                         Size month_size = mc.SingleMonthSize;
1740                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
1741                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
1742                         Size date_cell_size = (Size)((object)mc.date_cell_size);
1743                         
1744                         // draw the singlecalendars
1745                         int x_offset = 1;
1746                         int y_offset = 1;
1747                         // adjust for the position of the specific month
1748                         for (int i=0; i < mc.CalendarDimensions.Height; i++) \r
1749                         {
1750                                 if (i > 0) \r
1751                                 {
1752                                         y_offset += month_size.Height + calendar_spacing.Height;
1753                                 }
1754                                 // now adjust for x position    
1755                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) \r
1756                                 {
1757                                         if (j > 0) \r
1758                                         {
1759                                                 x_offset += month_size.Width + calendar_spacing.Width;
1760                                         } \r
1761                                         else \r
1762                                         {
1763                                                 x_offset = 1;
1764                                         }
1765
1766                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
1767                                         if (month_rect.IntersectsWith (clip_rectangle)) {
1768                                                 DrawSingleMonth (
1769                                                         dc,
1770                                                         clip_rectangle,
1771                                                         month_rect,
1772                                                         mc,
1773                                                         i,
1774                                                         j);
1775                                         }
1776                                 }
1777                         }
1778                         
1779                         Rectangle bottom_rect = new Rectangle (
1780                                                 client_rectangle.X,
1781                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
1782                                                 client_rectangle.Width,
1783                                                 date_cell_size.Height + 2);
1784                         // draw the today date if it's set
1785                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) \r
1786                         {
1787                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), bottom_rect);
1788                                 if (mc.ShowToday) {
1789                                         int today_offset = 5;
1790                                         if (mc.ShowTodayCircle) \r
1791                                         {
1792                                                 Rectangle today_circle_rect = new Rectangle (
1793                                                         client_rectangle.X + 5,
1794                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
1795                                                         date_cell_size.Width,
1796                                                         date_cell_size.Height);
1797                                                         DrawTodayCircle (dc, today_circle_rect);
1798                                                 today_offset += date_cell_size.Width + 5;
1799                                         }
1800                                         // draw today's date
1801                                         StringFormat text_format = new StringFormat();
1802                                         text_format.LineAlignment = StringAlignment.Center;
1803                                         text_format.Alignment = StringAlignment.Near;
1804                                         Font bold_font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
1805                                         Rectangle today_rect = new Rectangle (
1806                                                         today_offset + client_rectangle.X,
1807                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
1808                                                         Math.Max(client_rectangle.Width - today_offset, 0),
1809                                                         date_cell_size.Height);
1810                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), bold_font, ResPool.GetSolidBrush (mc.ForeColor), today_rect, text_format);
1811                                 }                               
1812                         }
1813                         
1814                         // finally paint the borders of the calendars as required
1815                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
1816                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
1817                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height));
1818                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
1819                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.Right-1, client_rectangle.Y, 1, client_rectangle.Height));
1820                                 } else { 
1821                                         Rectangle rect = new Rectangle (
1822                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
1823                                                 client_rectangle.Y,
1824                                                 calendar_spacing.Width,
1825                                                 client_rectangle.Height);
1826                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
1827                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
1828                                         }
1829                                 }
1830                         }
1831                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
1832                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
1833                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1));
1834                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
1835                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Bottom-1, client_rectangle.Width, 1));
1836                                 } else { 
1837                                         Rectangle rect = new Rectangle (
1838                                                 client_rectangle.X,
1839                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
1840                                                 client_rectangle.Width,
1841                                                 calendar_spacing.Height);
1842                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
1843                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
1844                                         }
1845                                 }
1846                         }
1847                         
1848                         // draw the drop down border if need
1849                         if (mc.owner != null) {
1850                                 Rectangle bounds = mc.ClientRectangle;
1851                                 if (clip_rectangle.Contains (mc.Location)) {
1852                                         // find out if top or left line to draw
1853                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
1854                                         
1855                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
1856                                         }
1857                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
1858                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
1859                                         }
1860                                 }
1861                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
1862                                         // find out if bottom or right line to draw
1863                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
1864                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
1865                                         }
1866                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
1867                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
1868                                         }
1869                                 }
1870                         }
1871                 }
1872
1873                 // darws a single part of the month calendar (with one month)
1874                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) \r
1875                 {
1876                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
1877                         Size title_size = (Size)((object)mc.title_size);
1878                         Size date_cell_size = (Size)((object)mc.date_cell_size);
1879                         DateTime current_month = (DateTime)((object)mc.current_month);
1880                         
1881                         // set up some standard string formating variables
1882                         StringFormat text_format = new StringFormat();
1883                         text_format.LineAlignment = StringAlignment.Center;
1884                         text_format.Alignment = StringAlignment.Center;
1885                         
1886
1887                         // draw the title back ground
1888                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
1889                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
1890                         if (title_rect.IntersectsWith (clip_rectangle)) {
1891                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
1892                                 // draw the title                               
1893                                 string title_text = this_month.ToString ("MMMM yyyy");
1894                                 dc.DrawString (title_text, mc.Font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, text_format);
1895
1896                                 // draw previous and next buttons if it's time
1897                                 if (row == 0 && col == 0) \r
1898                                 {
1899                                         // draw previous button
1900                                         DrawMonthCalendarButton (
1901                                                 dc,
1902                                                 rectangle,
1903                                                 mc,
1904                                                 title_size,
1905                                                 mc.button_x_offset,
1906                                                 (System.Drawing.Size)((object)mc.button_size),
1907                                                 true);
1908                                 }
1909                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) \r
1910                                 {
1911                                         // draw next button
1912                                         DrawMonthCalendarButton (
1913                                                 dc,
1914                                                 rectangle,
1915                                                 mc,
1916                                                 title_size,
1917                                                 mc.button_x_offset,
1918                                                 (System.Drawing.Size)((object)mc.button_size),
1919                                                 false);
1920                                 }
1921                         }
1922                         
1923                         // set the week offset and draw week nums if needed
1924                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
1925                         Rectangle day_name_rect = new Rectangle(
1926                                 rectangle.X,
1927                                 rectangle.Y + title_size.Height,
1928                                 (7 + col_offset) * date_cell_size.Width,
1929                                 date_cell_size.Height);
1930                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
1931                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), day_name_rect);
1932                                 // draw the day names 
1933                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
1934                                 for (int i=0; i < 7; i++) \r
1935                                 {
1936                                         int position = i - (int) first_day_of_week;
1937                                         if (position < 0) \r
1938                                         {
1939                                                 position = 7 + position;
1940                                         }
1941                                         // draw it
1942                                         Rectangle day_rect = new Rectangle(
1943                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
1944                                                 day_name_rect.Y,
1945                                                 date_cell_size.Width,
1946                                                 date_cell_size.Height);
1947                                         dc.DrawString (((DayOfWeek)i).ToString().Substring(0, 3), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, text_format);
1948                                 }
1949                                 
1950                                 // draw the vertical divider
1951                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
1952                                 dc.DrawLine (
1953                                         ResPool.GetPen (mc.ForeColor),
1954                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
1955                                         rectangle.Y + vert_divider_y,
1956                                         rectangle.Right - mc.divider_line_offset,
1957                                         rectangle.Y + vert_divider_y);
1958                         }
1959
1960
1961                         // draw the actual date items in the grid (including the week numbers)
1962                         Rectangle date_rect = new Rectangle (
1963                                 rectangle.X,
1964                                 rectangle.Y + title_size.Height + date_cell_size.Height,
1965                                 date_cell_size.Width,
1966                                 date_cell_size.Height);
1967                         int month_row_count = 0;
1968                         bool draw_week_num_divider = false;
1969                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
1970                         for (int i=0; i < 6; i++) \r
1971                         {
1972                                 // establish if this row is in our clip_area
1973                                 Rectangle row_rect = new Rectangle (
1974                                         rectangle.X,
1975                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
1976                                         date_cell_size.Width * 7,
1977                                         date_cell_size.Height);
1978                                 if (mc.ShowWeekNumbers) {
1979                                         row_rect.Width += date_cell_size.Width;
1980                                 }
1981                 
1982                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
1983                                 if (draw_row) {
1984                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), row_rect);
1985                                 }
1986                                 // establish if this is a valid week to draw
1987                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
1988                                         month_row_count = i;
1989                                 }
1990                                 
1991                                 // draw the week number if required
1992                                 if (mc.ShowWeekNumbers && month_row_count == i) {
1993                                         if (!draw_week_num_divider) {
1994                                                 draw_week_num_divider = draw_row;
1995                                         }
1996                                         // get the week for this row
1997                                         int week = mc.GetWeekOfYear (current_date);     
1998
1999                                         if (draw_row) {
2000                                                 dc.DrawString (
2001                                                         week.ToString(),
2002                                                         mc.Font,
2003                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
2004                                                         date_rect,
2005                                                         text_format);
2006                                         }
2007                                         date_rect.Offset(date_cell_size.Width, 0);
2008                                 }
2009                                                                 
2010                                 // only draw the days if we have to
2011                                 if(month_row_count == i) {
2012                                         for (int j=0; j < 7; j++) \r
2013                                         {
2014                                                 if (draw_row) {
2015                                                         DrawMonthCalendarDate (
2016                                                                 dc,
2017                                                                 date_rect,
2018                                                                 mc,
2019                                                                 current_date,
2020                                                                 this_month,
2021                                                                 row,
2022                                                                 col);
2023                                                 }
2024
2025                                                 // move the day on
2026                                                 current_date = current_date.AddDays(1);
2027                                                 date_rect.Offset(date_cell_size.Width, 0);
2028                                         }
2029
2030                                         // shift the rectangle down one row
2031                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
2032                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
2033                                 }
2034                         }
2035
2036                         // month_row_count is zero based, so add one
2037                         month_row_count++;
2038
2039                         // draw week numbers if required
2040                         if (draw_week_num_divider) {
2041                                 col_offset = 1;
2042                                 dc.DrawLine (
2043                                         ResPool.GetPen (mc.ForeColor),
2044                                         rectangle.X + date_cell_size.Width - 1,
2045                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
2046                                         rectangle.X + date_cell_size.Width - 1,
2047                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
2048                         }
2049                 }
2050
2051                 // draws the pervious or next button
2052                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) \r
2053                 {
2054                         bool is_clicked = false;
2055                         Rectangle button_rect;
2056                         Rectangle arrow_rect = new Rectangle (rectangle.X, rectangle.Y, 4, 7);
2057                         Point[] arrow_path = new Point[3];
2058                         // prepare the button
2059                         if (is_previous) \r
2060                         {
2061                                 is_clicked = mc.is_previous_clicked;
2062                                 button_rect = new Rectangle (
2063                                         rectangle.X + 1 + x_offset,
2064                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2065                                         Math.Max(button_size.Width - 1, 0),
2066                                         Math.Max(button_size.Height - 1, 0));
2067                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2068                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2069                                 if (is_clicked) {
2070                                         arrow_rect.Offset(1,1);
2071                                 }
2072                                 arrow_path[0] = new Point (arrow_rect.Right, arrow_rect.Y);
2073                                 arrow_path[1] = new Point (arrow_rect.X, arrow_rect.Y + arrow_rect.Height/2);
2074                                 arrow_path[2] = new Point (arrow_rect.Right, arrow_rect.Bottom);
2075                         }
2076                         else
2077                         {
2078                                 is_clicked = mc.is_next_clicked;
2079                                 button_rect = new Rectangle (
2080                                         rectangle.Right - 1 - x_offset - button_size.Width,
2081                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2082                                         Math.Max(button_size.Width - 1, 0),
2083                                         Math.Max(button_size.Height - 1, 0));
2084                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2085                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2086                                 if (is_clicked) {
2087                                         arrow_rect.Offset(1,1);
2088                                 }
2089                                 arrow_path[0] = new Point (arrow_rect.X, arrow_rect.Y);
2090                                 arrow_path[1] = new Point (arrow_rect.Right, arrow_rect.Y + arrow_rect.Height/2);
2091                                 arrow_path[2] = new Point (arrow_rect.X, arrow_rect.Bottom);                            
2092                         }
2093
2094                         // fill the background
2095                         dc.FillRectangle (SystemBrushes.Control, button_rect);
2096                         // draw the border
2097                         if (is_clicked) {
2098                                 dc.DrawRectangle (SystemPens.ControlDark, button_rect);
2099                         }
2100                         else {
2101                                 CPDrawBorder3D (dc, button_rect, Border3DStyle.Raised, Border3DSide.All);
2102                         }
2103                         // draw the arrow
2104                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);                 
2105                 }
2106                 
2107
2108                 // draws one day in the calendar grid
2109                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
2110                         Color date_color = mc.ForeColor;
2111                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
2112
2113                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
2114                         if (date.Year != month.Year || date.Month != month.Month) {
2115                                 DateTime check_date = month.AddMonths (-1);
2116                                 // check if it's the month before 
2117                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
2118                                         date_color = mc.TrailingForeColor;
2119                                 } else {
2120                                         // check if it's the month after
2121                                         check_date = month.AddMonths (1);
2122                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
2123                                                 date_color = mc.TrailingForeColor;
2124                                         } else {
2125                                                 return;
2126                                         }
2127                                 }
2128                         } else {
2129                                 date_color = mc.ForeColor;
2130                         }
2131
2132
2133                         if (date == mc.SelectionStart && date == mc.SelectionEnd) {
2134                                 // see if the date is in the start of selection
2135                                 date_color = mc.BackColor;
2136                                 // draw the left hand of the back ground
2137                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2138                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 359);
2139                         } else if (date == mc.SelectionStart) {
2140                                 // see if the date is in the start of selection
2141                                 date_color = mc.BackColor;
2142                                 // draw the left hand of the back ground
2143                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2144                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
2145                                 // fill the other side as a straight rect
2146                                 if (date < mc.SelectionEnd) \r
2147                                 {
2148                                         // use rectangle instead of rectangle to go all the way to edge of rect
2149                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
2150                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
2151                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2152                                 }
2153                         } else if (date == mc.SelectionEnd) {
2154                                 // see if it is the end of selection
2155                                 date_color = mc.BackColor;
2156                                 // draw the left hand of the back ground
2157                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);
2158                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
2159                                 // fill the other side as a straight rect
2160                                 if (date > mc.SelectionStart) {
2161                                         selection_rect.X = rectangle.X;
2162                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
2163                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2164                                 }
2165                         } else if (date > mc.SelectionStart && date < mc.SelectionEnd) {
2166                                 // now see if it's in the middle
2167                                 date_color = mc.BackColor;
2168                                 // draw the left hand of the back ground
2169                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, 0, -3);
2170                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2171                         }
2172
2173                         // set up some standard string formating variables
2174                         StringFormat text_format = new StringFormat();
2175                         text_format.LineAlignment = StringAlignment.Center;
2176                         text_format.Alignment = StringAlignment.Center;
2177                         
2178
2179                         // establish if it's a bolded font
2180                         Font font;
2181                         if (mc.IsBoldedDate (date)) {
2182                                 font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
2183                         } else {
2184                                 font = mc.Font;
2185                         }
2186
2187                         // just draw the date now
2188                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, text_format);
2189
2190                         // today circle if needed
2191                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
2192                                 DrawTodayCircle (dc, interior);
2193                         }
2194
2195                         // draw the selection grid
2196                         if (mc.is_date_clicked && mc.clicked_date == date) {                            
2197                                 using (Pen pen = new Pen (Color.Black, 1) ) {
2198                                         pen.DashStyle = DashStyle.Dot;
2199                                         dc.DrawRectangle (pen, interior);
2200                                 }
2201                         }
2202                 }
2203
2204                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
2205                         Color circle_color = Color.FromArgb (248, 0, 0);
2206                         // draw the left hand of the circle 
2207                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
2208                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
2209                         Point [] curve_points = new Point [3];
2210                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
2211                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
2212                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
2213
2214                         using (Pen pen = new Pen (circle_color, 2)) {
2215                                 dc.DrawArc (pen, lhs_circle_rect, 90, 180);
2216                                 dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
2217                                 dc.DrawCurve (pen, curve_points);
2218                                 dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
2219                         }
2220                 }
2221
2222                 #endregion      // MonthCalendar
2223
2224                 #region Panel
2225                 public override Size PanelDefaultSize {
2226                         get {
2227                                 return new Size (200, 100);
2228                         }
2229                 }
2230                 #endregion      // Panel
2231
2232                 #region PictureBox
2233                 public override void DrawPictureBox (Graphics dc, Rectangle clip, PictureBox pb) {
2234                         Rectangle client = pb.ClientRectangle;
2235
2236                         if (pb.Image != null) {
2237                                 switch (pb.SizeMode) {
2238                                 case PictureBoxSizeMode.StretchImage:
2239                                         dc.DrawImage (pb.Image, 0, 0, client.Width, client.Height);
2240                                         break;
2241
2242                                 case PictureBoxSizeMode.CenterImage:
2243                                         dc.DrawImage (pb.Image, (client.Width / 2) - (pb.Image.Width / 2), (client.Height / 2) - (pb.Image.Height / 2));
2244                                         break;
2245                                 default:
2246                                         // Normal, AutoSize
2247                                         dc.DrawImage(pb.Image, 0, 0);
2248                                         break;
2249                                 }
2250                         }
2251                         CPDrawBorderStyle (dc, client, pb.BorderStyle);
2252                 }
2253
2254                 public override Size PictureBoxDefaultSize {
2255                         get {
2256                                 return new Size (100, 50);
2257                         }
2258                 }
2259                 #endregion      // PictureBox
2260
2261                 #region ProgressBar
2262                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl) 
2263                 {
2264                         Rectangle       block_rect;
2265                         Rectangle       client_area = ctrl.client_area;
2266                         int             space_betweenblocks     = 2;                    
2267                         int             block_width;
2268                         int             increment;
2269                         int             barpos_pixels;
2270                         
2271                         block_width = ((client_area.Height) * 2 ) / 3;
2272                         barpos_pixels = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (ctrl.Maximum - ctrl.Minimum);
2273                         increment = block_width + space_betweenblocks;
2274
2275                         /* Draw border */
2276                         CPDrawBorder3D (dc, ctrl.ClientRectangle, Border3DStyle.SunkenInner, Border3DSide.All & ~Border3DSide.Middle, ColorButtonFace);
2277                         
2278                         /* Draw Blocks */
2279                         block_rect = new Rectangle (client_area.X, client_area.Y, block_width, client_area.Height);
2280                         while ((block_rect.X - client_area.X) < barpos_pixels) {
2281                                 
2282                                 if (clip_rect.IntersectsWith (block_rect) == true) {                            
2283                                         dc.FillRectangle (ResPool.GetSolidBrush (progressbarblock_color), block_rect);
2284                                 }                               
2285                                 
2286                                 block_rect.X  += increment;
2287                         }
2288                 }
2289                 
2290                 public override Size ProgressBarDefaultSize {
2291                         get {
2292                                 return new Size (100, 23);
2293                         }
2294                 }
2295
2296                 #endregion      // ProgressBar
2297
2298                 #region RadioButton
2299                 public override void DrawRadioButton (Graphics dc, Rectangle clip_rectangle, RadioButton radio_button) {
2300                         StringFormat    text_format;
2301                         Rectangle       client_rectangle;
2302                         Rectangle       text_rectangle;
2303                         Rectangle       radiobutton_rectangle;
2304                         SolidBrush      sb;
2305                         int             radiobutton_size = 12;
2306                         int     radiobutton_space = 4;
2307
2308                         client_rectangle = radio_button.ClientRectangle;
2309                         text_rectangle = client_rectangle;
2310                         radiobutton_rectangle = new Rectangle(text_rectangle.X, text_rectangle.Y, radiobutton_size, radiobutton_size);
2311
2312                         text_format = new StringFormat();
2313                         text_format.Alignment = StringAlignment.Near;
2314                         text_format.LineAlignment = StringAlignment.Center;
2315                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
2316
2317                         /* Calculate the position of text and checkbox rectangle */
2318                         if (radio_button.appearance!=Appearance.Button) {
2319                                 switch(radio_button.radiobutton_alignment) {
2320                                 case ContentAlignment.BottomCenter: {
2321                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2322                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2323                                         text_rectangle.X=client_rectangle.X;
2324                                         text_rectangle.Width=client_rectangle.Width;
2325                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
2326                                         break;
2327                                 }
2328
2329                                 case ContentAlignment.BottomLeft: {
2330                                         radiobutton_rectangle.X=client_rectangle.Left;
2331                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2332                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2333                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;                                 
2334                                         break;
2335                                 }
2336
2337                                 case ContentAlignment.BottomRight: {
2338                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2339                                         radiobutton_rectangle.Y=client_rectangle.Bottom-radiobutton_size;
2340                                         text_rectangle.X=client_rectangle.X;
2341                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2342                                         break;
2343                                 }
2344
2345                                 case ContentAlignment.MiddleCenter: {
2346                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2347                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2348                                         text_rectangle.X=client_rectangle.X;
2349                                         text_rectangle.Width=client_rectangle.Width;
2350                                         break;
2351                                 }
2352
2353                                 default:
2354                                 case ContentAlignment.MiddleLeft: {
2355                                         radiobutton_rectangle.X=client_rectangle.Left;
2356                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2357                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2358                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2359                                         break;
2360                                 }
2361
2362                                 case ContentAlignment.MiddleRight: {
2363                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2364                                         radiobutton_rectangle.Y=(client_rectangle.Bottom-client_rectangle.Top)/2-radiobutton_size/2;
2365                                         text_rectangle.X=client_rectangle.X;
2366                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2367                                         break;
2368                                 }
2369
2370                                 case ContentAlignment.TopCenter: {
2371                                         radiobutton_rectangle.X=(client_rectangle.Right-client_rectangle.Left)/2-radiobutton_size/2;
2372                                         radiobutton_rectangle.Y=client_rectangle.Top;
2373                                         text_rectangle.X=client_rectangle.X;
2374                                         text_rectangle.Y=radiobutton_size+radiobutton_space;
2375                                         text_rectangle.Width=client_rectangle.Width;
2376                                         text_rectangle.Height=client_rectangle.Height-radiobutton_size-radiobutton_space;
2377                                         break;
2378                                 }
2379
2380                                 case ContentAlignment.TopLeft: {
2381                                         radiobutton_rectangle.X=client_rectangle.Left;
2382                                         radiobutton_rectangle.Y=client_rectangle.Top;
2383                                         text_rectangle.X=client_rectangle.X+radiobutton_size+radiobutton_space;
2384                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2385                                         break;
2386                                 }
2387
2388                                 case ContentAlignment.TopRight: {
2389                                         radiobutton_rectangle.X=client_rectangle.Right-radiobutton_size;
2390                                         radiobutton_rectangle.Y=client_rectangle.Top;
2391                                         text_rectangle.X=client_rectangle.X;
2392                                         text_rectangle.Width=client_rectangle.Width-radiobutton_size-radiobutton_space;
2393                                         break;
2394                                 }
2395                                 }
2396                         } else {
2397                                 text_rectangle.X=client_rectangle.X;
2398                                 text_rectangle.Width=client_rectangle.Width;
2399                         }
2400                         
2401                         /* Set the horizontal alignment of our text */
2402                         switch(radio_button.text_alignment) {
2403                                 case ContentAlignment.BottomLeft:
2404                                 case ContentAlignment.MiddleLeft:
2405                                 case ContentAlignment.TopLeft: {
2406                                         text_format.Alignment=StringAlignment.Near;
2407                                         break;
2408                                 }
2409
2410                                 case ContentAlignment.BottomCenter:
2411                                 case ContentAlignment.MiddleCenter:
2412                                 case ContentAlignment.TopCenter: {
2413                                         text_format.Alignment=StringAlignment.Center;
2414                                         break;
2415                                 }
2416
2417                                 case ContentAlignment.BottomRight:
2418                                 case ContentAlignment.MiddleRight:
2419                                 case ContentAlignment.TopRight: {
2420                                         text_format.Alignment=StringAlignment.Far;
2421                                         break;
2422                                 }
2423                         }
2424
2425                         /* Set the vertical alignment of our text */
2426                         switch(radio_button.text_alignment) {
2427                                 case ContentAlignment.TopLeft: 
2428                                 case ContentAlignment.TopCenter: 
2429                                 case ContentAlignment.TopRight: {
2430                                         text_format.LineAlignment=StringAlignment.Near;
2431                                         break;
2432                                 }
2433
2434                                 case ContentAlignment.BottomLeft:
2435                                 case ContentAlignment.BottomCenter:
2436                                 case ContentAlignment.BottomRight: {
2437                                         text_format.LineAlignment=StringAlignment.Far;
2438                                         break;
2439                                 }
2440
2441                                 case ContentAlignment.MiddleLeft:
2442                                 case ContentAlignment.MiddleCenter:
2443                                 case ContentAlignment.MiddleRight: {
2444                                         text_format.LineAlignment=StringAlignment.Center;
2445                                         break;
2446                                 }
2447                         }
2448
2449                         ButtonState state = ButtonState.Normal;
2450                         if (radio_button.FlatStyle == FlatStyle.Flat) {
2451                                 state |= ButtonState.Flat;
2452                         }
2453                         
2454                         if (radio_button.Checked) {
2455                                 state |= ButtonState.Checked;
2456                         }
2457
2458                         // Start drawing
2459
2460                         sb=new SolidBrush(radio_button.BackColor);
2461                         dc.FillRectangle(sb, radio_button.ClientRectangle);
2462                         sb.Dispose();
2463                         
2464                 
2465                         
2466                         if (radio_button.appearance==Appearance.Button) {
2467                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
2468                                         DrawFlatStyleButton(dc, radio_button.ClientRectangle, radio_button);
2469                                 } else {                                
2470                                         CPDrawButton(dc, radio_button.ClientRectangle, state);
2471                                 }               
2472                         } else {
2473                                 // establish if we are rendering a flat style of some sort
2474                                 if (radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup) {
2475                                         DrawFlatStyleRadioButton (dc, radiobutton_rectangle, radio_button);
2476                                 } else {
2477                                         ControlPaint.DrawRadioButton (dc, radiobutton_rectangle, state);
2478                                 }
2479                         }
2480                         
2481                         // offset the text if it's pressed and a button
2482                         if (radio_button.Appearance == Appearance.Button) {
2483                                 if (radio_button.Checked || (radio_button.Capture && radio_button.FlatStyle != FlatStyle.Flat)) {
2484                                         text_rectangle.X ++;
2485                                         text_rectangle.Y ++;
2486                                 }
2487                                 
2488                                 text_rectangle.Inflate(-4,-4);
2489                         } 
2490                         
2491                         /* Place the text; to be compatible with Windows place it after the radiobutton has been drawn */                       
2492                         dc.DrawString (radio_button.Text, radio_button.Font, ThemeEngine.Current.ResPool.GetSolidBrush (radio_button.ForeColor), text_rectangle, text_format);
2493                         
2494                         if (radio_button.Enabled) {
2495                                 sb = ResPool.GetSolidBrush(radio_button.ForeColor);
2496                                 dc.DrawString(radio_button.Text, radio_button.Font, sb, text_rectangle, text_format);                           
2497                         } else if (radio_button.FlatStyle == FlatStyle.Flat) {
2498                                 dc.DrawString(radio_button.Text, radio_button.Font, ResPool.GetSolidBrush (ControlPaint.DarkDark (this.ColorButtonFace)), text_rectangle, text_format);
2499                         } else {
2500                                 CPDrawStringDisabled(dc, radio_button.Text, radio_button.Font, this.ColorButtonText, text_rectangle, text_format);
2501                         }
2502
2503                         if (radio_button.Focused) {
2504                                 if (radio_button.FlatStyle != FlatStyle.Flat) {
2505                                         DrawInnerFocusRectangle (dc, text_rectangle, radio_button.BackColor);
2506                                 } else {
2507                                         dc.DrawRectangle (ResPool.GetPen (radio_button.ForeColor), text_rectangle);
2508                                 }
2509                         }                       
2510                 }
2511
2512                 // renders a radio button with the Flat and Popup FlatStyle
2513                 private void DrawFlatStyleRadioButton (Graphics graphics, Rectangle rectangle, RadioButton radio_button)
2514                 {
2515                         int     lineWidth;
2516                         
2517                         if (radio_button.Enabled) {
2518                                 // draw the outer flatstyle arcs
2519                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
2520                                         graphics.DrawArc (ResPool.GetPen (radio_button.ForeColor), rectangle, 0, 359);
2521                                         
2522                                         // fill in the area depending on whether or not the mouse is hovering
2523                                         if (radio_button.is_entered && radio_button.Capture) {
2524                                                 graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.Light (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2525                                         } else {
2526                                                 graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2527                                         }
2528                                 } else {
2529                                         // must be a popup radio button
2530                                         // fill the control
2531                                         graphics.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 0, 359);
2532
2533                                         if (radio_button.is_entered || radio_button.Capture) {
2534                                                 // draw the popup 3d button knob
2535                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Light (radio_button.BackColor)), rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
2536
2537                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark (radio_button.BackColor)), rectangle, 135, 180);
2538                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 315, 180);
2539                                                 
2540                                         } else {
2541                                                 // just draw lighter flatstyle outer circle
2542                                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark (this.ColorButtonFace)), rectangle, 0, 359);                                                
2543                                         }                                                                               
2544                                 }
2545                         } else {
2546                                 // disabled
2547                                 // fill control background color regardless of actual backcolor
2548                                 graphics.FillPie (ResPool.GetSolidBrush (this.ColorButtonFace), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
2549                                 // draw the ark as control dark
2550                                 graphics.DrawArc (ResPool.GetPen (ControlPaint.Dark(this.ColorButtonFace)), rectangle, 0, 359);
2551                         }
2552
2553                         // draw the check
2554                         lineWidth = Math.Max (1, Math.Min(rectangle.Width, rectangle.Height)/3);
2555                         if (radio_button.Checked) {
2556                                 SolidBrush buttonBrush;
2557
2558                                 if (!radio_button.Enabled) {
2559                                         buttonBrush = ResPool.GetSolidBrush (ControlPaint.Dark (this.ColorButtonFace));
2560                                 } else if (radio_button.FlatStyle == FlatStyle.Popup && radio_button.is_entered && radio_button.Capture) {
2561                                         buttonBrush = ResPool.GetSolidBrush (this.ColorButtonText);
2562                                 } else {
2563                                         buttonBrush = ResPool.GetSolidBrush (radio_button.ForeColor);
2564                                 }
2565                                 graphics.FillPie (buttonBrush, rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2, 0, 359);
2566                         }       
2567                 }
2568
2569                 public override Size RadioButtonDefaultSize {
2570                         get {
2571                                 return new Size (104,24);
2572                         }
2573                 }
2574                 #endregion      // RadioButton
2575
2576                 #region ScrollBar
2577                 public override void DrawScrollBar (Graphics dc, Rectangle clip, ScrollBar bar)
2578                 {
2579                         int             scrollbutton_width = bar.scrollbutton_width;
2580                         int             scrollbutton_height = bar.scrollbutton_height;
2581                         Rectangle       first_arrow_area;
2582                         Rectangle       second_arrow_area;                      
2583                         Rectangle       thumb_pos;
2584                         
2585                         thumb_pos = bar.ThumbPos;
2586
2587                         if (bar.vert) {
2588                                 first_arrow_area = new Rectangle(0, 0, bar.Width, scrollbutton_height);
2589                                 bar.FirstArrowArea = first_arrow_area;
2590
2591                                 second_arrow_area = new Rectangle(0, bar.ClientRectangle.Height - scrollbutton_height, bar.Width, scrollbutton_height);
2592                                 bar.SecondArrowArea = second_arrow_area;
2593
2594                                 thumb_pos.Width = bar.Width;
2595                                 bar.ThumbPos = thumb_pos;
2596
2597                                 /* Buttons */
2598                                 if (clip.IntersectsWith (first_arrow_area))
2599                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state);
2600                                 if (clip.IntersectsWith (second_arrow_area))
2601                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state);
2602
2603                                 /* Background */
2604                                 switch (bar.thumb_moving) {
2605                                 case ScrollBar.ThumbMoving.None: {
2606                                         Rectangle r = new Rectangle (0,  
2607                                                         scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - (scrollbutton_height * 2));
2608                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2609
2610                                         if (intersect != Rectangle.Empty) {
2611                                                 Brush h = ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace);
2612                                                 dc.FillRectangle (h, intersect);
2613                                         }
2614                                         break;
2615                                 }
2616                                 case ScrollBar.ThumbMoving.Forward: {
2617                                         Rectangle r = new Rectangle (0,  scrollbutton_height,
2618                                                         bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height);
2619                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2620
2621                                         if (intersect != Rectangle.Empty)
2622                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace), intersect);
2623
2624                                         r.X = 0;
2625                                         r.Y = thumb_pos.Y + thumb_pos.Height;
2626                                         r.Width = bar.ClientRectangle.Width;
2627                                         r.Height = bar.ClientRectangle.Height -  (thumb_pos.Y + thumb_pos.Height) - scrollbutton_height;
2628
2629                                         intersect = Rectangle.Intersect (clip, r);
2630                                         if (intersect != Rectangle.Empty)
2631                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63,63,63), Color.Black), intersect);
2632                                         break;
2633                                 }
2634                                 
2635                                 case ScrollBar.ThumbMoving.Backwards: {
2636                                         Rectangle r = new Rectangle (0,  scrollbutton_height,
2637                                                         bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height);
2638                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2639
2640                                         if (intersect != Rectangle.Empty)
2641                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63,63,63), Color.Black), intersect);
2642
2643                                         r.X = 0;
2644                                         r.Y = thumb_pos.Y + thumb_pos.Height;
2645                                         r.Width = bar.ClientRectangle.Width; 
2646                                         r.Height = bar.ClientRectangle.Height -  (thumb_pos.Y + thumb_pos.Height) - scrollbutton_height;
2647
2648                                         intersect = Rectangle.Intersect (clip, r);
2649                                         if (intersect != Rectangle.Empty)
2650                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace), intersect);
2651                                         break;
2652                                 }
2653                                 
2654                                 default:
2655                                         break;
2656                                 }
2657                         } else {
2658                                 first_arrow_area = new Rectangle(0, 0, scrollbutton_width, bar.Height);
2659                                 bar.FirstArrowArea = first_arrow_area;
2660
2661                                 second_arrow_area = new Rectangle (bar.ClientRectangle.Width - scrollbutton_width, 0, scrollbutton_width, bar.Height);
2662                                 bar.SecondArrowArea = second_arrow_area;
2663
2664                                 thumb_pos.Height = bar.Height;
2665                                 bar.ThumbPos = thumb_pos;
2666
2667                                 /* Buttons */
2668                                 if (clip.IntersectsWith (first_arrow_area))
2669                                         CPDrawScrollButton (dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state);
2670                                 if (clip.IntersectsWith (second_arrow_area))
2671                                         CPDrawScrollButton (dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state);
2672
2673                                 /* Background */                                        
2674                                 switch (bar.thumb_moving) {
2675                                 case ScrollBar.ThumbMoving.None: {
2676                                         Rectangle r = new Rectangle (scrollbutton_width,
2677                                                         0, bar.ClientRectangle.Width - (scrollbutton_width * 2), bar.ClientRectangle.Height);
2678                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2679
2680                                         if (intersect != Rectangle.Empty)
2681                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace), intersect);
2682                                         break;
2683                                 }
2684                                 
2685                                 case ScrollBar.ThumbMoving.Forward: {
2686                                         Rectangle r = new Rectangle (scrollbutton_width,  0,
2687                                                         thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height);
2688                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2689
2690                                         if (intersect != Rectangle.Empty)
2691                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace), intersect);
2692
2693                                         r.X = thumb_pos.X + thumb_pos.Width;
2694                                         r.Y = 0;
2695                                         r.Width = bar.ClientRectangle.Width -  (thumb_pos.X + thumb_pos.Width) - scrollbutton_width;
2696                                         r.Height = bar.ClientRectangle.Height;
2697
2698                                         intersect = Rectangle.Intersect (clip, r);
2699                                         if (intersect != Rectangle.Empty)
2700                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63,63,63), Color.Black), intersect);
2701                                         break;
2702                                 }
2703                                 
2704                                 case ScrollBar.ThumbMoving.Backwards: {
2705                                         Rectangle r = new Rectangle (scrollbutton_width,  0,
2706                                                         thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height);
2707                                         Rectangle intersect = Rectangle.Intersect (clip, r);
2708
2709                                         if (intersect != Rectangle.Empty)
2710                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, Color.FromArgb (255, 63,63,63), Color.Black), intersect);
2711
2712                                         r.X = thumb_pos.X + thumb_pos.Width;
2713                                         r.Y = 0;
2714                                         r.Width = bar.ClientRectangle.Width -  (thumb_pos.X + thumb_pos.Width) - scrollbutton_width;
2715                                         r.Height = bar.ClientRectangle.Height;
2716
2717                                         intersect = Rectangle.Intersect (clip, r);
2718                                         if (intersect != Rectangle.Empty)
2719                                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace), intersect);
2720                                         break;
2721                                 }
2722                                 }
2723                         }
2724
2725                         /* Thumb */
2726                         if (bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith (thumb_pos))
2727                                 DrawScrollButtonPrimitive (dc, thumb_pos, ButtonState.Normal);                          
2728                 }
2729
2730                 public override int ScrollBarButtonSize {
2731                         get { return 16; }
2732                 }
2733                 #endregion      // ScrollBar
2734
2735                 #region StatusBar
2736                 public  override void DrawStatusBar (Graphics dc, Rectangle clip, StatusBar sb) {
2737                         Rectangle area = sb.ClientRectangle;
2738                         int horz_border = 2;
2739                         int vert_border = 2;
2740
2741                         dc.FillRectangle (GetControlBackBrush (sb.BackColor), clip);
2742                         
2743                         if (sb.Panels.Count == 0 && sb.Text != String.Empty) {
2744                                 string text = sb.Text;
2745                                 StringFormat string_format = new StringFormat ();
2746                                 string_format.Trimming = StringTrimming.Character;
2747                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
2748
2749                                 if (text [0] == '\t') {
2750                                         string_format.Alignment = StringAlignment.Center;
2751                                         text = text.Substring (1);
2752                                         if (text [0] == '\t') {
2753                                                 string_format.Alignment = StringAlignment.Far;
2754                                                 text = text.Substring (1);
2755                                         }
2756                                 }
2757                 
2758                                 dc.DrawString (text, sb.Font, ResPool.GetSolidBrush (sb.ForeColor),
2759                                                 new Rectangle(area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4), string_format);
2760                         } else if (sb.ShowPanels) {
2761                                 SolidBrush br_forecolor = GetControlForeBrush (sb.ForeColor);
2762                                 int prev_x = area.X + horz_border;
2763                                 int y = area.Y + vert_border;
2764                                 for (int i = 0; i < sb.Panels.Count; i++) {
2765                                         Rectangle pr = new Rectangle (prev_x, y,
2766                                                 sb.Panels [i].Width, area.Height);
2767                                         prev_x += pr.Width + StatusBarHorzGapWidth;
2768                                         if (pr.IntersectsWith (clip))
2769                                                 DrawStatusBarPanel (dc, pr, i, br_forecolor, sb.Panels [i]);
2770                                 }
2771                         }
2772
2773                         if (sb.SizingGrip)
2774                                 CPDrawSizeGrip (dc, ColorButtonFace, area);
2775
2776                 }
2777
2778
2779                 private void DrawStatusBarPanel (Graphics dc, Rectangle area, int index,
2780                         SolidBrush br_forecolor, StatusBarPanel panel) {
2781                         int border_size = 3; // this is actually const, even if the border style is none
2782
2783                         area.Height -= border_size;
2784                         if (panel.BorderStyle != StatusBarPanelBorderStyle.None) {
2785                                 Border3DStyle border_style = Border3DStyle.SunkenInner;
2786                                 if (panel.BorderStyle == StatusBarPanelBorderStyle.Raised)
2787                                         border_style = Border3DStyle.RaisedOuter;
2788                                 CPDrawBorder3D(dc, area, border_style, Border3DSide.All, ColorButtonFace);
2789                         }
2790
2791                         if (panel.Style == StatusBarPanelStyle.OwnerDraw) {
2792                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs (
2793                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
2794                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor);
2795                                 panel.Parent.OnDrawItemInternal (e);
2796                                 return;
2797                         }
2798
2799                         int left = area.Left;
2800                         if (panel.Icon != null) {
2801                                 left += 2;
2802                                 dc.DrawIcon (panel.Icon, left, area.Top);
2803                                 left += panel.Icon.Width;
2804                         }
2805
2806                         if (panel.Text == String.Empty)
2807                                 return;
2808
2809                         string text = panel.Text;
2810                         StringFormat string_format = new StringFormat ();
2811                         string_format.Trimming = StringTrimming.Character;
2812                         string_format.FormatFlags = StringFormatFlags.NoWrap;
2813
2814                         if (text [0] == '\t') {
2815                                 string_format.Alignment = StringAlignment.Center;
2816                                 text = text.Substring (1);
2817                                 if (text [0] == '\t') {
2818                                         string_format.Alignment = StringAlignment.Far;
2819                                         text = text.Substring (1);
2820                                 }
2821                         }
2822
2823                         int x = left + border_size;
2824                         int y = border_size + 2;
2825                         Rectangle r = new Rectangle (x, y, 
2826                                 area.Right - x - border_size,
2827                                 area.Bottom - y - border_size);
2828                         
2829                         dc.DrawString (text, panel.Parent.Font, br_forecolor, r, string_format);
2830                 }
2831
2832                 public override int StatusBarSizeGripWidth {
2833                         get { return 15; }
2834                 }
2835
2836                 public override int StatusBarHorzGapWidth {
2837                         get { return 3; }
2838                 }
2839
2840                 public override Size StatusBarDefaultSize {
2841                         get {
2842                                 return new Size (100, 22);
2843                         }
2844                 }
2845                 #endregion      // StatusBar
2846
2847                 public override void DrawTabControl (Graphics dc, Rectangle area, TabControl tab)
2848                 {
2849                         // Do we need to fill the back color? It can't be changed...
2850                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), area);
2851                         Rectangle panel_rect = GetTabPanelRectExt (tab);
2852
2853                         if (tab.Appearance == TabAppearance.Normal) {
2854                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.RaisedInner, Border3DSide.Left | Border3DSide.Top, ColorButtonFace);
2855                                 CPDrawBorder3D (dc, panel_rect, Border3DStyle.Raised, Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
2856                         }
2857
2858                         if (tab.Alignment == TabAlignment.Top) {
2859                                 for (int r = tab.TabPages.Count; r > 0; r--) {
2860                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
2861                                                 if (i == tab.SelectedIndex)
2862                                                         continue;
2863                                                 if (r != tab.TabPages [i].Row)
2864                                                         continue;
2865                                                 Rectangle rect = tab.GetTabRect (i);
2866                                                 if (!rect.IntersectsWith (area))
2867                                                         continue;
2868                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
2869                                         }
2870                                 }
2871                         } else {
2872                                 for (int r = 0; r < tab.TabPages.Count; r++) {
2873                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
2874                                                 if (i == tab.SelectedIndex)
2875                                                         continue;
2876                                                 if (r != tab.TabPages [i].Row)
2877                                                         continue;
2878                                                 Rectangle rect = tab.GetTabRect (i);
2879                                                 if (!rect.IntersectsWith (area))
2880                                                         continue;
2881                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
2882                                         }
2883                                 }
2884                         }
2885
2886                         if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
2887                                 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
2888                                 if (rect.IntersectsWith (area))
2889                                         DrawTab (dc, tab.TabPages [tab.SelectedIndex], tab, rect, true);
2890                         }
2891
2892                         if (tab.ShowSlider) {
2893                                 Rectangle right = GetTabControlRightScrollRect (tab);
2894                                 Rectangle left = GetTabControlLeftScrollRect (tab);
2895                                 CPDrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
2896                                 CPDrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
2897                         }
2898                 }
2899
2900                 public override Rectangle GetTabControlLeftScrollRect (TabControl tab)
2901                 {
2902                         switch (tab.Alignment) {
2903                         case TabAlignment.Top:
2904                                 return new Rectangle (tab.ClientRectangle.Right - 34, tab.ClientRectangle.Top + 1, 17, 17);
2905                         default:
2906                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
2907                                 return new Rectangle (tab.ClientRectangle.Right - 34, panel_rect.Bottom + 2, 17, 17);
2908                         }
2909                 }
2910
2911                 public override Rectangle GetTabControlRightScrollRect (TabControl tab)
2912                 {
2913                         switch (tab.Alignment) {
2914                         case TabAlignment.Top:
2915                                 return new Rectangle (tab.ClientRectangle.Right - 17, tab.ClientRectangle.Top + 1, 17, 17);
2916                         default:
2917                                 Rectangle panel_rect = GetTabPanelRectExt (tab);
2918                                 return new Rectangle (tab.ClientRectangle.Right - 17, panel_rect.Bottom + 2, 17, 17);
2919                         }
2920                 }
2921
2922                 public override Size TabControlDefaultItemSize {
2923                         get { return new Size (42, 21); }
2924                 }
2925
2926                 public override Point TabControlDefaultPadding {
2927                         get { return new Point (6, 3); }
2928                 }
2929
2930                 public override int TabControlMinimumTabWidth {
2931                         get { return 42; }
2932                 }
2933
2934                 public override Rectangle GetTabControlDisplayRectangle (TabControl tab)
2935                 {
2936                         Rectangle ext = GetTabPanelRectExt (tab);
2937                         // Account for border size
2938                         return new Rectangle (ext.Left + 2, ext.Top + 1, ext.Width - 6, ext.Height - 4);
2939                 }
2940
2941                 public override Size TabControlGetSpacing (TabControl tab) {
2942                         switch (tab.Appearance) {
2943                                 case TabAppearance.Normal:
2944                                         return new Size (1, -2);
2945                                 case TabAppearance.Buttons:
2946                                         return new Size (3, 3);
2947                                 case TabAppearance.FlatButtons:
2948                                         return new Size (9, 3);
2949                                 default:
2950                                         throw new Exception ("Invalid Appearance value: " + tab.Appearance);
2951                                 }
2952                 }
2953
2954                 private Rectangle GetTabPanelRectExt (TabControl tab)
2955                 {
2956                         // Offset the tab from the top corner
2957                         Rectangle res = new Rectangle (tab.ClientRectangle.X + 2,
2958                                         tab.ClientRectangle.Y,
2959                                         tab.ClientRectangle.Width - 2,
2960                                         tab.ClientRectangle.Height - 1);
2961
2962                         if (tab.TabCount == 0)
2963                                 return res;
2964
2965                         int spacing = TabControlGetSpacing (tab).Height;
2966                         int offset = (tab.ItemSize.Height + spacing) * tab.RowCount + 3;
2967
2968                         switch (tab.Alignment) {
2969                         case TabAlignment.Left:
2970                                 res.X += offset;
2971                                 res.Width -= offset;
2972                                 break;
2973                         case TabAlignment.Right:
2974                                 res.Width -= offset;
2975                                 break;
2976                         case TabAlignment.Top:
2977                                 res.Y += offset;
2978                                 res.Height -= offset;
2979                                 break;
2980                         case TabAlignment.Bottom:
2981                                 res.Height -= offset;
2982                                 break;
2983                         }
2984
2985                         return res;
2986                 }
2987
2988                 private int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
2989                 {
2990                         int FlatButtonSpacing = 8;                      
2991                         Rectangle interior;
2992                         int res = bounds.Width;
2993
2994                         // we can't fill the background right away because the bounds might be adjusted if the tab is selected
2995
2996                         if (tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons) {
2997
2998                                 dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
2999
3000                                 // Separators
3001                                 if (tab.Appearance == TabAppearance.FlatButtons) {
3002                                         int width = bounds.Width;
3003                                         bounds.Width += (FlatButtonSpacing - 2);
3004                                         res = bounds.Width;
3005                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Right);
3006                                         bounds.Width = width;
3007                                 }
3008
3009                                 if (is_selected) {
3010                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Sunken, Border3DSide.All);
3011                                 } else if (tab.Appearance != TabAppearance.FlatButtons) {
3012                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Raised, Border3DSide.All);
3013                                 }
3014
3015                                 interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 4, bounds.Height - 4);
3016
3017                                 
3018                                 StringFormat string_format = new StringFormat ();
3019                                 string_format.Alignment = StringAlignment.Center;
3020                                 string_format.LineAlignment = StringAlignment.Center;
3021                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3022
3023                                 interior.Y++;
3024                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), interior, string_format);
3025                                 interior.Y--;
3026                         } else {
3027                                 Pen light = ResPool.GetPen (ControlPaint.LightLight (tab.BackColor));
3028
3029                                 switch (tab.Alignment) {
3030                                         
3031                                 case TabAlignment.Top:
3032
3033
3034                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3035
3036                                         dc.DrawLine (light, bounds.Left, bounds.Bottom, bounds.Left, bounds.Top + 3);
3037                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
3038                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right - 3, bounds.Top);
3039
3040                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom);
3041                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 1, bounds.Top + 2, bounds.Right, bounds.Top + 3);
3042                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom);
3043
3044                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3045
3046                                         if (page.Text != String.Empty) {
3047                                                 StringFormat string_format = new StringFormat ();
3048                                                 string_format.Alignment = StringAlignment.Center;
3049                                                 string_format.LineAlignment = StringAlignment.Center;
3050                                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3051                                                 interior.Y++;
3052                                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), interior, string_format);
3053                                                 interior.Y--;
3054                                         }
3055
3056                                         break;
3057
3058                                 case TabAlignment.Bottom:
3059
3060                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3061
3062                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 3);
3063                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left + 2, bounds.Bottom - 1);
3064
3065                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left + 3, bounds.Bottom - 1, bounds.Right - 3, bounds.Bottom - 1);
3066                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Bottom - 3, bounds.Right - 1, bounds.Top);
3067
3068                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 3, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
3069                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right - 3, bounds.Bottom, bounds.Right, bounds.Bottom - 3);
3070                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom - 3, bounds.Right, bounds.Top);
3071
3072                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3073
3074                                         if (page.Text != String.Empty) {
3075                                                 StringFormat string_format = new StringFormat ();
3076                                                 string_format.Alignment = StringAlignment.Center;
3077                                                 string_format.LineAlignment = StringAlignment.Center;
3078                                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3079                                                 interior.Y++;
3080                                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), interior, string_format);
3081                                                 interior.Y--;
3082                                         }
3083
3084                                         break;
3085
3086                                 case TabAlignment.Left:
3087
3088                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3089
3090                                         dc.DrawLine (light, bounds.Left, bounds.Bottom - 3, bounds.Left, bounds.Top + 3);
3091                                         dc.DrawLine (light, bounds.Left, bounds.Top + 3, bounds.Left + 3, bounds.Top);
3092                                         dc.DrawLine (light, bounds.Left + 3, bounds.Top, bounds.Right, bounds.Top);
3093
3094                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right, bounds.Bottom - 1, bounds.Left + 2, bounds.Bottom - 1);
3095
3096                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Bottom, bounds.Left + 2, bounds.Bottom);
3097                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left + 2, bounds.Bottom, bounds.Left, bounds.Bottom - 3);
3098
3099                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3100
3101                                         if (page.Text != String.Empty) {
3102                                                 StringFormat string_format = new StringFormat ();
3103                                                 // Flip the text around
3104                                                 string_format.Alignment = StringAlignment.Center;
3105                                                 string_format.LineAlignment = StringAlignment.Center;
3106                                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3107                                                 string_format.FormatFlags = StringFormatFlags.DirectionVertical;
3108                                                 int wo = interior.Width / 2;
3109                                                 int ho = interior.Height / 2;
3110                                                 dc.TranslateTransform (interior.X + wo, interior.Y + ho);
3111                                                 dc.RotateTransform (180);
3112                                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), 0, 0, string_format);
3113                                                 dc.ResetTransform ();
3114                                         }
3115
3116                                         break;
3117
3118                                 default:
3119                                         // TabAlignment.Right
3120
3121                                         dc.FillRectangle (GetControlBackBrush (tab.BackColor), bounds);
3122
3123                                         dc.DrawLine (light, bounds.Left, bounds.Top, bounds.Right - 3, bounds.Top);
3124                                         dc.DrawLine (light, bounds.Right - 3, bounds.Top, bounds.Right, bounds.Top + 3);
3125
3126                                         dc.DrawLine (SystemPens.ControlDark, bounds.Right - 1, bounds.Top + 1, bounds.Right - 1, bounds.Bottom - 1);
3127                                         dc.DrawLine (SystemPens.ControlDark, bounds.Left, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
3128
3129                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Right, bounds.Top + 3, bounds.Right, bounds.Bottom - 3);
3130                                         dc.DrawLine (SystemPens.ControlDarkDark, bounds.Left, bounds.Bottom, bounds.Right - 3, bounds.Bottom);
3131
3132                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
3133
3134                                         if (page.Text != String.Empty) {
3135                                                 StringFormat string_format = new StringFormat ();
3136                                                 string_format.Alignment = StringAlignment.Center;
3137                                                 string_format.LineAlignment = StringAlignment.Center;
3138                                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
3139                                                 string_format.FormatFlags = StringFormatFlags.DirectionVertical;
3140                                                 interior.X++;
3141                                                 dc.DrawString (page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush (SystemColors.ControlText), interior, string_format);
3142                                                 interior.X--;
3143                                         }
3144
3145                                         break;
3146                                 }
3147                         }
3148
3149                         if (page.Focused) {
3150                                 CPDrawFocusRectangle (dc, interior, tab.ForeColor, tab.BackColor);
3151                         }
3152
3153                         return res;
3154                 }
3155
3156                 #region ToolBar
3157                 public  override void DrawToolBar (Graphics dc, Rectangle clip_rectangle, ToolBar control) {
3158                         StringFormat    format = new StringFormat ();
3159                         format.Trimming = StringTrimming.EllipsisWord;
3160                         if (control.textAlignment == ToolBarTextAlign.Underneath) {
3161                                 format.LineAlignment = StringAlignment.Center;
3162                                 format.Alignment = StringAlignment.Center;
3163                         } else {
3164                                 format.LineAlignment = StringAlignment.Center;
3165                                 format.Alignment = StringAlignment.Near;
3166                         }
3167                         
3168                         // Exclude the area for divider
3169                         Rectangle paint_area = new Rectangle (0, ToolBarGripWidth / 2, 
3170                                 control.Width, control.Height - ToolBarGripWidth / 2);
3171                         bool flat = (control.Appearance == ToolBarAppearance.Flat);
3172                         dc.FillRectangle (SystemBrushes.Control, paint_area);
3173                         CPDrawBorderStyle (dc, paint_area, control.BorderStyle);
3174
3175                         if (control.Divider)
3176                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), 0, 0, paint_area.Width, 0);
3177
3178                         foreach (ToolBarButton button in control.Buttons) {
3179
3180                                 Image image = null;
3181                                 Rectangle buttonArea = button.Rectangle;
3182                                 Rectangle imgRect = Rectangle.Empty;  // rect to draw the image
3183                                 Rectangle txtRect = buttonArea;       // rect to draw the text
3184                                 Rectangle ddRect = Rectangle.Empty;   // rect for the drop down arrow
3185
3186                                 // calculate different rects and draw the frame if its not separator button
3187                                 if (button.Style != ToolBarButtonStyle.Separator) {
3188                                         /* Adjustment for drop down arrow */
3189                                         if (button.Style == ToolBarButtonStyle.DropDownButton && control.DropDownArrows) {
3190                                                 ddRect.X = buttonArea.X + buttonArea.Width - this.ToolBarDropDownWidth;
3191                                                 ddRect.Y = buttonArea.Y;
3192                                                 ddRect.Width = this.ToolBarDropDownWidth;
3193                                                 ddRect.Height = buttonArea.Height;
3194                                         }
3195
3196                                         // calculate txtRect and imgRect, if imageIndex and imageList are present
3197                                         if (button.ImageIndex > -1 && control.ImageList != null) {
3198                                                 if (button.ImageIndex < control.ImageList.Images.Count)
3199                                                         image = control.ImageList.Images [button.ImageIndex];
3200                                                 // draw the image at the centre if textalignment is underneath
3201                                                 if (control.TextAlign == ToolBarTextAlign.Underneath) {
3202                                                         imgRect.X = buttonArea.X + ((buttonArea.Width - ddRect.Width 
3203                                                                 - control.ImageSize.Width) / 2) 
3204                                                                 + this.ToolBarImageGripWidth;
3205                                                         imgRect.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3206                                                         imgRect.Width = control.ImageSize.Width;
3207                                                         imgRect.Height = control.ImageSize.Height;
3208
3209                                                         txtRect.X = buttonArea.X;
3210                                                         txtRect.Y = buttonArea.Y + imgRect.Height + 2 * this.ToolBarImageGripWidth;
3211                                                         txtRect.Width = buttonArea.Width - ddRect.Width;
3212                                                         txtRect.Height = buttonArea.Height - imgRect.Height 
3213                                                                 - 2 * this.ToolBarImageGripWidth;
3214                                                 }
3215                                                 else {
3216                                                         imgRect.X = buttonArea.X + this.ToolBarImageGripWidth;
3217                                                         imgRect.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3218                                                         imgRect.Width = control.ImageSize.Width;
3219                                                         imgRect.Height = control.ImageSize.Height;
3220
3221                                                         txtRect.X = buttonArea.X + imgRect.Width + 2 * this.ToolBarImageGripWidth;
3222                                                         txtRect.Y = buttonArea.Y;
3223                                                         txtRect.Width = buttonArea.Width - imgRect.Width 
3224                                                                 - 2 * this.ToolBarImageGripWidth - ddRect.Width;
3225                                                         txtRect.Height = buttonArea.Height;
3226                                                 }
3227                                         }
3228                                         /* Draw the button frame, only if it is not a separator */
3229                                         if (flat) { 
3230                                                 if (button.Pushed || button.Pressed) {
3231                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.SunkenOuter, Border3DSide.All, ColorButtonFace);
3232                                                 } else if (button.Hilight) {
3233                                                         dc.DrawRectangle (ResPool.GetPen (ColorButtonText), buttonArea);
3234                                                         if (! ddRect.IsEmpty) {
3235                                                                 dc.DrawLine (ResPool.GetPen (ColorButtonText), ddRect.X, ddRect.Y, ddRect.X, 
3236                                                                         ddRect.Y + ddRect.Height);
3237                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3238                                                         }
3239                                                 }
3240                                         }
3241                                         else { // normal toolbar
3242                                                 if (button.Pushed || button.Pressed) {
3243                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.SunkenInner,
3244                                                                 Border3DSide.All, ColorButtonFace);
3245                                                         if (! ddRect.IsEmpty) {
3246                                                                 CPDrawBorder3D (dc, ddRect, Border3DStyle.SunkenInner,
3247                                                                         Border3DSide.Left, ColorButtonFace);
3248                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3249                                                         }
3250                                                 }
3251                                                 else {
3252                                                         CPDrawBorder3D (dc, buttonArea, Border3DStyle.RaisedInner,
3253                                                                 Border3DSide.All, ColorButtonFace);
3254                                                         if (! ddRect.IsEmpty) {
3255                                                                 CPDrawBorder3D (dc, ddRect, Border3DStyle.RaisedInner,
3256                                                                         Border3DSide.Left, ColorButtonFace);
3257                                                                 buttonArea.Width -= this.ToolBarDropDownWidth;
3258                                                         }
3259                                                 }
3260                                         }
3261                                 }
3262                                 DrawToolBarButton (dc, button, control.Font, format, paint_area, buttonArea,
3263                                         imgRect, image, txtRect, ddRect, flat);
3264                         }
3265                 }
3266
3267                 private void DrawToolBarButton (Graphics dc, ToolBarButton button, Font font, StringFormat format,
3268                         Rectangle controlArea, Rectangle buttonArea, Rectangle imgRect, 
3269                         Image image, Rectangle txtRect, Rectangle ddRect, bool flat) {
3270                         if (! button.Visible)
3271                                 return;
3272
3273                         switch (button.Style) {
3274
3275                         case ToolBarButtonStyle.Separator:
3276                                 // separator is drawn only in the case of flat appearance
3277                                 if (flat) {
3278                                         dc.DrawLine (ResPool.GetPen (ColorButtonShadow), buttonArea.X + 1, buttonArea.Y, 
3279                                                 buttonArea.X + 1, buttonArea.Height);
3280                                         dc.DrawLine (ResPool.GetPen (ColorButtonHilight), buttonArea.X + 1 + (int) ResPool.GetPen (ColorButtonFace).Width,
3281                                                 buttonArea.Y, buttonArea.X + 1 + (int) ResPool.GetPen (ColorButtonFace).Width, buttonArea.Height);
3282                                         /* draw a horizontal separator */
3283                                         if (button.Wrapper) {
3284                                                 int y = buttonArea.Height + this.ToolBarSeparatorWidth / 2;
3285                                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), 0, y, controlArea.Width, y);
3286                                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), 0, y + 1 + (int) ResPool.GetPen (ColorButtonFace).Width, controlArea.Width,
3287                                                         y + 1 + (int) ResPool.GetPen (ColorButtonFace).Width);
3288                                         }
3289                                 }
3290                                 break;
3291
3292                         case ToolBarButtonStyle.ToggleButton:
3293                                 Rectangle toggleArea = Rectangle.Empty;
3294                                 toggleArea.X = buttonArea.X + this.ToolBarImageGripWidth;
3295                                 toggleArea.Y = buttonArea.Y + this.ToolBarImageGripWidth;
3296                                 toggleArea.Width = buttonArea.Width - 2 * this.ToolBarImageGripWidth;
3297                                 toggleArea.Height = buttonArea.Height - 2 * this.ToolBarImageGripWidth;
3298                                 if (button.PartialPush && button.Pushed) {
3299                                         dc.FillRectangle (SystemBrushes.ControlLightLight, toggleArea);
3300                                         if (! imgRect.IsEmpty) {
3301                                                 if (button.Enabled && image != null)
3302                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width, 
3303                                                                 imgRect.Height, button.ImageIndex);
3304                                                 else {
3305                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3306                                                         ControlPaint.DrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3307                                                                 Border3DSide.Right | Border3DSide.Bottom);
3308                                                 }
3309                                         }
3310                                         if (button.Enabled)
3311                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3312                                         else
3313                                                 CPDrawStringDisabled (dc, button.Text, font, ColorButtonHilight, txtRect, format);
3314                                 }
3315
3316                                 else if (button.PartialPush) {
3317                                         dc.FillRectangle (SystemBrushes.ControlLight, toggleArea);
3318                                         if (! imgRect.IsEmpty) {
3319                                                 if (button.Enabled && image != null)
3320                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3321                                                                 imgRect.Height, button.ImageIndex);
3322                                                 else {
3323                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3324                                                         ControlPaint.DrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3325                                                                 Border3DSide.Right | Border3DSide.Bottom);
3326                                                 }
3327                                         }
3328                                         if (button.Enabled)
3329                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3330                                         else
3331                                                 CPDrawStringDisabled (dc, button.Text, font, ColorButtonHilight,
3332                                                         txtRect, format);
3333                                 }
3334
3335                                 else if (button.Pushed) {
3336                                         dc.FillRectangle (SystemBrushes.ControlLightLight, toggleArea);
3337                                         if (! imgRect.IsEmpty) {
3338                                                 if (button.Enabled && image != null)
3339                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3340                                                                 imgRect.Height, button.ImageIndex);
3341                                                 else {
3342                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3343                                                         CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3344                                                                 Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
3345                                                 }
3346                                         }
3347                                         if (button.Enabled)
3348                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3349                                         else
3350                                                 CPDrawStringDisabled (dc, button.Text, font, ColorButtonHilight,
3351                                                         txtRect, format);
3352                                 }
3353
3354                                 else {
3355                                         dc.FillRectangle (SystemBrushes.Control, toggleArea);
3356                                         if (! imgRect.IsEmpty) {
3357                                                 if (button.Enabled && image != null)
3358                                                         button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width,
3359                                                                 imgRect.Height, button.ImageIndex);
3360                                                 else {
3361                                                         dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3362                                                         CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3363                                                                 Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
3364                                                 }
3365                                         }
3366                                         if (button.Enabled)
3367                                                 dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3368                                         else
3369                                                 CPDrawStringDisabled (dc, button.Text, font, ColorButtonHilight,
3370                                                         txtRect, format);
3371                                 }
3372                                 break;
3373
3374                         case ToolBarButtonStyle.DropDownButton:
3375                                 // draw the dropdown arrow
3376                                 if (! ddRect.IsEmpty) {
3377                                         PointF [] vertices = new PointF [3];
3378                                         PointF ddCenter = new PointF (ddRect.X + (ddRect.Width/2.0f), ddRect.Y + (ddRect.Height/2.0f));
3379                                         vertices [0].X = ddCenter.X - this.ToolBarDropDownArrowWidth / 2.0f + 0.5f;
3380                                         vertices [0].Y = ddCenter.Y;
3381                                         vertices [1].X = ddCenter.X + this.ToolBarDropDownArrowWidth / 2.0f + 0.5f;
3382                                         vertices [1].Y = ddCenter.Y;
3383                                         vertices [2].X = ddCenter.X + 0.5f; // 0.5 is added for adjustment
3384                                         vertices [2].Y = ddCenter.Y + this.ToolBarDropDownArrowHeight;
3385                                         dc.FillPolygon (SystemBrushes.ControlText, vertices);
3386                                 }
3387                                 goto case ToolBarButtonStyle.PushButton;
3388
3389                         case ToolBarButtonStyle.PushButton:
3390                                 if (! imgRect.IsEmpty){
3391                                         if (button.Enabled && image != null)
3392                                                 button.Parent.ImageList.Draw (dc, imgRect.X, imgRect.Y, imgRect.Width, imgRect.Height,
3393                                                         button.ImageIndex);
3394                                         else {
3395                                                 dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ColorGrayText), imgRect);
3396                                                 CPDrawBorder3D (dc, imgRect, Border3DStyle.SunkenOuter,
3397                                                         Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
3398                                         }
3399                                 }
3400                                 if (button.Enabled)
3401                                         dc.DrawString (button.Text, font, SystemBrushes.ControlText, txtRect, format);
3402                                 else
3403                                         CPDrawStringDisabled (dc, button.Text, font, ColorButtonHilight,
3404                                                 txtRect, format);
3405                                 break;
3406                         }
3407                 }
3408
3409                 // Grip width for the ToolBar
3410                 public override int ToolBarGripWidth {
3411                         get { return 2;}
3412                 }
3413
3414                 // Grip width for the Image on the ToolBarButton
3415                 public override int ToolBarImageGripWidth {
3416                         get { return 2;}
3417                 }
3418
3419                 // width of the separator
3420                 public override int ToolBarSeparatorWidth {
3421                         get { return 4; }
3422                 }
3423
3424                 // width of the dropdown arrow rect
3425                 public override int ToolBarDropDownWidth {
3426                         get { return 13; }
3427                 }
3428
3429                 // width for the dropdown arrow on the ToolBarButton
3430                 public override int ToolBarDropDownArrowWidth {
3431                         get { return 5;}
3432                 }
3433
3434                 // height for the dropdown arrow on the ToolBarButton
3435                 public override int ToolBarDropDownArrowHeight {
3436                         get { return 3;}
3437                 }
3438
3439                 public override Size ToolBarDefaultSize {
3440                         get {
3441                                 return new Size (100, 42);
3442                         }
3443                 }
3444                 #endregion      // ToolBar
3445
3446                 #region ToolTip
3447                 public override void DrawToolTip(Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control) {
3448                         dc.FillRectangle(ResPool.GetSolidBrush(this.ColorInfoWindow), control.client_rect);
3449                         dc.DrawRectangle(ResPool.GetPen(this.ColorWindowFrame), 0, 0, control.Width-1, control.Height-1);
3450                         dc.DrawString(control.text, control.Font, ResPool.GetSolidBrush(this.ColorInfoText), control.client_rect, control.string_format);
3451                 }
3452
3453                 public override Size ToolTipSize(ToolTip.ToolTipWindow tt, string text) {
3454                         SizeF   sizef;
3455
3456                         sizef = tt.DeviceContext.MeasureString(text, tt.Font);
3457                         return new Size((int)sizef.Width+2, (int)sizef.Height+3);               // Need space for the border
3458                 }
3459                 #endregion      // ToolTip
3460
3461                 #region TrackBar
3462                 private void DrawTrackBar_Vertical (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
3463                         ref Rectangle thumb_pos, ref Rectangle thumb_area,  Brush br_thumb,
3464                         float ticks, int value_pos, bool mouse_value) {                 
3465
3466                         Point toptick_startpoint = new Point ();
3467                         Point bottomtick_startpoint = new Point ();
3468                         Point channel_startpoint = new Point ();
3469                         float pixel_len;
3470                         float pixels_betweenticks;
3471                         const int space_from_right = 8;
3472                         const int space_from_left = 8;
3473                         Rectangle area = tb.ClientRectangle;
3474                         
3475                         switch (tb.TickStyle)   {
3476                         case TickStyle.BottomRight:
3477                         case TickStyle.None:
3478                                 channel_startpoint.Y = 8;
3479                                 channel_startpoint.X = 9;
3480                                 bottomtick_startpoint.Y = 13;
3481                                 bottomtick_startpoint.X = 24;                           
3482                                 break;
3483                         case TickStyle.TopLeft:
3484                                 channel_startpoint.Y = 8;
3485                                 channel_startpoint.X = 19;
3486                                 toptick_startpoint.Y = 13;
3487                                 toptick_startpoint.X = 8;
3488                                 break;
3489                         case TickStyle.Both:
3490                                 channel_startpoint.Y = 8;
3491                                 channel_startpoint.X = 18;      
3492                                 bottomtick_startpoint.Y = 13;
3493                                 bottomtick_startpoint.X = 32;                           
3494                                 toptick_startpoint.Y = 13;
3495                                 toptick_startpoint.X = 8;                               
3496                                 break;
3497                         default:
3498                                 break;
3499                         }
3500                         
3501                         thumb_area.X = area.X + channel_startpoint.X;
3502                         thumb_area.Y = area.Y + channel_startpoint.Y;
3503                         thumb_area.Height = area.Height - space_from_right - space_from_left;
3504                         thumb_area.Width = 4;
3505
3506                         /* Draw channel */
3507                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonShadow), channel_startpoint.X, channel_startpoint.Y,
3508                                 1, thumb_area.Height);
3509                         
3510                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonDkShadow), channel_startpoint.X + 1, channel_startpoint.Y,
3511                                 1, thumb_area.Height);
3512
3513                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonHilight), channel_startpoint.X + 3, channel_startpoint.Y,
3514                                 1, thumb_area.Height);
3515
3516                         pixel_len = thumb_area.Height - 11;
3517                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
3518                         
3519                         /* Convert thumb position from mouse position to value*/
3520                         if (mouse_value) {
3521                                 
3522                                 if (value_pos >= channel_startpoint.Y)
3523                                         value_pos = (int)(((float) (value_pos - channel_startpoint.Y)) / pixels_betweenticks);
3524                                 else
3525                                         value_pos = 0;                  
3526
3527                                 if (value_pos + tb.Minimum > tb.Maximum)
3528                                         value_pos = tb.Maximum - tb.Minimum;
3529                                 
3530                                 tb.Value = value_pos + tb.Minimum;
3531                         }                       
3532                         
3533                         thumb_pos.Y = channel_startpoint.Y + (int) (pixels_betweenticks * (float) value_pos);
3534                         
3535                         /* Draw thumb fixed 10x22 size */
3536                         thumb_pos.Width = 10;
3537                         thumb_pos.Height = 22;
3538
3539                         switch (tb.TickStyle)   {
3540                         case TickStyle.BottomRight:
3541                         case TickStyle.None: {
3542                                 thumb_pos.X = channel_startpoint.X - 8;
3543
3544                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X , thumb_pos.Y + 10);
3545                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 16, thumb_pos.Y);
3546                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X + 16, thumb_pos.Y, thumb_pos.X + 16 + 4, thumb_pos.Y + 4);
3547                                 
3548                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X +1, thumb_pos.Y + 9, thumb_pos.X +15, thumb_pos.Y  +9);
3549                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 16, thumb_pos.Y + 9, thumb_pos.X +16 + 4, thumb_pos.Y  +9 - 4);
3550
3551                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X, thumb_pos.Y  + 10, thumb_pos.X +16, thumb_pos.Y +10);
3552                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 16, thumb_pos.Y  + 10, thumb_pos.X  +16 + 5, thumb_pos.Y +10 - 5);
3553
3554                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 16, 8);
3555                                 dc.FillRectangle (br_thumb, thumb_pos.X + 17, thumb_pos.Y + 2, 1, 6);
3556                                 dc.FillRectangle (br_thumb, thumb_pos.X + 18, thumb_pos.Y + 3, 1, 4);
3557                                 dc.FillRectangle (br_thumb, thumb_pos.X + 19, thumb_pos.Y + 4, 1, 2);
3558
3559                                 break;
3560                         }
3561                         case TickStyle.TopLeft: {
3562                                 thumb_pos.X = channel_startpoint.X - 10;
3563
3564                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X + 4 + 16, thumb_pos.Y);
3565                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X + 4, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 4);
3566
3567                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X  + 4, thumb_pos.Y + 9, thumb_pos.X + 4 + 16 , thumb_pos.Y+ 9);
3568                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 4, thumb_pos.Y  + 9, thumb_pos.X, thumb_pos.Y + 5);
3569                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X  + 19, thumb_pos.Y + 9, thumb_pos.X  +19 , thumb_pos.Y+ 1);
3570
3571                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X  + 4, thumb_pos.Y+ 10, thumb_pos.X  + 4 + 16, thumb_pos.Y+ 10);
3572                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X  + 4, thumb_pos.Y + 10, thumb_pos.X  -1, thumb_pos.Y+ 5);
3573                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 20, thumb_pos.Y, thumb_pos.X+ 20, thumb_pos.Y + 10);
3574
3575                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 15, 8);
3576                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 1, 6);
3577                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 1, 4);
3578                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 1, 2);
3579
3580                                 break;
3581                         }
3582
3583                         case TickStyle.Both: {
3584                                 thumb_pos.X = area.X + 10;
3585                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 9);
3586                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 19, thumb_pos.Y);
3587
3588                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 1, thumb_pos.Y + 9, thumb_pos.X+ 19, thumb_pos.Y  + 9);
3589                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X  + 10, thumb_pos.Y+ 1, thumb_pos.X + 19, thumb_pos.Y  + 8);
3590
3591                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X, thumb_pos.Y + 10, thumb_pos.X+ 20, thumb_pos.Y  +10);
3592                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X  + 20, thumb_pos.Y, thumb_pos.X  + 20, thumb_pos.Y+ 9);
3593
3594                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 18, 8);
3595
3596                                 break;
3597                         }
3598
3599                         default:
3600                                 break;
3601                         }
3602
3603                         pixel_len = thumb_area.Height - 11;
3604                         pixels_betweenticks = pixel_len / ticks;
3605                         
3606                         thumb_area.X = thumb_pos.X;
3607                         thumb_area.Y = channel_startpoint.Y;
3608                         thumb_area.Width = thumb_pos.Height;
3609                         
3610                         /* Draw ticks*/
3611                         Region outside = new Region (area);
3612                         outside.Exclude (thumb_area);                   
3613                         
3614                         if (outside.IsVisible (clip_rectangle)) {                               
3615                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
3616                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) { 
3617                                         
3618                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks)  {                                       
3619                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
3620                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
3621                                                                 area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc);
3622                                                 else
3623                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
3624                                                                 area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc);
3625                                         }
3626                                 }
3627         
3628                                 if (pixels_betweenticks > 0 &&  ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
3629                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
3630         
3631                                         pixel_len = thumb_area.Height - 11;
3632                                         pixels_betweenticks = pixel_len / ticks;
3633                                         
3634                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
3635                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
3636                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
3637                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc);
3638                                                 else
3639                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
3640                                                                 area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc);
3641                                         }                       
3642                                 }
3643                         }
3644                         
3645                         outside.Dispose ();
3646                         
3647                 }
3648
3649                 /* 
3650                         Horizontal trackbar 
3651                   
3652                         Does not matter the size of the control, Win32 always draws:
3653                                 - Ticks starting from pixel 13, 8
3654                                 - Channel starting at pos 8, 19 and ends at Width - 8
3655                                 - Autosize makes always the control 40 pixels height
3656                                 - Ticks are draw at (channel.Witdh - 10) / (Maximum - Minimum)
3657                                 
3658                 */
3659                 private void DrawTrackBar_Horizontal (Graphics dc, Rectangle clip_rectangle, TrackBar tb,
3660                         ref Rectangle thumb_pos, ref Rectangle thumb_area, Brush br_thumb,
3661                         float ticks, int value_pos, bool mouse_value) {                 
3662                         Point toptick_startpoint = new Point ();
3663                         Point bottomtick_startpoint = new Point ();
3664                         Point channel_startpoint = new Point ();
3665                         float pixel_len;
3666                         float pixels_betweenticks;
3667                         const int space_from_right = 8;
3668                         const int space_from_left = 8;
3669                         Rectangle area = tb.ClientRectangle;
3670                                                 
3671                         switch (tb.TickStyle) {
3672                         case TickStyle.BottomRight:
3673                         case TickStyle.None:
3674                                 channel_startpoint.X = 8;
3675                                 channel_startpoint.Y = 9;
3676                                 bottomtick_startpoint.X = 13;
3677                                 bottomtick_startpoint.Y = 24;                           
3678                                 break;
3679                         case TickStyle.TopLeft:
3680                                 channel_startpoint.X = 8;
3681                                 channel_startpoint.Y = 19;
3682                                 toptick_startpoint.X = 13;
3683                                 toptick_startpoint.Y = 8;
3684                                 break;
3685                         case TickStyle.Both:
3686                                 channel_startpoint.X = 8;
3687                                 channel_startpoint.Y = 18;      
3688                                 bottomtick_startpoint.X = 13;
3689                                 bottomtick_startpoint.Y = 32;                           
3690                                 toptick_startpoint.X = 13;
3691                                 toptick_startpoint.Y = 8;                               
3692                                 break;
3693                         default:
3694                                 break;
3695                         }
3696                                                 
3697                         thumb_area.X = area.X + channel_startpoint.X;
3698                         thumb_area.Y = area.Y + channel_startpoint.Y;
3699                         thumb_area.Width = area.Width - space_from_right - space_from_left;
3700                         thumb_area.Height = 4;
3701                         
3702                         /* Draw channel */
3703                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonShadow), channel_startpoint.X, channel_startpoint.Y,
3704                                 thumb_area.Width, 1);
3705                         
3706                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonDkShadow), channel_startpoint.X, channel_startpoint.Y + 1,
3707                                 thumb_area.Width, 1);
3708
3709                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonHilight), channel_startpoint.X, channel_startpoint.Y +3,
3710                                 thumb_area.Width, 1);
3711
3712                         pixel_len = thumb_area.Width - 11;
3713                         pixels_betweenticks = pixel_len / (tb.Maximum - tb.Minimum);
3714
3715                         /* Convert thumb position from mouse position to value*/
3716                         if (mouse_value) {                      
3717                                 if (value_pos >= channel_startpoint.X)
3718                                         value_pos = (int)(((float) (value_pos - channel_startpoint.X)) / pixels_betweenticks);
3719                                 else
3720                                         value_pos = 0;                          
3721
3722                                 if (value_pos + tb.Minimum > tb.Maximum)
3723                                         value_pos = tb.Maximum - tb.Minimum;
3724                                 
3725                                 tb.Value = value_pos + tb.Minimum;
3726                         }                       
3727                         
3728                         thumb_pos.X = channel_startpoint.X + (int) (pixels_betweenticks * (float) value_pos);
3729                         
3730                         /* Draw thumb fixed 10x22 size */
3731                         thumb_pos.Width = 10;
3732                         thumb_pos.Height = 22;
3733
3734                         switch (tb.TickStyle) {
3735                         case TickStyle.BottomRight:
3736                         case TickStyle.None: {
3737                                 thumb_pos.Y = channel_startpoint.Y - 8;
3738
3739                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 10, thumb_pos.Y);
3740                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 16);
3741                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y + 16, thumb_pos.X + 4, thumb_pos.Y + 16 + 4);
3742
3743                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X +9, thumb_pos.Y +15);
3744                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 16, thumb_pos.X +9 - 4, thumb_pos.Y +16 + 4);
3745
3746                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y +16);
3747                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 10, thumb_pos.Y + 16, thumb_pos.X +10 - 5, thumb_pos.Y +16 + 5);
3748
3749                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 16);
3750                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 17, 6, 1);
3751                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 18, 4, 1);
3752                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 19, 2, 1);
3753                                 break;
3754                         }
3755                         case TickStyle.TopLeft: {
3756                                 thumb_pos.Y = channel_startpoint.Y - 10;
3757
3758                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X, thumb_pos.Y + 4 + 16);
3759                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y + 4, thumb_pos.X + 4, thumb_pos.Y);
3760
3761                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 9, thumb_pos.Y + 4 + 16);
3762                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y);
3763                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 19, thumb_pos.X + 1 , thumb_pos.Y +19);
3764
3765                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 10, thumb_pos.Y + 4 + 16);
3766                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 10, thumb_pos.Y + 4, thumb_pos.X + 5, thumb_pos.Y -1);
3767                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 10, thumb_pos.Y + 20);
3768
3769                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 4, 8, 15);
3770                                 dc.FillRectangle (br_thumb, thumb_pos.X + 2, thumb_pos.Y + 3, 6, 1);
3771                                 dc.FillRectangle (br_thumb, thumb_pos.X + 3, thumb_pos.Y + 2, 4, 1);
3772                                 dc.FillRectangle (br_thumb, thumb_pos.X + 4, thumb_pos.Y + 1, 2, 1);
3773                                 break;
3774                         }
3775
3776                         case TickStyle.Both: {
3777                                 thumb_pos.Y = area.Y + 10;
3778                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X + 9, thumb_pos.Y);
3779                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), thumb_pos.X, thumb_pos.Y, thumb_pos.X, thumb_pos.Y + 19);
3780
3781                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 9, thumb_pos.Y + 1, thumb_pos.X + 9, thumb_pos.Y + 19);
3782                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), thumb_pos.X + 1, thumb_pos.Y + 10, thumb_pos.X + 8, thumb_pos.Y + 19);
3783
3784                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X + 10, thumb_pos.Y, thumb_pos.X +10, thumb_pos.Y + 20);
3785                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), thumb_pos.X, thumb_pos.Y + 20, thumb_pos.X + 9, thumb_pos.Y + 20);
3786
3787                                 dc.FillRectangle (br_thumb, thumb_pos.X + 1, thumb_pos.Y + 1, 8, 18);
3788
3789                                 break;
3790                         }
3791
3792                         default:
3793                                 break;
3794                         }
3795
3796                         pixel_len = thumb_area.Width - 11;
3797                         pixels_betweenticks = pixel_len / ticks;
3798
3799                         /* Draw ticks*/
3800                         thumb_area.Y = thumb_pos.Y;
3801                         thumb_area.X = channel_startpoint.X;
3802                         thumb_area.Height = thumb_pos.Height;
3803                         Region outside = new Region (area);
3804                         outside.Exclude (thumb_area);                   
3805                         
3806                         if (outside.IsVisible (clip_rectangle)) {                               
3807                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.BottomRight) == TickStyle.BottomRight ||
3808                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {                         
3809                                         
3810                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
3811                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
3812                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
3813                                                                 area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3);
3814                                                 else
3815                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
3816                                                                 area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2);
3817                                         }
3818                                 }
3819         
3820                                 if (pixels_betweenticks > 0 && ((tb.TickStyle & TickStyle.TopLeft) == TickStyle.TopLeft ||
3821                                         ((tb.TickStyle & TickStyle.Both) == TickStyle.Both))) {
3822                                         
3823                                         for (float inc = 0; inc < (pixel_len + 1); inc += pixels_betweenticks) {                                        
3824                                                 if (inc == 0 || (inc +  pixels_betweenticks) >= pixel_len +1)
3825                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
3826                                                                 area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y);
3827                                                 else
3828                                                         dc.DrawLine (ResPool.GetPen (pen_ticks_color), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
3829                                                                 area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y );
3830                                         }                       
3831                                 }
3832                         }
3833                         
3834                         outside.Dispose ();                     
3835                 }
3836
3837                 public override void DrawTrackBar (Graphics dc, Rectangle clip_rectangle, TrackBar tb) 
3838                 {
3839                         Brush           br_thumb;
3840                         int             value_pos;
3841                         bool            mouse_value;
3842                         float           ticks = (tb.Maximum - tb.Minimum) / tb.tickFrequency; /* N of ticks draw*/
3843                         Rectangle       area;
3844                         Rectangle       thumb_pos = tb.ThumbPos;
3845                         Rectangle       thumb_area = tb.ThumbArea;
3846                         
3847                         if (tb.thumb_pressed) {
3848                                 value_pos = tb.thumb_mouseclick;
3849                                 mouse_value = true;
3850                         } else {
3851                                 value_pos = tb.Value - tb.Minimum;
3852                                 mouse_value = false;
3853                         }
3854
3855                         area = tb.ClientRectangle;
3856
3857                         if (tb.thumb_pressed == true) {
3858                                 br_thumb = (Brush) ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonHilight, ColorButtonFace);
3859                         } else {
3860                                 br_thumb = ResPool.GetSolidBrush (ColorButtonFace);
3861                         }
3862
3863                         
3864                         /* Control Background */
3865                         if (tb.BackColor == DefaultControlBackColor) {
3866                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonFace), clip_rectangle);
3867                         } else {
3868                                 dc.FillRectangle (ResPool.GetSolidBrush (tb.BackColor), clip_rectangle);
3869                         }
3870                         
3871
3872                         if (tb.Focused) {
3873                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonFace, Color.Black), area.X, area.Y, area.Width - 1, 1);
3874                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonFace, Color.Black), area.X, area.Y + area.Height - 1, area.Width - 1, 1);
3875                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonFace, Color.Black), area.X, area.Y, 1, area.Height - 1);
3876                                 dc.FillRectangle (ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonFace, Color.Black), area.X + area.Width - 1, area.Y, 1, area.Height - 1);
3877                         }
3878
3879                         if (tb.Orientation == Orientation.Vertical) {
3880                                 DrawTrackBar_Vertical (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
3881                                         br_thumb, ticks, value_pos, mouse_value);
3882                         
3883                         } else {
3884                                 DrawTrackBar_Horizontal (dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
3885                                         br_thumb, ticks, value_pos, mouse_value);
3886                         }
3887
3888                         tb.ThumbPos = thumb_pos;
3889                         tb.ThumbArea = thumb_area;
3890                 }
3891
3892                 public override Size TrackBarDefaultSize {
3893                         get {
3894                                 return new Size (104, 42);
3895                         }
3896                 }
3897
3898                 #endregion      // TrackBar
3899
3900                 #region VScrollBar
3901                 public override Size VScrollBarDefaultSize {
3902                         get {
3903                                 return new Size (this.ScrollBarButtonSize, 80);
3904                         }
3905                 }
3906                 #endregion      // VScrollBar
3907
3908                 #region TreeView
3909                 public override Size TreeViewDefaultSize {\r
3910                         get {\r
3911                                 return new Size (121, 97);\r
3912                         }\r
3913                 }\r
3914
3915                 #endregion
3916
3917                 #region ControlPaint
3918                 private enum DrawFrameControlStates {
3919                         ButtonCheck             = 0x0000,
3920                         ButtonRadioImage        = 0x0001,
3921                         ButtonRadioMask         = 0x0002,
3922                         ButtonRadio             = 0x0004,
3923                         Button3State            = 0x0008,
3924                         ButtonPush              = 0x0010,
3925
3926                         CaptionClose            = 0x0000,
3927                         CaptionMin              = 0x0001,
3928                         CaptionMax              = 0x0002,
3929                         CaptionRestore          = 0x0004,
3930                         CaptionHelp             = 0x0008,
3931
3932                         MenuArrow               = 0x0000,
3933                         MenuCheck               = 0x0001,
3934                         MenuBullet              = 0x0002,
3935                         MenuArrowRight          = 0x0004,
3936
3937                         ScrollUp                = 0x0000,
3938                         ScrollDown              = 0x0001,
3939                         ScrollLeft              = 0x0002,
3940                         ScrollRight             = 0x0003,
3941                         ScrollComboBox          = 0x0005,
3942                         ScrollSizeGrip          = 0x0008,
3943                         ScrollSizeGripRight     = 0x0010,
3944
3945                         Inactive                = 0x0100,
3946                         Pushed                  = 0x0200,
3947                         Checked                 = 0x0400,
3948                         Transparent             = 0x0800,
3949                         Hot                     = 0x1000,
3950                         AdjustRect              = 0x2000,
3951                         Flat                    = 0x4000,
3952                         Mono                    = 0x8000
3953
3954                 }
3955
3956                 private enum DrawFrameControlTypes {
3957                         Caption = 1,
3958                         Menu    = 2,
3959                         Scroll  = 3,
3960                         Button  = 4
3961                 }
3962
3963                 public override void CPDrawBorder (Graphics graphics, Rectangle bounds, Color leftColor, int leftWidth,
3964                         ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
3965                         Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
3966                         int bottomWidth, ButtonBorderStyle bottomStyle) {
3967                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom-1, leftWidth, leftColor, leftStyle, Border3DSide.Left);
3968                         DrawBorderInternal(graphics, bounds.Left, bounds.Top, bounds.Right-1, bounds.Top, topWidth, topColor, topStyle, Border3DSide.Top);
3969                         DrawBorderInternal(graphics, bounds.Right-1, bounds.Top, bounds.Right-1, bounds.Bottom-1, rightWidth, rightColor, rightStyle, Border3DSide.Right);
3970                         DrawBorderInternal(graphics, bounds.Left, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1, bottomWidth, bottomColor, bottomStyle, Border3DSide.Bottom);
3971                 }
3972
3973                 public override void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides) {
3974                         CPDrawBorder3D(graphics, rectangle, style, sides, ColorButtonFace);
3975                 }
3976
3977                 private void CPDrawBorder3D (Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color) {
3978                         Pen             penTopLeft;
3979                         Pen             penTopLeftInner;
3980                         Pen             penBottomRight;
3981                         Pen             penBottomRightInner;
3982                         Rectangle       rect= new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
3983                         bool            doInner = false;
3984
3985                         if ((style & Border3DStyle.Adjust)!=0) {
3986                                 rect.Y-=2;
3987                                 rect.X-=2;
3988                                 rect.Width+=4;
3989                                 rect.Height+=4;
3990                         }
3991
3992                         /* default to flat */
3993                         penTopLeft=ResPool.GetPen(ControlPaint.Dark(control_color));
3994                         penTopLeftInner=ResPool.GetPen(ControlPaint.Dark(control_color));
3995                         penBottomRight=ResPool.GetPen(ControlPaint.Dark(control_color));
3996                         penBottomRightInner=ResPool.GetPen(ControlPaint.Dark(control_color));
3997
3998                         if ((style & Border3DStyle.RaisedOuter)!=0) {
3999                                 penTopLeft=ResPool.GetPen(ControlPaint.LightLight(control_color));
4000                                 penBottomRight=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4001                                 if ((style & (Border3DStyle.RaisedInner | Border3DStyle.SunkenInner))!=0) {
4002                                         doInner=true;
4003                                 }
4004                         } else if ((style & Border3DStyle.SunkenOuter)!=0) {
4005                                 penTopLeft=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4006                                 penBottomRight=ResPool.GetPen(ControlPaint.LightLight(control_color));
4007                                 if ((style & (Border3DStyle.RaisedInner | Border3DStyle.SunkenInner))!=0) {
4008                                         doInner=true;
4009                                 }
4010                         }
4011
4012                         if ((style & Border3DStyle.RaisedInner)!=0) {
4013                                 if (doInner) {
4014                                         penTopLeftInner=ResPool.GetPen(control_color);
4015                                         penBottomRightInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4016                                 } else {
4017                                         penTopLeft=ResPool.GetPen(ControlPaint.LightLight(control_color));
4018                                         penBottomRight=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4019                                 }
4020                         } else if ((style & Border3DStyle.SunkenInner)!=0) {
4021                                 if (doInner) {
4022                                         penTopLeftInner=ResPool.GetPen(ControlPaint.Dark(control_color));
4023                                         penBottomRightInner=ResPool.GetPen(control_color);
4024                                 } else {
4025                                         penTopLeft=ResPool.GetPen(ControlPaint.DarkDark(control_color));
4026                                         penBottomRight=ResPool.GetPen(ControlPaint.LightLight(control_color));
4027                                 }
4028                         }
4029
4030                         if ((sides & Border3DSide.Middle)!=0) {
4031                                 graphics.FillRectangle(ResPool.GetSolidBrush(control_color), rect);
4032                         }
4033
4034                         if ((sides & Border3DSide.Left)!=0) {
4035                                 graphics.DrawLine(penTopLeft, rect.Left, rect.Bottom-2, rect.Left, rect.Top);
4036                                 if (doInner) {
4037                                         graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Bottom-2, rect.Left+1, rect.Top);
4038                                 }
4039                         }
4040
4041                         if ((sides & Border3DSide.Top)!=0) {
4042                                 graphics.DrawLine(penTopLeft, rect.Left, rect.Top, rect.Right-2, rect.Top);
4043
4044                                 if (doInner) {
4045                                         if ((sides & Border3DSide.Left)!=0) {
4046                                                 graphics.DrawLine(penTopLeftInner, rect.Left+1, rect.Top+1, rect.Right-3, rect.Top+1);
4047                                         } else {
4048                                                 graphics.DrawLine(penTopLeftInner, rect.Left, rect.Top+1, rect.Right-3, rect.Top+1);
4049                                         }
4050                                 }
4051                         }
4052
4053                         if ((sides & Border3DSide.Right)!=0) {
4054                                 graphics.DrawLine(penBottomRight, rect.Right-1, rect.Top, rect.Right-1, rect.Bottom-1);
4055
4056                                 if (doInner) {
4057                                         if ((sides & Border3DSide.Top)!=0) {
4058                                                 graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top+1, rect.Right-2, rect.Bottom-2);
4059                                         } else {
4060                                                 graphics.DrawLine(penBottomRightInner, rect.Right-2, rect.Top, rect.Right-2, rect.Bottom-2);
4061                                         }
4062                                 }
4063                         }
4064
4065                         if ((sides & Border3DSide.Bottom)!=0) {
4066                                 int     left=rect.Left;
4067
4068                                 if ((sides & Border3DSide.Left)!=0) {
4069                                         left+=1;
4070                                 }
4071
4072                                 graphics.DrawLine(penBottomRight, rect.Left, rect.Bottom-1, rect.Right-1, rect.Bottom-1);
4073
4074                                 if (doInner) {
4075                                         if ((sides & Border3DSide.Right)!=0) {
4076                                                 graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-2, rect.Bottom-2);
4077                                         } else {
4078                                                 graphics.DrawLine(penBottomRightInner, left, rect.Bottom-2, rect.Right-2, rect.Bottom-2);
4079                                         }
4080                                 }
4081                         }
4082
4083                 }
4084
4085
4086                 public override void CPDrawButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4087                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonPush;
4088
4089                         if ((state & ButtonState.Pushed)!=0) {
4090                                 dfcs |= DrawFrameControlStates.Pushed;
4091                         }
4092
4093                         if ((state & ButtonState.Checked)!=0) {
4094                                 dfcs |= DrawFrameControlStates.Checked;
4095                         }
4096
4097                         if ((state & ButtonState.Flat)!=0) {
4098                                 dfcs |= DrawFrameControlStates.Flat;
4099                         }
4100
4101                         if ((state & ButtonState.Inactive)!=0) {
4102                                 dfcs |= DrawFrameControlStates.Inactive;
4103                         }
4104                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4105                 }
4106
4107
4108                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state) {
4109                         Rectangle       captionRect;
4110                         int                     lineWidth;
4111
4112                         CPDrawButton(graphics, rectangle, state);
4113
4114                         if (rectangle.Width<rectangle.Height) {
4115                                 captionRect=new Rectangle(rectangle.X+1, rectangle.Y+rectangle.Height/2-rectangle.Width/2+1, rectangle.Width-4, rectangle.Width-4);
4116                         } else {
4117                                 captionRect=new Rectangle(rectangle.X+rectangle.Width/2-rectangle.Height/2+1, rectangle.Y+1, rectangle.Height-4, rectangle.Height-4);
4118                         }
4119
4120                         if ((state & ButtonState.Pushed)!=0) {
4121                                 captionRect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-3, rectangle.Height-3);
4122                         }
4123
4124                         /* Make sure we've got at least a line width of 1 */
4125                         lineWidth=Math.Max(1, captionRect.Width/7);
4126
4127                         switch(button) {
4128                         case CaptionButton.Close: {
4129                                 Pen     pen;
4130
4131                                 if ((state & ButtonState.Inactive)!=0) {
4132                                         pen=new Pen(ColorButtonHilight, lineWidth);
4133                                         DrawCaptionHelper(graphics, ColorButtonHilight, pen, lineWidth, 1, captionRect, button);
4134                                         pen.Dispose();
4135
4136                                         pen=new Pen(ColorButtonShadow, lineWidth);
4137                                         DrawCaptionHelper(graphics, ColorButtonShadow, pen, lineWidth, 0, captionRect, button);
4138                                         pen.Dispose();
4139                                         return;
4140                                 } else {
4141                                         pen=new Pen(ColorButtonText, lineWidth);
4142                                         DrawCaptionHelper(graphics, ColorButtonText, pen, lineWidth, 0, captionRect, button);
4143                                         pen.Dispose();
4144                                         return;
4145                                 }
4146                         }
4147
4148                         case CaptionButton.Help:
4149                         case CaptionButton.Maximize:
4150                         case CaptionButton.Minimize:
4151                         case CaptionButton.Restore: {
4152                                 if ((state & ButtonState.Inactive)!=0) {
4153                                         DrawCaptionHelper(graphics, ColorButtonHilight, SystemPens.ControlLightLight, lineWidth, 1, captionRect, button);
4154
4155                                         DrawCaptionHelper(graphics, ColorButtonShadow, SystemPens.ControlDark, lineWidth, 0, captionRect, button);
4156                                         return;
4157                                 } else {
4158                                         DrawCaptionHelper(graphics, ColorButtonText, SystemPens.ControlText, lineWidth, 0, captionRect, button);
4159                                         return;
4160                                 }
4161                         }
4162                         }
4163                 }
4164
4165
4166                 public override void CPDrawCheckBox (Graphics graphics, Rectangle rectangle, ButtonState state) {
4167                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonCheck;
4168
4169                         if ((state & ButtonState.Pushed)!=0) {
4170                                 dfcs |= DrawFrameControlStates.Pushed;
4171                         }
4172
4173                         if ((state & ButtonState.Checked)!=0) {
4174                                 dfcs |= DrawFrameControlStates.Checked;
4175                         }
4176
4177                         if ((state & ButtonState.Flat)!=0) {
4178                                 dfcs |= DrawFrameControlStates.Flat;
4179                         }
4180
4181                         if ((state & ButtonState.Inactive)!=0) {
4182                                 dfcs |= DrawFrameControlStates.Inactive;
4183                         }
4184
4185                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4186
4187                 }
4188
4189                 public override void CPDrawComboButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4190                         Point[]                 arrow = new Point[3];
4191                         Point                           P1;
4192                         Point                           P2;
4193                         Point                           P3;
4194                         int                             centerX;
4195                         int                             centerY;
4196                         int                             shiftX;
4197                         int                             shiftY;
4198                         Rectangle               rect;
4199
4200                         if ((state & ButtonState.Checked)!=0) {
4201                                 graphics.FillRectangle(ResPool.GetHatchBrush (HatchStyle.Percent50, ColorButtonLight, ColorButtonHilight),rectangle);                           
4202                         }
4203
4204                         if ((state & ButtonState.Flat)!=0) {
4205                                 ControlPaint.DrawBorder(graphics, rectangle, ColorButtonShadow, ButtonBorderStyle.Solid);
4206                         } else {
4207                                 if ((state & (ButtonState.Pushed | ButtonState.Checked))!=0) {
4208                                         // this needs to render like a pushed button - jba
4209                                         // CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
4210                                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4211                                         graphics.DrawRectangle (ResPool.GetPen (ControlPaint.Dark (ColorButtonFace)), trace_rectangle);
4212                                 } else {
4213                                         CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
4214                                 }
4215                         }
4216
4217                         rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
4218                         centerX=rect.Left+rect.Width/2;
4219                         centerY=rect.Top+rect.Height/2;
4220                         shiftX=Math.Max(1, rect.Width/8);
4221                         shiftY=Math.Max(1, rect.Height/8);
4222
4223                         if ((state & ButtonState.Pushed)!=0) {
4224                                 shiftX++;
4225                                 shiftY++;
4226                         }
4227
4228                         rect.Y-=shiftY;
4229                         centerY-=shiftY;
4230                         P1=new Point(rect.Left, centerY);
4231                         P2=new Point(rect.Right, centerY);
4232                         P3=new Point(centerX, rect.Bottom);
4233
4234                         arrow[0]=P1;
4235                         arrow[1]=P2;
4236                         arrow[2]=P3;
4237
4238                         /* Draw the arrow */
4239                         if ((state & ButtonState.Inactive)!=0) {
4240                                 graphics.FillPolygon(SystemBrushes.ControlLightLight, arrow, FillMode.Winding);
4241
4242                                 /* Move away from the shadow */
4243                                 P1.X-=1;                P1.Y-=1;
4244                                 P2.X-=1;                P2.Y-=1;
4245                                 P3.X-=1;                P3.Y-=1;
4246
4247                                 arrow[0]=P1;
4248                                 arrow[1]=P2;
4249                                 arrow[2]=P3;
4250
4251
4252                                 graphics.FillPolygon(SystemBrushes.ControlDark, arrow, FillMode.Winding);
4253                         } else {
4254                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
4255                         }
4256                 }
4257
4258
4259                 public override void CPDrawContainerGrabHandle (Graphics graphics, Rectangle bounds) {
4260                         
4261                         Pen                     pen     = new Pen(Color.Black, 1);
4262                         Rectangle       rect    = new Rectangle(bounds.X, bounds.Y, bounds.Width-1, bounds.Height-1);   // Dunno why, but MS does it that way, too
4263                         int                     X;
4264                         int                     Y;
4265
4266                         graphics.FillRectangle(ResPool.GetSolidBrush (ColorButtonText), rect);
4267                         graphics.DrawRectangle(pen, rect);
4268
4269                         X=rect.X+rect.Width/2;
4270                         Y=rect.Y+rect.Height/2;
4271
4272                         /* Draw the cross */
4273                         graphics.DrawLine(pen, X, rect.Y+2, X, rect.Bottom-2);
4274                         graphics.DrawLine(pen, rect.X+2, Y, rect.Right-2, Y);
4275
4276                         /* Draw 'arrows' for vertical lines */
4277                         graphics.DrawLine(pen, X-1, rect.Y+3, X+1, rect.Y+3);
4278                         graphics.DrawLine(pen, X-1, rect.Bottom-3, X+1, rect.Bottom-3);
4279
4280                         /* Draw 'arrows' for horizontal lines */
4281                         graphics.DrawLine(pen, rect.X+3, Y-1, rect.X+3, Y+1);
4282                         graphics.DrawLine(pen, rect.Right-3, Y-1, rect.Right-3, Y+1);
4283
4284                 }
4285
4286                 public virtual void DrawFlatStyleFocusRectangle (Graphics graphics, Rectangle rectangle, ButtonBase button, Color foreColor, Color backColor) {
4287                         // make a rectange to trace around border of the button
4288                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4289                         
4290                         Color outerColor = foreColor;
4291                         // adjust focus color according to the flatstyle
4292                         if (button.FlatStyle == FlatStyle.Popup && !button.is_pressed) {
4293                                 outerColor = (backColor == ColorButtonFace) ? ControlPaint.Dark(ColorButtonFace) : ColorButtonText;                             
4294                         }
4295                         
4296                         // draw the outer rectangle
4297                         graphics.DrawRectangle (ResPool.GetPen (outerColor), trace_rectangle);                  
4298                         
4299                         // draw the inner rectangle                                             
4300                         if (button.FlatStyle == FlatStyle.Popup) {
4301                                 DrawInnerFocusRectangle (graphics, Rectangle.Inflate (rectangle, -4, -4), backColor);
4302                         } else {
4303                                 // draw a flat inner rectangle
4304                                 Pen pen = ResPool.GetPen (ControlPaint.LightLight (backColor));
4305                                 graphics.DrawRectangle(pen, Rectangle.Inflate (trace_rectangle, -4, -4));                               
4306                         }
4307                 }
4308                 
4309                 public virtual void DrawInnerFocusRectangle(Graphics graphics, Rectangle rectangle, Color backColor)
4310                 {       
4311                         // make a rectange to trace around border of the button
4312                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
4313                         
4314                         Color colorBackInverted = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
4315                         DashStyle oldStyle; // used for caching old penstyle
4316                         Pen pen = ResPool.GetPen (colorBackInverted);
4317                         
4318                         oldStyle = pen.DashStyle; 
4319                         pen.DashStyle = DashStyle.Dot;
4320                         graphics.DrawRectangle (pen, trace_rectangle);
4321                         pen.DashStyle = oldStyle;
4322                 }
4323                                 
4324
4325                 public override void CPDrawFocusRectangle (Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) 
4326                 {                       
4327                         Rectangle rect = rectangle;
4328                         Pen pen;
4329                         HatchBrush brush;
4330                                 
4331                         if (backColor.GetBrightness () >= 0.5) {
4332                                 foreColor = Color.Transparent;
4333                                 backColor = Color.Black;
4334                                 
4335                         } else {
4336                                 backColor = Color.FromArgb (Math.Abs (backColor.R-255), Math.Abs (backColor.G-255), Math.Abs (backColor.B-255));
4337                                 foreColor = Color.Black;
4338                         }
4339                                                 
4340                         brush = ResPool.GetHatchBrush (HatchStyle.Percent50, backColor, foreColor);
4341                         pen = new Pen (brush, 1);
4342                                                 
4343                         rect.Width--;
4344                         rect.Height--;                  
4345                         
4346                         graphics.DrawRectangle (pen, rect);
4347                         pen.Dispose ();
4348                 }
4349                 
4350                 public override void CPDrawGrabHandle (Graphics graphics, Rectangle rectangle, bool primary, bool enabled) {
4351                         SolidBrush      sb;
4352                         Pen                     pen;
4353
4354                         if (primary==true) {
4355                                 pen=new Pen(Color.Black, 1);
4356                                 if (enabled==true) {
4357                                         sb=ResPool.GetSolidBrush (ColorButtonText);
4358                                 } else {
4359                                         sb=ResPool.GetSolidBrush (ColorButtonFace);
4360                                 }
4361                         } else {
4362                                 pen=new Pen(Color.White, 1);
4363                                 if (enabled==true) {
4364                                         sb=ThemeEngine.Current.ResPool.GetSolidBrush (Color.Black);
4365                                 } else {
4366                                         sb=ResPool.GetSolidBrush (ColorButtonFace);
4367                                 }
4368                         }
4369                         graphics.FillRectangle(sb, rectangle);
4370                         graphics.DrawRectangle(pen, rectangle);                 
4371                         pen.Dispose();
4372                 }
4373
4374
4375                 public override void CPDrawGrid (Graphics graphics, Rectangle area, Size pixelsBetweenDots, Color backColor) {
4376                         Color   foreColor;
4377                         int     h;
4378                         int     b;
4379                         int     s;
4380
4381                         ControlPaint.Color2HBS(backColor, out h, out b, out s);
4382
4383                         if (b>127) {
4384                                 foreColor=Color.Black;
4385                         } else {
4386                                 foreColor=Color.White;
4387                         }
4388
4389 #if false
4390                         /* Commented out until I take the time and figure out
4391                                 which HatchStyle will match requirements. The code below
4392                                 is only correct for Percent50.
4393                         */
4394                         if (pixelsBetweenDots.Width==pixelsBetweenDots.Height) {
4395                                 HatchBrush      brush=null;
4396
4397                                 switch(pixelsBetweenDots.Width) {
4398                                         case 2: brush=new HatchBrush(HatchStyle.Percent50, foreColor, backColor); break;
4399                                         case 4: brush=new HatchBrush(HatchStyle.Percent25, foreColor, backColor); break;
4400                                         case 5: brush=new HatchBrush(HatchStyle.Percent20, foreColor, backColor); break;
4401                                         default: {
4402                                                 /* Have to do it the slow way */
4403                                                 break;
4404                                         }
4405                                 }
4406                                 if (brush!=null) {
4407                                         graphics.FillRectangle(brush, area);
4408                                         pen.Dispose();
4409                                         brush.Dispose();
4410                                         return;
4411                                 }
4412                         }
4413 #endif
4414                         /* Slow method */
4415
4416                         Bitmap bitmap = new Bitmap(area.Width, area.Height, graphics);
4417
4418                         for (int x=0; x<area.Width; x+=pixelsBetweenDots.Width) {
4419                                 for (int y=0; y<area.Height; y+=pixelsBetweenDots.Height) {
4420                                         bitmap.SetPixel(x, y, foreColor);
4421                                 }
4422                         }
4423                         graphics.DrawImage(bitmap, area.X, area.Y, area.Width, area.Height);
4424                         bitmap.Dispose();
4425                 }
4426
4427                 public override void CPDrawImageDisabled (Graphics graphics, Image image, int x, int y, Color background) {
4428                         /*
4429                                 Microsoft seems to ignore the background and simply make
4430                                 the image grayscale. At least when having > 256 colors on
4431                                 the display.
4432                         */
4433                         
4434                         if (imagedisabled_attributes == null) {                         
4435                                 imagedisabled_attributes = new ImageAttributes ();
4436                                 ColorMatrix colorMatrix=new ColorMatrix(new float[][] {
4437                                           // This table would create a perfect grayscale image, based on luminance
4438                                           //                            new float[]{0.3f,0.3f,0.3f,0,0},
4439                                           //                            new float[]{0.59f,0.59f,0.59f,0,0},
4440                                           //                            new float[]{0.11f,0.11f,0.11f,0,0},
4441                                           //                            new float[]{0,0,0,1,0,0},
4442                                           //                            new float[]{0,0,0,0,1,0},
4443                                           //                            new float[]{0,0,0,0,0,1}
4444                 
4445                                           // This table generates a image that is grayscaled and then
4446                                           // brightened up. Seems to match MS close enough.
4447                                           new float[]{0.2f,0.2f,0.2f,0,0},
4448                                           new float[]{0.41f,0.41f,0.41f,0,0},
4449                                           new float[]{0.11f,0.11f,0.11f,0,0},
4450                                           new float[]{0.15f,0.15f,0.15f,1,0,0},
4451                                           new float[]{0.15f,0.15f,0.15f,0,1,0},
4452                                           new float[]{0.15f,0.15f,0.15f,0,0,1}
4453                                   });
4454                                   
4455                                  imagedisabled_attributes.SetColorMatrix (colorMatrix);
4456                         }
4457                         
4458                         graphics.DrawImage(image, new Rectangle(x, y, image.Width, image.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imagedisabled_attributes);
4459                         
4460                 }
4461
4462
4463                 public override void CPDrawLockedFrame (Graphics graphics, Rectangle rectangle, bool primary) {
4464                         Pen     penBorder;
4465                         Pen     penInside;
4466
4467                         if (primary) {
4468                                 penBorder=new Pen(Color.White, 2);
4469                                 penInside=new Pen(Color.Black, 1);
4470                         } else {
4471                                 penBorder=new Pen(Color.Black, 2);
4472                                 penInside=new Pen(Color.White, 1);
4473                         }
4474                         penBorder.Alignment=PenAlignment.Inset;
4475                         penInside.Alignment=PenAlignment.Inset;
4476
4477                         graphics.DrawRectangle(penBorder, rectangle);
4478                         graphics.DrawRectangle(penInside, rectangle.X+2, rectangle.Y+2, rectangle.Width-5, rectangle.Height-5);
4479                         penBorder.Dispose();
4480                         penInside.Dispose();
4481                 }
4482
4483
4484                 public override void CPDrawMenuGlyph (Graphics graphics, Rectangle rectangle, MenuGlyph glyph) {
4485                         Rectangle       rect;
4486                         int                     lineWidth;
4487
4488                         // MS draws always the background white
4489                         graphics.FillRectangle(ResPool.GetSolidBrush (Color.White), rectangle);
4490
4491                         switch(glyph) {
4492                         case MenuGlyph.Arrow: {
4493                                 Point[]                 arrow = new Point[3];
4494                                 Point                           P1;
4495                                 Point                           P2;
4496                                 Point                           P3;
4497                                 int                             centerX;
4498                                 int                             centerY;
4499                                 int                             shiftX;
4500
4501                                 rect=new Rectangle(rectangle.X+rectangle.Width/4, rectangle.Y+rectangle.Height/4, rectangle.Width/2, rectangle.Height/2);
4502                                 centerX=rect.Left+rect.Width/2;
4503                                 centerY=rect.Top+rect.Height/2;
4504                                 shiftX=Math.Max(1, rect.Width/8);
4505
4506                                 rect.X-=shiftX;
4507                                 centerX-=shiftX;
4508
4509                                 P1=new Point(centerX, rect.Top-1);
4510                                 P2=new Point(centerX, rect.Bottom);
4511                                 P3=new Point(rect.Right, centerY);
4512
4513                                 arrow[0]=P1;
4514                                 arrow[1]=P2;
4515                                 arrow[2]=P3;
4516
4517                                 graphics.FillPolygon(SystemBrushes.ControlText, arrow, FillMode.Winding);
4518
4519                                 return;
4520                         }
4521
4522                         case MenuGlyph.Bullet: {
4523                                 
4524                                 lineWidth=Math.Max(2, rectangle.Width/3);
4525                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
4526                                 
4527                                 graphics.FillEllipse(ResPool.GetSolidBrush (ColorButtonText), rect);
4528                                 
4529                                 return;
4530                         }
4531
4532                         case MenuGlyph.Checkmark: {
4533                                 int                     Scale;
4534
4535                                 lineWidth=Math.Max(2, rectangle.Width/6);
4536                                 Scale=Math.Max(1, rectangle.Width/12);
4537
4538                                 rect=new Rectangle(rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2);
4539
4540                                 for (int i=0; i<lineWidth; i++) {
4541                                         graphics.DrawLine(SystemPens.MenuText, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
4542                                         graphics.DrawLine(SystemPens.MenuText, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i, rect.Left+lineWidth/2+6*Scale, rect.Top+lineWidth-2*Scale+i);
4543                                 }
4544                                 return;
4545                         }
4546                         }
4547
4548                 }
4549
4550                 public override void CPDrawRadioButton (Graphics graphics, Rectangle rectangle, ButtonState state) {
4551                         DrawFrameControlStates  dfcs=DrawFrameControlStates.ButtonRadio;
4552
4553                         if ((state & ButtonState.Pushed)!=0) {
4554                                 dfcs |= DrawFrameControlStates.Pushed;
4555                         }
4556
4557                         if ((state & ButtonState.Checked)!=0) {
4558                                 dfcs |= DrawFrameControlStates.Checked;
4559                         }
4560
4561                         if ((state & ButtonState.Flat)!=0) {
4562                                 dfcs |= DrawFrameControlStates.Flat;
4563                         }
4564
4565                         if ((state & ButtonState.Inactive)!=0) {
4566                                 dfcs |= DrawFrameControlStates.Inactive;
4567                         }
4568                         DrawFrameControl(graphics, rectangle, DrawFrameControlTypes.Button, dfcs);
4569
4570                 }
4571
4572
4573                 public override void CPDrawReversibleFrame (Rectangle rectangle, Color backColor, FrameStyle style) {
4574
4575                 }
4576
4577
4578                 public override void CPDrawReversibleLine (Point start, Point end, Color backColor) {
4579
4580                 }
4581
4582
4583                 /* Scroll button: regular button + direction arrow */
4584                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state) {
4585                         bool enabled = (state == ButtonState.Inactive) ? false: true;                   
4586                                         
4587                         DrawScrollButtonPrimitive (dc, area, state);
4588                                                 
4589                         if (area.Width < 12 || area.Height < 12) /* Cannot see a thing at smaller sizes */
4590                                 return;
4591
4592                         /* Paint arrows */
4593                         switch (type) {
4594                         case ScrollButton.Up: {
4595                                 int x = area.X +  (area.Width / 2) - 4;
4596                                 int y = area.Y + 9;
4597
4598                                 for (int i = 0; i < 3; i++)
4599                                         if (enabled)
4600                                                 dc.DrawLine (ResPool.GetPen (arrow_color), x + i, y - i, x + i + 6 - 2*i, y - i);
4601                                         else
4602                                                 dc.DrawLine (ResPool.GetPen (ColorGrayText), x + i, y - i, x + i + 6 - 2*i, y - i);
4603
4604                                 
4605                                 dc.FillRectangle (enabled ? ResPool.GetSolidBrush (arrow_color) :  ResPool.GetSolidBrush (ColorGrayText),
4606                                         x + 3, area.Y + 6, 1, 1);
4607                                         
4608                                 break;
4609                         }
4610                         case ScrollButton.Down: {
4611                                 int x = area.X +  (area.Width / 2) - 5;
4612                                 int y = area.Y + 5;
4613
4614                                 for (int i = 4; i != 0; i--)
4615                                         if (enabled)
4616                                                 dc.DrawLine (ResPool.GetPen (arrow_color), x + i, y + i, x + i + 8 - 2*i, y + i);
4617                                         else
4618                                                 dc.DrawLine (ResPool.GetPen (ColorGrayText), x + i, y + i, x + i + 8 - 2*i, y + i);
4619
4620                                 
4621                                 dc.FillRectangle (enabled ? ResPool.GetSolidBrush (arrow_color) :  ResPool.GetSolidBrush (ColorGrayText),
4622                                         x + 4, y + 4, 1, 1);
4623                                 break;
4624                         }
4625
4626                         case ScrollButton.Left: {
4627                                 int y = area.Y +  (area.Height / 2) - 4;
4628                                 int x = area.X + 9;
4629
4630                                 for (int i = 0; i < 3; i++)
4631                                         if (enabled)
4632                                                 dc.DrawLine (ResPool.GetPen (arrow_color), x - i, y + i, x - i, y + i + 6 - 2*i);
4633                                         else
4634                                                 dc.DrawLine (ResPool.GetPen (ColorGrayText), x - i, y + i, x - i, y + i + 6 - 2*i);
4635
4636                                 dc.FillRectangle (enabled ? ResPool.GetSolidBrush (arrow_color) :  ResPool.GetSolidBrush (ColorGrayText),
4637                                         x - 3, y + 3, 1, 1);
4638                                 break;
4639                         }
4640
4641                         case ScrollButton.Right: {
4642                                 int y = area.Y +  (area.Height / 2) - 5;
4643                                 int x = area.X + 5;
4644
4645                                 for (int i = 4; i != 0; i--)
4646                                         if (enabled)
4647                                                 dc.DrawLine (ResPool.GetPen (arrow_color), x + i, y + i, x + i, y + i + 8 - 2*i);
4648                                         else
4649                                                 dc.DrawLine (ResPool.GetPen (ColorGrayText), x + i, y + i, x + i, y + i + 8 - 2*i);
4650
4651                                 dc.FillRectangle (enabled ? ResPool.GetSolidBrush (arrow_color) :  ResPool.GetSolidBrush (ColorGrayText),
4652                                         x + 4, y + 4, 1, 1);
4653                                 break;
4654                         }
4655
4656                         default:
4657                                 break;
4658
4659                         }
4660                 }
4661
4662
4663                 public  override void CPDrawSelectionFrame (Graphics graphics, bool active, Rectangle outsideRect, Rectangle insideRect,
4664                         Color backColor) {
4665
4666                 }
4667
4668
4669                 public override void CPDrawSizeGrip (Graphics dc, Color backColor, Rectangle bounds) {
4670                         Point pt = new Point (bounds.Right - 2, bounds.Bottom - 1);
4671
4672                         dc.DrawLine (ResPool.GetPen (ColorButtonFace), pt.X - 12, pt.Y, pt.X, pt.Y);
4673                         dc.DrawLine (ResPool.GetPen (ColorButtonFace), pt.X, pt.Y, pt.X, pt.Y - 13);
4674
4675                         // diagonals
4676                         for (int i = 0; i < 11; i += 4) {
4677                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), pt.X - i, pt.Y, pt.X + 1, pt.Y - i - 2);
4678                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), pt.X - i - 1, pt.Y, pt.X + 1, pt.Y - i - 2);
4679                         }
4680
4681                         for (int i = 3; i < 13; i += 4)
4682                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), pt.X - i, pt.Y, pt.X + 1, pt.Y - i - 1);
4683                 }
4684
4685
4686                 public  override void CPDrawStringDisabled (Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle,
4687                         StringFormat format) {                  
4688
4689                         layoutRectangle.Offset(1.0f, 1.0f);
4690                         graphics.DrawString(s, font, ResPool.GetSolidBrush (ControlPaint.Light(color, 95)), layoutRectangle, format);                   
4691                         layoutRectangle.Offset(-1.0f, -1.0f);
4692                         graphics.DrawString(s, font, ResPool.GetSolidBrush (ControlPaint.Light(color, 50)), layoutRectangle, format);
4693                         
4694                 }
4695
4696                 private static void DrawBorderInternal(Graphics graphics, int startX, int startY, int endX, int endY,
4697                         int width, Color color, ButtonBorderStyle style, Border3DSide side) {
4698
4699                         Pen     pen=new Pen(color, 1);
4700
4701                         switch(style) {
4702                         case ButtonBorderStyle.Solid: {
4703                                 pen.DashStyle=DashStyle.Solid;
4704                                 break;
4705                         }
4706
4707                         case ButtonBorderStyle.Dashed: {
4708                                 pen.DashStyle=DashStyle.Dash;
4709                                 break;
4710                         }
4711
4712                         case ButtonBorderStyle.Dotted: {
4713                                 pen.DashStyle=DashStyle.Dot;
4714                                 break;
4715                         }
4716
4717                         case ButtonBorderStyle.Inset: {
4718                                 pen.DashStyle=DashStyle.Solid;
4719                                 break;
4720                         }
4721
4722                         case ButtonBorderStyle.Outset: {
4723                                 pen.DashStyle=DashStyle.Solid;
4724                                 break;
4725                         }
4726
4727                         default:
4728                         case ButtonBorderStyle.None: {
4729                                 pen.Dispose();
4730                                 return;
4731                         }
4732                         }
4733
4734
4735                         switch(style) {
4736                         case ButtonBorderStyle.Outset: {
4737                                 Color           colorGrade;
4738                                 int             hue, brightness, saturation;
4739                                 int             brightnessSteps;
4740                                 int             brightnessDownSteps;
4741
4742                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
4743
4744                                 brightnessDownSteps=brightness/width;
4745                                 if (brightness>127) {
4746                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
4747                                 } else {
4748                                         brightnessSteps=(127-brightness)/width;
4749                                 }
4750
4751                                 for (int i=0; i<width; i++) {
4752                                         switch(side) {
4753                                         case Border3DSide.Left: {
4754                                                 pen.Dispose();
4755                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
4756                                                 pen=new Pen(colorGrade, 1);
4757                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
4758                                                 break;
4759                                         }
4760
4761                                         case Border3DSide.Right: {
4762                                                 pen.Dispose();
4763                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
4764                                                 pen=new Pen(colorGrade, 1);
4765                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
4766                                                 break;
4767                                         }
4768
4769                                         case Border3DSide.Top: {
4770                                                 pen.Dispose();
4771                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
4772                                                 pen=new Pen(colorGrade, 1);
4773                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
4774                                                 break;
4775                                         }
4776
4777                                         case Border3DSide.Bottom: {
4778                                                 pen.Dispose();
4779                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
4780                                                 pen=new Pen(colorGrade, 1);
4781                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
4782                                                 break;
4783                                         }
4784                                         }
4785                                 }
4786                                 break;
4787                         }
4788
4789                         case ButtonBorderStyle.Inset: {
4790                                 Color           colorGrade;
4791                                 int             hue, brightness, saturation;
4792                                 int             brightnessSteps;
4793                                 int             brightnessDownSteps;
4794
4795                                 ControlPaint.Color2HBS(color, out hue, out brightness, out saturation);
4796
4797                                 brightnessDownSteps=brightness/width;
4798                                 if (brightness>127) {
4799                                         brightnessSteps=Math.Max(6, (160-brightness)/width);
4800                                 } else {
4801                                         brightnessSteps=(127-brightness)/width;
4802                                 }
4803
4804                                 for (int i=0; i<width; i++) {
4805                                         switch(side) {
4806                                         case Border3DSide.Left: {
4807                                                 pen.Dispose();
4808                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
4809                                                 pen=new Pen(colorGrade, 1);
4810                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
4811                                                 break;
4812                                         }
4813
4814                                         case Border3DSide.Right: {
4815                                                 pen.Dispose();
4816                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
4817                                                 pen=new Pen(colorGrade, 1);
4818                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
4819                                                 break;
4820                                         }
4821
4822                                         case Border3DSide.Top: {
4823                                                 pen.Dispose();
4824                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Max(0, brightness-brightnessDownSteps*(width-i)), saturation);
4825                                                 pen=new Pen(colorGrade, 1);
4826                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
4827                                                 break;
4828                                         }
4829
4830                                         case Border3DSide.Bottom: {
4831                                                 pen.Dispose();
4832                                                 colorGrade=ControlPaint.HBS2Color(hue, Math.Min(255, brightness+brightnessSteps*(width-i)), saturation);
4833                                                 pen=new Pen(colorGrade, 1);
4834                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
4835                                                 break;
4836                                         }
4837                                         }
4838                                 }
4839                                 break;
4840                         }
4841
4842                                 /*
4843                                         I decided to have the for-loop duplicated for speed reasons;
4844                                         that way we only have to switch once (as opposed to have the
4845                                         for-loop around the switch)
4846                                 */
4847                         default: {
4848                                 switch(side) {
4849                                 case Border3DSide.Left: {
4850                                         for (int i=0; i<width; i++) {
4851                                                 graphics.DrawLine(pen, startX+i, startY+i, endX+i, endY-i);
4852                                         }
4853                                         break;
4854                                 }
4855
4856                                 case Border3DSide.Right: {
4857                                         for (int i=0; i<width; i++) {
4858                                                 graphics.DrawLine(pen, startX-i, startY+i, endX-i, endY-i);
4859                                         }
4860                                         break;
4861                                 }
4862
4863                                 case Border3DSide.Top: {
4864                                         for (int i=0; i<width; i++) {
4865                                                 graphics.DrawLine(pen, startX+i, startY+i, endX-i, endY+i);
4866                                         }
4867                                         break;
4868                                 }
4869
4870                                 case Border3DSide.Bottom: {
4871                                         for (int i=0; i<width; i++) {
4872                                                 graphics.DrawLine(pen, startX+i, startY-i, endX-i, endY-i);
4873                                         }
4874                                         break;
4875                                 }
4876                                 }
4877                                 break;
4878                         }
4879                         }
4880                         pen.Dispose();
4881                 }
4882
4883                 /*
4884                         This function actually draws the various caption elements.
4885                         This way we can scale them nicely, no matter what size, and they
4886                         still look like MS's scaled caption buttons. (as opposed to scaling a bitmap)
4887                 */
4888
4889                 private static void DrawCaptionHelper(Graphics graphics, Color color, Pen pen, int lineWidth, int shift, Rectangle captionRect, CaptionButton button) {
4890                         switch(button) {
4891                         case CaptionButton.Close: {
4892                                 pen.StartCap=LineCap.Triangle;
4893                                 pen.EndCap=LineCap.Triangle;
4894                                 if (lineWidth<2) {
4895                                         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);
4896                                         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);
4897                                 }
4898
4899                                 graphics.DrawLine(pen, captionRect.Left+2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Right-2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
4900                                 graphics.DrawLine(pen, captionRect.Right-2*lineWidth+shift, captionRect.Top+2*lineWidth+shift, captionRect.Left+2*lineWidth+shift, captionRect.Bottom-2*lineWidth+shift);
4901                                 return;
4902                         }
4903
4904                         case CaptionButton.Help: {
4905                                 StringFormat    sf = new StringFormat();                                
4906                                 Font                            font = new Font("Microsoft Sans Serif", captionRect.Height, FontStyle.Bold, GraphicsUnit.Pixel);
4907
4908                                 sf.Alignment=StringAlignment.Center;
4909                                 sf.LineAlignment=StringAlignment.Center;
4910
4911
4912                                 graphics.DrawString("?", font, ThemeEngine.Current.ResPool.GetSolidBrush (color), captionRect.X+captionRect.Width/2+shift, captionRect.Y+captionRect.Height/2+shift+lineWidth/2, sf);
4913
4914                                 sf.Dispose();                           
4915                                 font.Dispose();
4916
4917                                 return;
4918                         }
4919
4920                         case CaptionButton.Maximize: {
4921                                 /* Top 'caption bar' line */
4922                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
4923                                         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);
4924                                 }
4925
4926                                 /* Left side line */
4927                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4928                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+2*lineWidth+shift, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
4929                                 }
4930
4931                                 /* Right side line */
4932                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4933                                         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);
4934                                 }
4935
4936                                 /* Bottom line */
4937                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4938                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
4939                                 }
4940                                 return;
4941                         }
4942
4943                         case CaptionButton.Minimize: {
4944                                 /* Bottom line */
4945                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
4946                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth+shift, captionRect.Bottom-lineWidth+shift-i);
4947                                 }
4948                                 return;
4949                         }
4950
4951                         case CaptionButton.Restore: {
4952                                 /** First 'window' **/
4953                                 /* Top 'caption bar' line */
4954                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
4955                                         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);
4956                                 }
4957
4958                                 /* Left side line */
4959                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4960                                         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);
4961                                 }
4962
4963                                 /* Right side line */
4964                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4965                                         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);
4966                                 }
4967
4968                                 /* Bottom line */
4969                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4970                                         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);
4971                                 }
4972
4973                                 /** Second 'window' **/
4974                                 /* Top 'caption bar' line */
4975                                 for (int i=0; i<Math.Max(2, lineWidth); i++) {
4976                                         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);
4977                                 }
4978
4979                                 /* Left side line */
4980                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4981                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift+i, captionRect.Top+4*lineWidth+shift+1, captionRect.Left+lineWidth+shift+i, captionRect.Bottom-lineWidth+shift);
4982                                 }
4983
4984                                 /* Right side line */
4985                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4986                                         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);
4987                                 }
4988
4989                                 /* Bottom line */
4990                                 for (int i=0; i<Math.Max(1, lineWidth/2); i++) {
4991                                         graphics.DrawLine(pen, captionRect.Left+lineWidth+shift, captionRect.Bottom-lineWidth+shift-i, captionRect.Right-3*lineWidth-lineWidth/2+shift, captionRect.Bottom-lineWidth+shift-i);
4992                                 }
4993
4994                                 return;
4995                         }
4996
4997                         }
4998                 }
4999
5000                 [MonoTODO("Finish drawing code for Caption, Menu and Scroll")]
5001                 private void DrawFrameControl(Graphics graphics, Rectangle rectangle, DrawFrameControlTypes Type, DrawFrameControlStates State) {
5002                         // make a rectange to trace around border of the button
5003                         Rectangle trace_rectangle = new Rectangle(rectangle.X, rectangle.Y, Math.Max (rectangle.Width-1, 0), Math.Max (rectangle.Height-1, 0));
5004                         switch(Type) {
5005                         case DrawFrameControlTypes.Button: {
5006
5007                                 if ((State & DrawFrameControlStates.ButtonPush)!=0) {
5008 // JBA 31 oct 2004 - I don't think that button style should be rendered like this
5009 //                                      /* Goes first, affects the background */
5010 //                                      if ((State & DrawFrameControlStates.Checked)!=0) {
5011 //                                              HatchBrush      hatchBrush=new HatchBrush(HatchStyle.Percent50, ColorButtonLight, ColorButtonHilight);
5012 //                                              graphics.FillRectangle(hatchBrush,rectangle);
5013 //                                              hatchBrush.Dispose();
5014 //                                      }
5015
5016                                         if ((State & DrawFrameControlStates.Pushed)!=0 || (State & DrawFrameControlStates.Checked)!=0) {
5017                                                 graphics.DrawRectangle (ResPool.GetPen (ControlPaint.Dark (ColorButtonFace)), trace_rectangle);
5018                                         } else if ((State & DrawFrameControlStates.Flat)!=0) {
5019                                                 ControlPaint.DrawBorder(graphics, rectangle, ColorButtonShadow, ButtonBorderStyle.Solid);
5020                                         } else if ((State & DrawFrameControlStates.Inactive)!=0) {
5021                                                 /* Same as normal, it would seem */
5022                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
5023                                         } else {
5024                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
5025                                         }
5026                                 } else if ((State & DrawFrameControlStates.ButtonRadio)!=0) {
5027                                         Pen                     penFatDark      = new Pen(ColorButtonShadow, 1);
5028                                         Pen                     penFatLight     = new Pen(ColorButtonLight, 1);
5029                                         int                     lineWidth;
5030
5031                                         graphics.FillPie (ResPool.GetSolidBrush (this.ColorWindow), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
5032
5033                                         graphics.DrawArc(penFatDark, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 135, 180);
5034                                         graphics.DrawArc(penFatLight, rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 315, 180);
5035
5036                                         graphics.DrawArc(SystemPens.ControlDark, rectangle, 135, 180);
5037                                         graphics.DrawArc(SystemPens.ControlLightLight, rectangle, 315, 180);
5038
5039                                         lineWidth=Math.Max(1, Math.Min(rectangle.Width, rectangle.Height)/3);
5040
5041                                         if ((State & DrawFrameControlStates.Checked)!=0) {
5042                                                 SolidBrush      buttonBrush;
5043
5044                                                 if ((State & DrawFrameControlStates.Inactive)!=0) {
5045                                                         buttonBrush=(SolidBrush)SystemBrushes.ControlDark;
5046                                                 } else {
5047                                                         buttonBrush=(SolidBrush)SystemBrushes.ControlText;
5048                                                 }
5049                                                 graphics.FillPie(buttonBrush, rectangle.X+lineWidth, rectangle.Y+lineWidth, rectangle.Width-lineWidth*2, rectangle.Height-lineWidth*2, 0, 359);
5050                                         }
5051                                         penFatDark.Dispose();
5052                                         penFatLight.Dispose();
5053                                 } else if ((State & DrawFrameControlStates.ButtonRadioImage)!=0) {
5054                                         throw new NotImplementedException () ;
5055                                 } else if ((State & DrawFrameControlStates.ButtonRadioMask)!=0) {
5056                                         throw new NotImplementedException ();
5057                                 } else {        /* Must be Checkbox */
5058                                         Pen                     pen;
5059                                         int                     lineWidth;
5060                                         Rectangle       rect;
5061                                         int                     Scale;
5062
5063                                         /* Goes first, affects the background */
5064                                         if ((State & DrawFrameControlStates.Pushed)!=0 ||
5065                                                 (State & DrawFrameControlStates.Inactive)!=0) {
5066                                                 graphics.FillRectangle(SystemBrushes.Control, rectangle);
5067                                         } else {
5068                                                 graphics.FillRectangle(SystemBrushes.Window, rectangle);
5069                                         }
5070
5071                                         /* Draw the sunken frame */
5072                                         if ((State & DrawFrameControlStates.Flat)!=0) {
5073                                                 ControlPaint.DrawBorder(graphics, rectangle, ColorButtonShadow, ButtonBorderStyle.Solid);
5074                                         } else {
5075                                                 CPDrawBorder3D(graphics, rectangle, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Top | Border3DSide.Right | Border3DSide.Bottom, ColorButtonFace);
5076                                         }
5077
5078                                         /* Make sure we've got at least a line width of 1 */
5079                                         lineWidth=Math.Max(3, rectangle.Width/6);
5080                                         Scale=Math.Max(1, rectangle.Width/12);
5081
5082                                         // define a rectangle inside the border area
5083                                         rect=new Rectangle(rectangle.X+2, rectangle.Y+2, rectangle.Width-4, rectangle.Height-4);
5084                                         if ((State & DrawFrameControlStates.Inactive)!=0) {
5085                                                 pen=SystemPens.ControlDark;
5086                                         } else {
5087                                                 pen=SystemPens.ControlText;
5088                                         }
5089
5090                                         if ((State & DrawFrameControlStates.Checked)!=0) {
5091                                                 /* Need to draw a check-mark */
5092                                                 for (int i=0; i<lineWidth; i++) {
5093                                                         graphics.DrawLine(pen, rect.Left+lineWidth/2, rect.Top+lineWidth+i, rect.Left+lineWidth/2+2*Scale, rect.Top+lineWidth+2*Scale+i);
5094                                                         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);
5095                                                 }
5096
5097                                         }
5098                                 }
5099                                 return;
5100                         }
5101
5102                         case DrawFrameControlTypes.Caption: {
5103                                 // FIXME:
5104                                 break;
5105                         }
5106
5107                         case DrawFrameControlTypes.Menu: {
5108                                 // FIXME:
5109                                 break;
5110                         }
5111
5112                         case DrawFrameControlTypes.Scroll: {
5113                                 // FIXME:
5114                                 break;
5115                         }
5116                         }
5117                 }
5118
5119                 /* Generic scroll button */
5120                 public void DrawScrollButtonPrimitive (Graphics dc, Rectangle area, ButtonState state) {
5121                         if ((state & ButtonState.Pushed) == ButtonState.Pushed) {
5122                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonFace), area.X + 1,
5123                                         area.Y + 1, area.Width - 2 , area.Height - 2);
5124
5125                                 dc.DrawRectangle (ResPool.GetPen (ColorButtonShadow), area.X,
5126                                         area.Y, area.Width, area.Height);
5127
5128                                 return;
5129                         }                       
5130         
5131                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonFace), area.X, area.Y, area.Width, 1);
5132                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonFace), area.X, area.Y, 1, area.Height);
5133
5134                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonHilight), area.X + 1, area.Y + 1, area.Width - 1, 1);
5135                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonHilight), area.X + 1, area.Y + 2, 1,
5136                                 area.Height - 4);
5137
5138                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonShadow), area.X + 1, area.Y + area.Height - 2,
5139                                 area.Width - 2, 1);
5140
5141                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonDkShadow), area.X, area.Y + area.Height -1,
5142                                 area.Width , 1);
5143
5144                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonShadow), area.X + area.Width - 2,
5145                                 area.Y + 1, 1, area.Height -3);
5146
5147                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonDkShadow), area.X + area.Width -1,
5148                                 area.Y, 1, area.Height - 1);
5149
5150                         dc.FillRectangle (ResPool.GetSolidBrush (ColorButtonFace), area.X + 2,
5151                                 area.Y + 2, area.Width - 4, area.Height - 4);
5152                         
5153                 }
5154                 
5155                 public override void CPDrawBorderStyle (Graphics dc, Rectangle area, BorderStyle border_style) {
5156                         switch (border_style){
5157                         case BorderStyle.Fixed3D:
5158                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), area.X, area.Y, area.X +area.Width, area.Y);
5159                                 dc.DrawLine (ResPool.GetPen (ColorButtonShadow), area.X, area.Y, area.X, area.Y + area.Height);
5160                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), area.X , area.Y + area.Height - 1, area.X + area.Width , 
5161                                         area.Y + area.Height - 1);
5162                                 dc.DrawLine (ResPool.GetPen (ColorButtonHilight), area.X + area.Width -1 , area.Y, area.X + area.Width -1, 
5163                                         area.Y + area.Height);
5164
5165                                 // FIXME: These colors are not correct. Microsoft uses different ones but I didn't find them.
5166                                 dc.DrawLine (ResPool.GetPen (ColorButtonLight), area.X + 1, area.Bottom - 2, area.Right - 2, area.Bottom - 2);
5167                                 dc.DrawLine (ResPool.GetPen (ColorButtonLight), area.Right - 2, area.Top + 1, area.Right - 2, area.Bottom - 2);
5168                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), area.X + 1, area.Top + 1, area.X + 1, area.Bottom - 3);
5169                                 dc.DrawLine (ResPool.GetPen (ColorButtonDkShadow), area.X + 1, area.Top + 1, area.Right - 3, area.Top + 1);
5170                                 break;
5171                         case BorderStyle.FixedSingle:
5172                                 dc.DrawRectangle (ResPool.GetPen (ColorWindowFrame), area.X, area.Y, area.Width - 1, area.Height - 1);
5173                                 break;
5174                         case BorderStyle.None:
5175                         default:
5176                                 break;
5177                         }
5178                         
5179                 }
5180                 #endregion      // ControlPaint
5181
5182
5183         } //class
5184 }