Merge pull request #268 from pcc/menudeactivate
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeClearlooks.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) 2006 Alexander Olk
21 //
22 // Authors:
23 //      Alexander Olk, alex.olk@googlemail.com
24 //
25 //      based on ThemeWin32Classic
26 //
27 //              - You can activate this Theme with export MONO_THEME=clearlooks
28 //
29 // This theme tries to match clearlooks theme
30 //
31 // TODO:        
32 //      - if an other control draws over a ScrollBar button you can see artefacts on the rounded edges 
33 //        (maybe use theme backcolor, but that looks ugly on a white background, need to find a way to get the backcolor of the parent control)
34 //      - more correct drawing of disabled controls
35
36 using System.Drawing;
37 using System.Drawing.Drawing2D;
38 using System.Drawing.Imaging;
39 using System.Drawing.Text;
40
41 namespace System.Windows.Forms {
42         internal class ThemeClearlooks : ThemeWin32Classic {
43                 public override Version Version {
44                         get {
45                                 return new Version( 0, 0, 0, 2 );
46                         }
47                 }
48                 
49                 static readonly Color theme_back_color = Color.FromArgb( 239, 235, 231 );
50                 
51                 static readonly Color gradient_first_color = Color.FromArgb( 250, 248, 247 );
52                 static readonly Color gradient_second_color = Color.FromArgb( 226, 219, 212 );
53                 static readonly Color gradient_second_color_nr2 = Color.FromArgb( 234, 229, 224 );
54                 static readonly Color pressed_gradient_first_color = Color.FromArgb( 217, 207, 202 );
55                 static readonly Color pressed_gradient_second_color = Color.FromArgb( 199, 193, 187 );
56                 static readonly Color border_normal_dark_color = Color.FromArgb( 129, 117, 106 );
57                 static readonly Color border_normal_light_color = Color.FromArgb( 158, 145, 131 );
58                 static readonly Color border_pressed_dark_color = Color.FromArgb( 109, 103, 98 );
59                 static readonly Color border_pressed_light_color = Color.FromArgb( 120, 114, 107 );
60                 static readonly Color button_outer_border_dark_color = Color.FromArgb( 232, 226, 220 );
61                 static readonly Color button_outer_border_light_color = Color.FromArgb( 250, 248, 247 ); 
62                 static readonly Color inner_border_dark_color = Color.FromArgb( 226, 219, 212 );
63                 static readonly Color pressed_inner_border_dark_color = Color.FromArgb( 192, 181, 169 );
64                 static readonly Color edge_top_inner_color = Color.FromArgb( 206, 200, 194 );
65                 static readonly Color edge_bottom_inner_color = Color.FromArgb( 215, 209, 202 );
66                 static readonly Color button_edge_top_outer_color = Color.FromArgb( 237, 233, 228 );
67                 static readonly Color button_edge_bottom_outer_color = Color.FromArgb( 243, 239, 236 );
68                 static readonly Color button_focus_color = Color.FromArgb( 101, 94, 86 );
69                 static readonly Color button_mouse_entered_second_gradient_color = Color.FromArgb( 230, 226, 219 );
70                 
71                 static readonly Color scrollbar_background_color = Color.FromArgb( 209, 200, 191 );
72                 static readonly Color scrollbar_border_color = Color.FromArgb( 170, 156, 143 );
73                 static readonly Color scrollbar_gradient_first_color = Color.FromArgb( 248, 247, 245 );
74                 static readonly Color scrollbar_gradient_second_color = Color.FromArgb( 234, 229, 224 );
75                 
76                 new static readonly Color arrow_color = Color.FromArgb( 16, 16, 16 );
77                 
78                 static readonly Color tab_border_color = Color.FromArgb( 166, 151, 138 );
79                 static readonly Color tab_not_selected_gradient_first_color = Color.FromArgb( 227, 223, 220 );
80                 static readonly Color tab_not_selected_gradient_second_color = Color.FromArgb( 214, 209, 204 );
81                 static readonly Color tab_selected_gradient_first_color = Color.FromArgb( 243, 239, 236 );
82                 static readonly Color tab_selected_gradient_second_color = Color.FromArgb( 234, 228, 223 );
83                 static readonly Color tab_edge_color = Color.FromArgb( 200, 196, 191 );
84                 static readonly Color tab_inner_border_color = Color.FromArgb( 221, 212, 205 );
85                 static readonly Color tab_top_border_focus_color = Color.FromArgb( 70, 91, 110 );
86                 static readonly Color tab_focus_color = Color.FromArgb( 105, 147, 185 );
87                 
88                 static readonly Color menuitem_gradient_first_color = Color.FromArgb( 98, 140, 178 );
89                 static readonly Color menuitem_gradient_second_color = Color.FromArgb( 81, 113, 142 );
90                 static readonly Color menuitem_border_color = Color.FromArgb( 80, 112, 141 );
91                 static readonly Color menu_separator_color = Color.FromArgb( 219, 211, 203 );
92                 static readonly Color menu_background_color = Color.FromArgb( 248, 245, 242 );
93                 static readonly Color menu_border_color = Color.FromArgb( 141, 122, 104 );
94                 static readonly Color menu_inner_border_color = Color.FromArgb( 236, 228, 221 );
95                 
96                 static readonly Color combobox_border_color = Color.FromArgb( 159, 146, 132 );
97                 static readonly Color combobox_focus_border_color = Color.FromArgb( 70, 91, 110 );
98                 //static readonly Color combobox_focus_inner_border_color = Color.FromArgb( 167, 198, 225 );
99                 static readonly Color combobox_button_second_gradient_color = Color.FromArgb( 226, 220, 213 );
100                 
101                 static readonly Color progressbar_edge_dot_color = Color.FromArgb( 219, 212, 205 );
102                 static readonly Color progressbar_inner_border_color = Color.FromArgb( 139, 176, 209 );
103                 static readonly Color progressbar_first_gradient_color = Color.FromArgb( 104, 146, 184 );
104                 static readonly Color progressbar_second_gradient_color = Color.FromArgb( 91, 133, 172 );
105                 
106                 static readonly Color checkbox_inner_boder_color = Color.FromArgb( 237, 234, 231 );
107                 static readonly Color checkbox_pressed_inner_boder_color = Color.FromArgb( 203, 196, 189 );
108                 static readonly Color checkbox_pressed_backcolor = Color.FromArgb( 212, 207, 202 );
109                 
110                 static readonly Color trackbar_second_gradient_color = Color.FromArgb( 114, 154, 190 );
111                 static readonly Color trackbar_third_gradient_color = Color.FromArgb( 130, 168, 202 );
112                 static readonly Color trackbar_inner_first_gradient_color = Color.FromArgb( 238, 233, 229 );
113                 static readonly Color trackbar_inner_second_gradient_color = Color.FromArgb( 223, 215, 208 );
114                 static readonly Color trackbar_inner_pressed_second_gradient_color = Color.FromArgb( 224, 217, 210 );
115                 
116                 //static readonly Color disabled_color_foreground = Color.FromArgb( 182, 180, 173 );
117                 
118                 static readonly Color active_caption = Color.FromArgb( 85, 152, 215 );
119                 
120                 static readonly Color radio_button_border_circle_color = Color.FromArgb( 126, 118, 105 );
121                 static readonly Color radio_button_dot_color = Color.FromArgb( 94, 160, 221 );
122                 
123                 const int SEPARATOR_HEIGHT = 7;
124                 const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tab
125                 const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
126                 
127                 static Color control_parent_backcolor;
128                 
129                 #region Principal Theme Methods
130                 public ThemeClearlooks( ) {
131                         ColorControl = theme_back_color;
132                 }
133                 
134                 public override Color DefaultControlBackColor {
135                         get { return theme_back_color; }
136                 }
137                 
138                 public override Color DefaultWindowBackColor {
139                         get { return theme_back_color; }                        
140                 }
141                 
142                 public override Color ColorControl {
143                         get { return theme_back_color;}
144                 }
145                 
146                 public override Color ColorHighlight {
147                         get { return menuitem_gradient_first_color; }
148                 }
149                 
150                 public override Color ColorActiveCaption {
151                         get { return active_caption; }
152                 }
153                 
154                 public override Size Border3DSize {
155                         get {
156                                 return new Size( 3, 3 );
157                         }
158                 }
159                 
160                 public override Color ColorInfo {
161                         get { return Color.FromArgb (255, 255, 191); }
162                 }
163                 
164                 static readonly Color info_border_color = Color.FromArgb (218, 178, 85);
165                 static readonly Color info_second_color = Color.FromArgb (220, 220, 160);
166
167                 public override Image Images(UIIcon index, int size) {
168                         switch (index) {
169                         case UIIcon.PlacesRecentDocuments:
170                                 if (XplatUI.RunningOnUnix)
171                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "recently/recently", new Size(size, size) );
172                                 else
173                                         return base.Images (UIIcon.PlacesRecentDocuments, size);
174                         case UIIcon.PlacesDesktop:
175                                 if (XplatUI.RunningOnUnix)
176                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "desktop/desktop", new Size(size, size) );
177                                 else
178                                         return base.Images (UIIcon.PlacesDesktop, size);
179                         case UIIcon.PlacesPersonal:
180                                 if (XplatUI.RunningOnUnix)
181                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "directory/home", new Size(size, size) );
182                                 else
183                                         return base.Images (UIIcon.PlacesPersonal, size);
184                         case UIIcon.PlacesMyComputer:
185                                 if (XplatUI.RunningOnUnix)
186                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "workplace/workplace", new Size(size, size) );
187                                 else
188                                         return base.Images (UIIcon.PlacesMyComputer, size);
189                         case UIIcon.PlacesMyNetwork:
190                                 if (XplatUI.RunningOnUnix)
191                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "network/network", new Size(size, size) );
192                                 else
193                                         return base.Images (UIIcon.PlacesMyNetwork, size);
194                                 
195                                 // Icons for message boxes
196                         case UIIcon.MessageBoxError:            return base.Images (UIIcon.MessageBoxError, size);
197                         case UIIcon.MessageBoxInfo:             return base.Images (UIIcon.MessageBoxInfo, size);
198                         case UIIcon.MessageBoxQuestion:         return base.Images (UIIcon.MessageBoxQuestion, size);
199                         case UIIcon.MessageBoxWarning:          return base.Images (UIIcon.MessageBoxWarning, size);
200                                 
201                                 // misc Icons
202                         case UIIcon.NormalFolder:
203                                 if (XplatUI.RunningOnUnix)
204                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "inode/directory", new Size(size, size) );
205                                 else
206                                         return base.Images (UIIcon.NormalFolder, size);
207                                 
208                         default: {
209                                         throw new ArgumentException("Invalid Icon type requested", "index");
210                                 }
211                         }
212                 }
213                 #endregion      // Internal Methods
214                 
215                 #region ButtonBase
216                 protected override void ButtonBase_DrawButton( ButtonBase button, Graphics dc ) {
217                         dc.FillRectangle( ResPool.GetSolidBrush( button.BackColor ), button.ClientRectangle );
218                         
219                         Color first_gradient_color = gradient_first_color;
220                         Color second_gradient_color = gradient_second_color;
221                         
222                         if (((button is CheckBox) && (((CheckBox)button).check_state == CheckState.Checked)) ||
223                             ((button is RadioButton) && (((RadioButton)button).check_state == CheckState.Checked))) {
224                                 first_gradient_color = button.is_entered ? gradient_second_color : pressed_gradient_first_color;
225                                 second_gradient_color = button.is_entered  ? gradient_second_color : pressed_gradient_second_color;
226                         } else
227                         if (!button.is_enabled) {
228                                 button.is_entered = false;
229                         } else
230                         if (button.is_entered) {
231                                 if (!button.is_pressed) {
232                                         first_gradient_color = Color.White;
233                                         second_gradient_color = button_mouse_entered_second_gradient_color;
234                                 } else {
235                                         first_gradient_color = pressed_gradient_first_color;
236                                         second_gradient_color = pressed_gradient_second_color;
237                                 }
238                         }
239                         
240                         bool paint_acceptbutton_black_border = false;
241                         Form form = button.TopLevelControl as Form;
242                         
243                         if (form != null && (form.AcceptButton == button as IButtonControl))
244                                 paint_acceptbutton_black_border = true;
245                         
246                         CL_Draw_Button(dc, button.ClientRectangle, button.FlatStyle,
247                                           button.is_entered, button.is_enabled, button.is_pressed,
248                                           first_gradient_color, second_gradient_color,
249                                           paint_acceptbutton_black_border);
250                 }
251
252                 private void CL_Draw_Button(Graphics dc, Rectangle buttonRectangle, FlatStyle flat_style,
253                                                bool is_entered, bool is_enabled, bool is_pressed,
254                                                Color first_gradient_color, Color second_gradient_color,
255                                                bool paint_acceptbutton_black_border)
256                 {
257                         Rectangle lgbRectangle = new Rectangle (buttonRectangle.X + 3, buttonRectangle.Y + 3,
258                                                                 is_pressed ? buttonRectangle.Width - 5 : buttonRectangle.Width - 6,
259                                                                 buttonRectangle.Height - 6);
260                         
261                         if (flat_style != FlatStyle.Popup || ((flat_style == FlatStyle.Popup) && is_entered)) {
262                                 LinearGradientBrush lgbr;
263                                 if (flat_style == FlatStyle.Flat) {
264                                         lgbr = new LinearGradientBrush (new Point (buttonRectangle.X, buttonRectangle.Y + 3),
265                                                                        new Point (buttonRectangle.X, buttonRectangle.Bottom - 3),
266                                                                        second_gradient_color, first_gradient_color);
267                                 } else {
268                                         lgbr = new LinearGradientBrush  (new Point (buttonRectangle.X, buttonRectangle.Y + 3),
269                                                                         new Point (buttonRectangle.X, buttonRectangle.Bottom - 3),
270                                                                         first_gradient_color, second_gradient_color);
271                                 }
272                                 dc.FillRectangle (lgbr, lgbRectangle);
273                                 lgbr.Dispose ();
274                                 
275                                 Point[] points_top = {
276                                         new Point (buttonRectangle.X + 2, buttonRectangle.Y + 2),
277                                         new Point (buttonRectangle.X + 3, buttonRectangle.Y + 1),
278                                         new Point (buttonRectangle.Right - 4, buttonRectangle.Y + 1),
279                                         new Point (buttonRectangle.Right - 3 , buttonRectangle.Y + 2)
280                                 };
281                                 
282                                 Point[] points_bottom = {
283                                         new Point (buttonRectangle.X + 2, buttonRectangle.Bottom - 3),
284                                         new Point (buttonRectangle.X + 3, buttonRectangle.Bottom - 2),
285                                         new Point (buttonRectangle.Right - 4, buttonRectangle.Bottom - 2),
286                                         new Point (buttonRectangle.Right - 3, buttonRectangle.Bottom - 3)
287                                 };
288                                 
289                                 Point[] points_top_outer = {
290                                         new Point (buttonRectangle.X + 1, buttonRectangle.Y + 1),
291                                         new Point (buttonRectangle.X + 2, buttonRectangle.Y),
292                                         new Point (buttonRectangle.Right - 3, buttonRectangle.Y),
293                                         new Point (buttonRectangle.Right - 2 , buttonRectangle.Y + 1)
294                                 };
295                                 
296                                 Point[] points_bottom_outer = {
297                                         new Point (buttonRectangle.X + 1, buttonRectangle.Bottom - 2),
298                                         new Point (buttonRectangle.X + 2, buttonRectangle.Bottom - 1),
299                                         new Point (buttonRectangle.Right - 3, buttonRectangle.Bottom - 1),
300                                         new Point (buttonRectangle.Right - 2, buttonRectangle.Bottom - 2)
301                                 };
302                                 
303                                 Pen pen = null; 
304                                 
305                                 // normal border
306                                 if (is_enabled) { 
307                                         Color top_color = Color.Black;
308                                         Color bottom_color = Color.Black;
309                                         
310                                         if (!paint_acceptbutton_black_border) {
311                                                 top_color = is_pressed ? border_pressed_dark_color : border_normal_dark_color;
312                                                 bottom_color = is_pressed ? border_pressed_light_color : border_normal_light_color;
313                                         }
314                                         
315                                         pen = ResPool.GetPen (top_color);
316                                         dc.DrawLines (pen, points_top);
317                                         pen = ResPool.GetPen (bottom_color);
318                                         dc.DrawLines (pen, points_bottom);
319                                         
320                                         using (LinearGradientBrush lgbr2 = new LinearGradientBrush (new Point (buttonRectangle.X, buttonRectangle.Y + 3),
321                                                                                                     new Point (buttonRectangle.X, buttonRectangle.Bottom - 3),
322                                                                                                     top_color, bottom_color)) {
323                                                 using (Pen lgbrpen = new Pen (lgbr2)) {
324                                                         dc.DrawLine (lgbrpen, buttonRectangle.X + 1, buttonRectangle.Y + 3, buttonRectangle.X + 1, buttonRectangle.Bottom - 3);
325                                                         dc.DrawLine (lgbrpen, buttonRectangle.Right - 2, buttonRectangle.Y + 3, buttonRectangle.Right - 2, buttonRectangle.Bottom - 3);
326                                                 }
327                                         }
328                                 } else {
329                                         Point[] points_button_complete = {
330                                                 new Point (buttonRectangle.X + 1, buttonRectangle.Y + 3),
331                                                 new Point (buttonRectangle.X + 3, buttonRectangle.Y + 1),
332                                                 new Point (buttonRectangle.Right - 4, buttonRectangle.Y + 1),
333                                                 new Point (buttonRectangle.Right - 2, buttonRectangle.Y + 3),
334                                                 new Point (buttonRectangle.Right - 2, buttonRectangle.Bottom - 4),
335                                                 new Point (buttonRectangle.Right - 4, buttonRectangle.Bottom - 2),
336                                                 new Point (buttonRectangle.X + 3, buttonRectangle.Bottom - 2),
337                                                 new Point (buttonRectangle.X + 1, buttonRectangle.Bottom - 4),
338                                                 new Point (buttonRectangle.X + 1, buttonRectangle.Y + 3)
339                                         };
340                                         
341                                         pen = ResPool.GetPen (pressed_inner_border_dark_color);
342                                         dc.DrawLines (pen, points_button_complete);
343                                 }
344                                 
345                                 // outer border
346                                 pen = ResPool.GetPen (button_outer_border_dark_color);
347                                 dc.DrawLines (pen, points_top_outer);
348                                 pen = ResPool.GetPen (button_outer_border_light_color);
349                                 dc.DrawLines (pen, points_bottom_outer);
350                                 
351                                 using (LinearGradientBrush lgbr2 = new LinearGradientBrush (new Point (buttonRectangle.X, buttonRectangle.Y + 2),
352                                                                                             new Point (buttonRectangle.X, buttonRectangle.Bottom - 1),
353                                                                                             button_outer_border_dark_color, button_outer_border_light_color)) {
354                                         using (Pen lgbrpen = new Pen(lgbr2)) {
355                                                 dc.DrawLine (lgbrpen, buttonRectangle.X, buttonRectangle.Y + 2, buttonRectangle.X, buttonRectangle.Bottom - 3);
356                                                 dc.DrawLine (lgbrpen, buttonRectangle.Right - 1, buttonRectangle.Y + 2, buttonRectangle.Right - 1, buttonRectangle.Bottom - 3);
357                                         }
358                                 }
359                                 
360                                 // inner border
361                                 pen = ResPool.GetPen (is_pressed ? pressed_inner_border_dark_color : inner_border_dark_color);
362                                 if (!is_pressed) {
363                                         dc.DrawLine (pen, buttonRectangle.Right - 3, buttonRectangle.Y + 3, buttonRectangle.Right - 3, buttonRectangle.Bottom - 4);
364                                 }
365                                 dc.DrawLine (pen, buttonRectangle.X + 3, buttonRectangle.Bottom - 3, buttonRectangle.Right - 4, buttonRectangle.Bottom - 3);
366                                 pen = ResPool.GetPen (is_pressed ? pressed_inner_border_dark_color : Color.White);
367                                 dc.DrawLine (pen, buttonRectangle.X + 2, buttonRectangle.Y + 3, buttonRectangle.X + 2, buttonRectangle.Bottom - 4);
368                                 dc.DrawLine (pen, buttonRectangle.X + 3 , buttonRectangle.Y + 2, buttonRectangle.Right - 4, buttonRectangle.Y + 2);
369                                 
370                                 // edges
371                                 pen = ResPool.GetPen (edge_top_inner_color);
372                                 dc.DrawLine (pen, buttonRectangle.X + 1, buttonRectangle.Y + 2, buttonRectangle.X + 2, buttonRectangle.Y + 1);
373                                 dc.DrawLine (pen, buttonRectangle.Right - 3, buttonRectangle.Y + 1, buttonRectangle.Right - 2, buttonRectangle.Y + 2);
374                                 
375                                 pen = ResPool.GetPen (button_edge_top_outer_color);
376                                 dc.DrawLine (pen, buttonRectangle.X, buttonRectangle.Y + 1, buttonRectangle.X + 1, buttonRectangle.Y);
377                                 dc.DrawLine (pen, buttonRectangle.Right - 2, buttonRectangle.Y, buttonRectangle.Right - 1, buttonRectangle.Y + 1);
378                                 
379                                 pen = ResPool.GetPen (edge_bottom_inner_color);
380                                 dc.DrawLine (pen, buttonRectangle.X + 1, buttonRectangle.Bottom - 3, buttonRectangle.X + 2, buttonRectangle.Bottom - 2);
381                                 dc.DrawLine (pen, buttonRectangle.Right - 2, buttonRectangle.Bottom - 3, buttonRectangle.Right - 3, buttonRectangle.Bottom - 2);
382                                 
383                                 pen = ResPool.GetPen (button_edge_bottom_outer_color);
384                                 dc.DrawLine (pen, buttonRectangle.X, buttonRectangle.Bottom - 2, buttonRectangle.X + 1, buttonRectangle.Bottom - 1);
385                                 dc.DrawLine (pen, buttonRectangle.Right - 1, buttonRectangle.Bottom - 2, buttonRectangle.Right - 2, buttonRectangle.Bottom - 1);
386                         }
387                 }
388                 
389                 protected override void ButtonBase_DrawFocus( ButtonBase button, Graphics dc ) {
390                         
391                         if ( !button.is_enabled || button.FlatStyle == FlatStyle.Popup )
392                                 return;
393                         
394                         Pen pen = ResPool.GetPen( button_focus_color );
395                         DashStyle old_dash_style = pen.DashStyle;
396                         pen.DashStyle = DashStyle.Dot;
397                         
398                         Rectangle focus_rect = new Rectangle( button.ClientRectangle.X + 4, button.ClientRectangle.Y + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9 );
399                         
400                         dc.DrawRectangle( pen, focus_rect );
401                         
402                         pen.DashStyle = old_dash_style;
403                 }
404                 
405                 // FIXME: remove if libgdiplus DrawOrMeasureString is fixed
406                 protected override void ButtonBase_DrawText( ButtonBase button, Graphics dc ) {
407                         if ( !( button is CheckBox ) && !( button is RadioButton ) ) {
408                                 Rectangle buttonRectangle = button.ClientRectangle;
409                                 Rectangle text_rect = Rectangle.Inflate( buttonRectangle, -4, -4 );
410                                 
411                                 string text = button.Text;
412                                 
413                                 if ( text.Length > 1 ) {
414                                         SizeF sizef = dc.MeasureString( text, button.Font, text_rect.Width, button.text_format );
415                                         
416                                         if ( (int)sizef.Width > text_rect.Width - 3 ) {
417                                                 for ( int i = 1; i < text.Length + 1; i++ ) {
418                                                         sizef = dc.MeasureString( text.Substring( 0, i ), button.Font, text_rect.Width, button.text_format );
419                                                         
420                                                         if ( (int)sizef.Width > text_rect.Width - 3 ) {
421                                                                 text = text.Substring( 0, i - 1 );
422                                                                 break;
423                                                         }
424                                                 }
425                                         }
426                                 }
427                                 
428                                 if ( button.is_pressed ) {
429                                         text_rect.X++;
430                                         text_rect.Y++;
431                                 }
432                                 
433                                 if ( button.is_enabled ) {                                      
434                                         dc.DrawString( text, button.Font, ResPool.GetSolidBrush( button.ForeColor ), text_rect, button.text_format );
435                                 } else {
436                                         if ( button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup ) {
437                                                 dc.DrawString( text, button.Font, ResPool.GetSolidBrush( ControlPaint.DarkDark( this.ColorControl ) ), text_rect, button.text_format );
438                                         } else {
439                                                 CPDrawStringDisabled( dc, text, button.Font, ColorControlText, text_rect, button.text_format );
440                                         }
441                                 }
442                         }
443                 }
444                 #endregion      // ButtonBase
445                 
446                 #region Menus
447                 public override void DrawMenuItem( MenuItem item, DrawItemEventArgs e ) {
448                         StringFormat string_format;
449                         Rectangle rect_text = e.Bounds;
450                         
451                         if ( item.Visible == false )
452                                 return; 
453                         
454                         if ( item.MenuBar ) {
455                                 string_format = string_format_menu_menubar_text;
456                         } else {
457                                 string_format = string_format_menu_text;
458                         }
459                         
460                         if ( item.Separator ) {
461                                 e.Graphics.DrawLine( ResPool.GetPen( menu_separator_color ),
462                                                     e.Bounds.X, e.Bounds.Y + 1, e.Bounds.X + e.Bounds.Right - 4, e.Bounds.Y + 1 );
463                                 
464                                 e.Graphics.DrawLine( ResPool.GetPen( Color.White ),
465                                                     e.Bounds.X, e.Bounds.Y + 2, e.Bounds.X + e.Bounds.Right - 4, e.Bounds.Y + 2 );
466                                 
467                                 return;
468                         }
469                         
470                         if ( !item.MenuBar )
471                                 rect_text.X += MenuCheckSize.Width;
472                         
473                         if ( item.BarBreak ) { /* Draw vertical break bar*/
474                                 Rectangle rect = e.Bounds;
475                                 rect.Y++;
476                                 rect.Width = 3;
477                                 rect.Height = item.MenuHeight - 6;
478                                 
479                                 e.Graphics.DrawLine( ResPool.GetPen( menu_separator_color ),
480                                                     rect.X, rect.Y , rect.X, rect.Y + rect.Height );
481                                 
482                                 e.Graphics.DrawLine( ResPool.GetPen( ColorControlLight ),
483                                                     rect.X + 1, rect.Y , rect.X + 1, rect.Y + rect.Height );
484                         }
485                         
486                         Color color_text = ColorMenuText;
487                         Color color_back;
488                         
489                         /* Draw background */
490                         Rectangle rect_back = e.Bounds;
491                         rect_back.X++;
492                         rect_back.Width -= 2;
493                         
494                         if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected ) {
495                                 color_text = ColorHighlightText;
496                                 color_back = item.MenuBar ? theme_back_color : menu_background_color;
497                                 
498                                 using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( rect_back.X, rect_back.Y + 1 ), new Point( rect_back.X, rect_back.Bottom - 1 ), menuitem_gradient_first_color, menuitem_gradient_second_color ) ) {
499                                         e.Graphics.FillRectangle( lgbr, rect_back.X + 1, rect_back.Y + 1, rect_back.Width - 1, rect_back.Height - 1 );
500                                 }
501                                 
502                                 rect_back.Height--;
503                                 Pen tmp_pen = ResPool.GetPen( menuitem_border_color );
504                                 e.Graphics.DrawLine( tmp_pen, rect_back.X + 1, rect_back.Y, rect_back.Right - 1, rect_back.Y );
505                                 e.Graphics.DrawLine( tmp_pen, rect_back.Right, rect_back.Y + 1, rect_back.Right, rect_back.Bottom - 1 );
506                                 e.Graphics.DrawLine( tmp_pen, rect_back.Right - 1, rect_back.Bottom, rect_back.X + 1, rect_back.Bottom );
507                                 e.Graphics.DrawLine( tmp_pen, rect_back.X, rect_back.Bottom - 1, rect_back.X, rect_back.Y + 1 );
508                         } else {
509                                 color_text = ColorMenuText;
510                                 color_back = item.MenuBar ? theme_back_color : menu_background_color;
511                                 
512                                 e.Graphics.FillRectangle( ResPool.GetSolidBrush( color_back ), rect_back );
513                         }
514                         
515                         if ( item.Enabled ) {
516                                 e.Graphics.DrawString( item.Text, e.Font,
517                                                       ResPool.GetSolidBrush( color_text ),
518                                                       rect_text, string_format );
519                                 
520                                 if ( !item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut ) {
521                                         string str = item.GetShortCutText( );
522                                         Rectangle rect = rect_text;
523                                         rect.X = item.XTab;
524                                         rect.Width -= item.XTab;
525                                         
526                                         e.Graphics.DrawString( str, e.Font, ResPool.GetSolidBrush( color_text ),
527                                                               rect, string_format_menu_shortcut );
528                                 }
529                         } else {
530                                 ControlPaint.DrawStringDisabled( e.Graphics, item.Text, e.Font,
531                                                                 Color.Black, rect_text, string_format );
532                         }
533                         
534                         /* Draw arrow */
535                         if ( item.MenuBar == false && item.IsPopup ) {
536                                 int cx = MenuCheckSize.Width;
537                                 int cy = MenuCheckSize.Height;
538                                 using ( Bitmap  bmp = new Bitmap( cx, cy ) ) {
539                                         using ( Graphics dc = Graphics.FromImage( bmp ) ) {
540                                                 SmoothingMode old_smoothing_mode = dc.SmoothingMode;
541                                                 dc.SmoothingMode = SmoothingMode.AntiAlias;
542                                                 
543                                                 Rectangle rect_arrow = new Rectangle( 0, 0, cx, cy );
544                                                 ControlPaint.DrawMenuGlyph( dc, rect_arrow, MenuGlyph.Arrow );
545                                                 bmp.MakeTransparent( );
546                                                 
547                                                 if ( item.Enabled ) {
548                                                         e.Graphics.DrawImage( bmp, e.Bounds.X + e.Bounds.Width - cx,
549                                                                              e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ) );
550                                                 } else {
551                                                         ControlPaint.DrawImageDisabled( e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
552                                                                                        e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ),  color_back );
553                                                 }
554                                                 
555                                                 dc.SmoothingMode = old_smoothing_mode;
556                                         }
557                                 }
558                         }
559                         
560                         /* Draw checked or radio */
561                         if ( item.MenuBar == false && item.Checked ) {
562                                 
563                                 Rectangle area = e.Bounds;
564                                 int cx = MenuCheckSize.Width;
565                                 int cy = MenuCheckSize.Height;
566                                 using ( Bitmap bmp = new Bitmap( cx, cy ) ) {
567                                         using ( Graphics gr = Graphics.FromImage( bmp ) ) {
568                                                 Rectangle rect_arrow = new Rectangle( 0, 0, cx, cy );
569                                                 
570                                                 if ( item.RadioCheck )
571                                                         ControlPaint.DrawMenuGlyph( gr, rect_arrow, MenuGlyph.Bullet );
572                                                 else
573                                                         ControlPaint.DrawMenuGlyph( gr, rect_arrow, MenuGlyph.Checkmark );
574                                                 
575                                                 bmp.MakeTransparent( );
576                                                 e.Graphics.DrawImage( bmp, area.X, e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ) );
577                                         }
578                                 }
579                         }
580                 }
581                 
582                 public override void DrawPopupMenu( Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect ) {
583                         
584                         dc.FillRectangle( ResPool.GetSolidBrush
585                                          ( menu_background_color ), cliparea );
586                         
587                         /* Draw menu borders */
588                         dc.DrawRectangle( ResPool.GetPen( menu_border_color ), rect.X, rect.Y, rect.Width - 1, rect.Height - 1 );
589                         
590                         // inner border
591                         Pen tmp_pen = ResPool.GetPen( Color.White );
592                         dc.DrawLine( tmp_pen, rect.X + 1, rect.Y + 1, rect.Right - 2, rect.Y + 1 );
593                         dc.DrawLine( tmp_pen, rect.X + 1, rect.Y + 2, rect.X + 1, rect.Bottom - 2 );
594                         
595                         tmp_pen = ResPool.GetPen( menu_inner_border_color );
596                         dc.DrawLine( tmp_pen, rect.Right - 2, rect.Y + 2, rect.Right - 2, rect.Bottom - 2 );
597                         dc.DrawLine( tmp_pen, rect.Right - 3, rect.Bottom - 2, rect.X + 2, rect.Bottom - 2 );
598                         
599                         for ( int i = 0; i < menu.MenuItems.Count; i++ )
600                                 if ( cliparea.IntersectsWith( menu.MenuItems[ i ].bounds ) ) {
601                                         MenuItem item = menu.MenuItems[ i ];
602                                         item.MenuHeight = menu.Height;
603                                         item.PerformDrawItem( new DrawItemEventArgs( dc, MenuFont,
604                                                                                     item.bounds, i, item.Status ) );
605                                 }
606                 }
607                 #endregion // Menus
608                 
609                 #region ProgressBar
610                 public override void DrawProgressBar( Graphics dc, Rectangle clip_rect, ProgressBar ctrl ) {
611                         Rectangle       client_area = ctrl.client_area;
612                         int             barpos_pixels;
613                         Rectangle bar = ctrl.client_area;
614                         
615                         barpos_pixels = ( ( ctrl.Value - ctrl.Minimum ) * client_area.Width ) / ( ctrl.Maximum - ctrl.Minimum );
616                         
617                         bar.Width = barpos_pixels + 1;
618                         
619                         // Draw bar background
620                         dc.FillRectangle( ResPool.GetSolidBrush( menu_separator_color ), ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.Width - 2, ctrl.ClientRectangle.Height - 2 );
621                         
622                         /* Draw border */
623                         Pen tmp_pen = ResPool.GetPen( progressbar_edge_dot_color );
624                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y + 1 );
625                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 2 );
626                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y + 1 );
627                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 2 );
628                         
629                         tmp_pen = ResPool.GetPen( scrollbar_border_color );
630                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.Right - 2, ctrl.ClientRectangle.Y );
631                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 2 );
632                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.Right - 2, ctrl.ClientRectangle.Bottom - 1 );
633                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 2 );
634                         
635                         if ( barpos_pixels <= 0 )
636                                 return;
637                         
638                         if ((bar.Width - 2) <= 0 || (bar.Height - 1) <= 0)
639                                 return;
640                         
641                         // Draw bar
642                         dc.DrawRectangle( ResPool.GetPen( combobox_focus_border_color ), bar.X - 1, bar.Y - 1, bar.Width, bar.Height + 1 );
643                         tmp_pen = ResPool.GetPen( progressbar_inner_border_color );
644                         dc.DrawLine( tmp_pen, bar.X, bar.Y, bar.Right - 2, bar.Y );
645                         dc.DrawLine( tmp_pen, bar.X, bar.Y, bar.X, bar.Bottom - 1 );
646                         
647                         using ( Bitmap bmp = new Bitmap( bar.Width - 2, bar.Height - 1 ) ) {
648                                 using ( Graphics gr = Graphics.FromImage( bmp ) ) {
649                                         gr.FillRectangle( ResPool.GetSolidBrush( tab_focus_color ), 0, 0, bmp.Width, bmp.Height );
650                                         
651                                         LinearGradientBrush lgbr = new LinearGradientBrush( new Rectangle( 0, 0, bmp.Height, bmp.Height ), progressbar_first_gradient_color, progressbar_second_gradient_color, 0.0f, true );
652                                         
653                                         lgbr.RotateTransform( 45.0f, MatrixOrder.Append );
654                                         
655                                         float pen_width = bmp.Height / 2;
656                                         
657                                         Pen pen = new Pen( lgbr, pen_width );
658                                         
659                                         int add = bmp.Height + (int)pen.Width / 2;
660                                         
661                                         int x_top = 0;
662                                         int x_bottom = - bmp.Height;
663                                         
664                                         while ( x_bottom < bmp.Width ) {
665                                                 gr.DrawLine( pen, x_top, 0, x_bottom, bmp.Height );
666                                                 x_top += add;
667                                                 x_bottom += add;
668                                         }
669                                         pen.Dispose( );
670                                         lgbr.Dispose( );
671                                 }
672                                 
673                                 dc.DrawImage( bmp, bar.X + 1, bar.Y + 1 );
674                         }
675                 }
676                 #endregion      // ProgressBar
677                 
678                 #region RadioButton
679                 
680                 // renders a radio button with the Flat and Popup FlatStyle
681                 protected override void DrawFlatStyleRadioButton (Graphics dc, Rectangle rectangle, RadioButton radio_button)
682                 {
683                         if (radio_button.Enabled) {
684                                 // draw the outer flatstyle arcs
685                                 if (radio_button.FlatStyle == FlatStyle.Flat) {
686                                         dc.DrawArc (ResPool.GetPen (radio_button.ForeColor), rectangle, 0, 359);
687                                         
688                                         // fill in the area depending on whether or not the mouse is hovering
689                                         if (radio_button.is_entered && radio_button.Capture) {
690                                                 dc.FillPie (ResPool.GetSolidBrush (ControlPaint.Light (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
691                                         } else {
692                                                 dc.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
693                                         }
694                                 } else {
695                                         // must be a popup radio button
696                                         // fill the control
697                                         dc.FillPie (ResPool.GetSolidBrush (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 0, 359);
698                                         
699                                         if (radio_button.is_entered || radio_button.Capture) {
700                                                 // draw the popup 3d button knob
701                                                 dc.DrawArc (ResPool.GetPen (ControlPaint.Light (radio_button.BackColor)), rectangle.X+1, rectangle.Y+1, rectangle.Width-2, rectangle.Height-2, 0, 359);
702                                                 
703                                                 dc.DrawArc (ResPool.GetPen (ControlPaint.Dark (radio_button.BackColor)), rectangle, 135, 180);
704                                                 dc.DrawArc (ResPool.GetPen (ControlPaint.LightLight (radio_button.BackColor)), rectangle, 315, 180);
705                                                 
706                                         } else {
707                                                 // just draw lighter flatstyle outer circle
708                                                 dc.DrawArc (ResPool.GetPen (ControlPaint.Dark (this.ColorControl)), rectangle, 0, 359);                                         
709                                         }                                                                               
710                                 }
711                         } else {
712                                 // disabled
713                                 // fill control background color regardless of actual backcolor
714                                 dc.FillPie (ResPool.GetSolidBrush (this.ColorControl), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
715                                 // draw the ark as control dark
716                                 dc.DrawArc (ResPool.GetPen (ControlPaint.Dark(this.ColorControl)), rectangle, 0, 359);
717                         }
718                         
719                         // draw the check
720                         if (radio_button.Checked) {
721                                 SmoothingMode old_smoothing_mode = dc.SmoothingMode;
722                                 dc.SmoothingMode = SmoothingMode.AntiAlias;
723                                 
724                                 CL_Draw_RadioButton_Dot (dc, rectangle, true, false);
725                                 
726                                 dc.SmoothingMode = old_smoothing_mode;
727                         }
728                 }
729                 #endregion      // RadioButton
730                 
731                 #region ScrollBar
732                 public override void DrawScrollBar( Graphics dc, Rectangle clip, ScrollBar bar ) {
733                         int             scrollbutton_width = bar.scrollbutton_width;
734                         int             scrollbutton_height = bar.scrollbutton_height;
735                         Rectangle       first_arrow_area;
736                         Rectangle       second_arrow_area;                      
737                         Rectangle       thumb_pos;
738                         
739                         thumb_pos = bar.ThumbPos;
740                         
741                         if ( bar.vert ) {
742                                 first_arrow_area = new Rectangle( 0, 0, bar.Width, scrollbutton_height + 1 );
743                                 bar.FirstArrowArea = first_arrow_area;
744                                 
745                                 second_arrow_area = new Rectangle( 0, bar.ClientRectangle.Height - scrollbutton_height - 1, bar.Width, scrollbutton_height + 1 );
746                                 bar.SecondArrowArea = second_arrow_area;
747                                 
748                                 thumb_pos.Width = bar.Width;
749                                 bar.ThumbPos = thumb_pos;
750
751                                 Pen pen;
752                                 /* Background, upper track */
753                                 Rectangle UpperTrack = new Rectangle (0, 0, bar.ClientRectangle.Width, bar.ThumbPos.Top);
754                                 if (clip.IntersectsWith (UpperTrack))
755                                         dc.FillRectangle (ResPool.GetSolidBrush (scrollbar_background_color), UpperTrack);
756                                         pen = ResPool.GetPen (scrollbar_border_color);
757                                         dc.DrawLine (pen, UpperTrack.X, UpperTrack.Y, UpperTrack.X, UpperTrack.Bottom - 1);
758                                         dc.DrawLine (pen, UpperTrack.Right - 1, UpperTrack.Y, UpperTrack.Right - 1, UpperTrack.Bottom - 1);
759
760                                 /* Background, lower track */
761                                 Rectangle LowerTrack = new Rectangle (0, bar.ThumbPos.Bottom, bar.ClientRectangle.Width, bar.ClientRectangle.Height - bar.ThumbPos.Bottom);
762                                 if (clip.IntersectsWith (LowerTrack))
763                                         dc.FillRectangle (ResPool.GetSolidBrush (scrollbar_background_color), LowerTrack);
764                                         pen = ResPool.GetPen (scrollbar_border_color);
765                                         dc.DrawLine (pen, LowerTrack.X, LowerTrack.Y, LowerTrack.X, LowerTrack.Bottom - 1);
766                                         dc.DrawLine (pen, LowerTrack.Right - 1, LowerTrack.Y, LowerTrack.Right - 1, LowerTrack.Bottom - 1);
767
768                                 /* Buttons */
769                                 if ( clip.IntersectsWith( first_arrow_area ) )
770                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state );
771                                 if ( clip.IntersectsWith( second_arrow_area ) )
772                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state );
773                         } else {
774                                 first_arrow_area = new Rectangle( 0, 0, scrollbutton_width + 1, bar.Height );
775                                 bar.FirstArrowArea = first_arrow_area;
776                                 
777                                 second_arrow_area = new Rectangle( bar.ClientRectangle.Width - scrollbutton_width - 1, 0, scrollbutton_width + 1, bar.Height );
778                                 bar.SecondArrowArea = second_arrow_area;
779                                 
780                                 thumb_pos.Height = bar.Height;
781                                 bar.ThumbPos = thumb_pos;
782
783                                 Pen pen;
784                                 //Background, left track
785                                 Rectangle LeftTrack = new Rectangle (0, 0, bar.ThumbPos.Left, bar.ClientRectangle.Height);
786                                 if (clip.IntersectsWith (LeftTrack))
787                                         dc.FillRectangle (ResPool.GetSolidBrush (scrollbar_background_color), LeftTrack);
788                                         pen = ResPool.GetPen (scrollbar_border_color);
789                                         dc.DrawLine (pen, LeftTrack.X, LeftTrack.Y, LeftTrack.Right - 1, LeftTrack.Y);
790                                         dc.DrawLine (pen, LeftTrack.X, LeftTrack.Bottom - 1, LeftTrack.Right - 1, LeftTrack.Bottom - 1);
791
792                                 //Background, right track
793                                 Rectangle RightTrack = new Rectangle (bar.ThumbPos.Right, 0, bar.ClientRectangle.Width - bar.ThumbPos.Right, bar.ClientRectangle.Height);
794                                 if (clip.IntersectsWith (RightTrack))
795                                         dc.FillRectangle (ResPool.GetSolidBrush (scrollbar_background_color), RightTrack);
796                                         pen = ResPool.GetPen (scrollbar_border_color);
797                                         dc.DrawLine (pen, RightTrack.X, RightTrack.Y, RightTrack.Right - 1, RightTrack.Y);
798                                         dc.DrawLine (pen, RightTrack.X, RightTrack.Bottom - 1, RightTrack.Right - 1, RightTrack.Bottom - 1);                                    
799                                 
800                                 /* Buttons */
801                                 if ( clip.IntersectsWith( first_arrow_area ) )
802                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state );
803                                 if ( clip.IntersectsWith( second_arrow_area ) )
804                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state );
805                         }
806                         
807                         /* Thumb */
808                         ScrollBar_DrawThumb( bar, thumb_pos, clip, dc );                                
809                 }
810                 
811                 protected override void ScrollBar_DrawThumb( ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) {
812                         if ( bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith( thumb_pos ) )
813                                 DrawScrollBarThumb( dc, thumb_pos, bar );
814                 }
815                 #endregion      // ScrollBar
816                 
817                 #region StatusBar
818                 protected override void DrawStatusBarPanel( Graphics dc, Rectangle area, int index,
819                                                            Brush br_forecolor, StatusBarPanel panel ) {
820                         int border_size = 3; // this is actually const, even if the border style is none
821                         
822                         area.Height -= border_size;
823                         if ( panel.BorderStyle != StatusBarPanelBorderStyle.None ) {
824                                 dc.DrawRectangle( ResPool.GetPen( pressed_inner_border_dark_color ), area );
825                         }
826                         
827                         if ( panel.Style == StatusBarPanelStyle.OwnerDraw ) {
828                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs(
829                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
830                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor );
831                                 panel.Parent.OnDrawItemInternal( e );
832                                 return;
833                         }
834                         
835                         int left = area.Left;
836                         if ( panel.Icon != null ) {
837                                 left += 2;
838                                 dc.DrawIcon( panel.Icon, left, area.Top );
839                                 left += panel.Icon.Width;
840                         }
841                         
842                         if ( panel.Text == String.Empty )
843                                 return;
844                         
845                         string text = panel.Text;
846                         StringFormat string_format = new StringFormat( );
847                         string_format.Trimming = StringTrimming.Character;
848                         string_format.FormatFlags = StringFormatFlags.NoWrap;
849                         
850                         if ( text[ 0 ] == '\t' ) {
851                                 string_format.Alignment = StringAlignment.Center;
852                                 text = text.Substring( 1 );
853                                 if ( text[ 0 ] == '\t' ) {
854                                         string_format.Alignment = StringAlignment.Far;
855                                         text = text.Substring( 1 );
856                                 }
857                         }
858                         
859                         int x = left + border_size;
860                         int y = border_size + 2;
861                         Rectangle r = new Rectangle( x, y,
862                                                     area.Right - x - border_size,
863                                                     area.Bottom - y - border_size );
864                         
865                         dc.DrawString( text, panel.Parent.Font, br_forecolor, r, string_format );
866                 }
867                 #endregion      // StatusBar
868                 
869                 // FIXME: regions near the borders don't get filled with the correct backcolor
870                 // TODO: TabAlignment.Left and TabAlignment.Bottom
871                 public override void DrawTabControl( Graphics dc, Rectangle area, TabControl tab ) {
872                         if (tab.Parent != null)
873                                 dc.FillRectangle( ResPool.GetSolidBrush( tab.Parent.BackColor ), area );
874                         else
875                                 dc.FillRectangle( ResPool.GetSolidBrush( tab.BackColor ), area );
876                         Rectangle panel_rect = TabControlGetPanelRect( tab );
877                         
878                         if ( tab.Appearance == TabAppearance.Normal ) {
879                                 
880                                 switch ( tab.Alignment ) {
881                                         case TabAlignment.Top:
882                                                 // inner border...
883                                                 Pen pen = ResPool.GetPen( Color.White );
884                                                 
885                                                 dc.DrawLine( pen, panel_rect.Left + 1, panel_rect.Top, panel_rect.Left + 1, panel_rect.Bottom - 1 );
886                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top , panel_rect.Right - 2, panel_rect.Top );
887                                                 
888                                                 pen = ResPool.GetPen( tab_inner_border_color );
889                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Top + 1, panel_rect.Right - 2, panel_rect.Bottom - 2 );
890                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Bottom - 1, panel_rect.Left + 2, panel_rect.Bottom - 1 );
891                                                 
892                                                 // border
893                                                 pen = ResPool.GetPen( tab_border_color );
894                                                 
895                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Top - 1, panel_rect.Right - 1, panel_rect.Top - 1 );
896                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Top - 1, panel_rect.Right - 1, panel_rect.Bottom - 2 );
897                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Bottom - 2, panel_rect.Right - 3, panel_rect.Bottom );
898                                                 dc.DrawLine( pen, panel_rect.Right - 3, panel_rect.Bottom, panel_rect.Left + 2, panel_rect.Bottom );
899                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Bottom, panel_rect.Left, panel_rect.Bottom - 2 );
900                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Bottom - 2, panel_rect.Left, panel_rect.Top - 1 );
901                                                 break;
902                                                 
903                                                 // FIXME: the size of the tab page is to big to draw the upper inner white border
904                                         case TabAlignment.Right:
905                                                 // inner border...
906                                                 pen = ResPool.GetPen( Color.White );
907                                                 
908                                                 dc.DrawLine( pen, panel_rect.Left + 1, panel_rect.Top + 1, panel_rect.Left + 1, panel_rect.Bottom - 1 );
909                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top + 1 , panel_rect.Right - 2, panel_rect.Top + 1 );
910                                                 
911                                                 pen = ResPool.GetPen( tab_inner_border_color );
912                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Top + 1, panel_rect.Right - 2, panel_rect.Bottom - 2 );
913                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Bottom - 1, panel_rect.Left + 2, panel_rect.Bottom - 1 );
914                                                 
915                                                 // border
916                                                 pen = ResPool.GetPen( tab_border_color );
917                                                 
918                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top, panel_rect.Right - 1, panel_rect.Top );
919                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Top, panel_rect.Right - 1, panel_rect.Bottom );
920                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Bottom, panel_rect.Left + 2, panel_rect.Bottom );
921                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Bottom, panel_rect.Left, panel_rect.Bottom - 2 );
922                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Bottom - 2, panel_rect.Left, panel_rect.Top + 2 );
923                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Top + 2, panel_rect.Left + 2, panel_rect.Top );
924                                                 break;
925                                 }
926                         }
927                         
928                         if (tab.Alignment == TabAlignment.Top) {
929                                 for (int r = tab.TabPages.Count; r > 0; r--) {
930                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
931                                                 if (i == tab.SelectedIndex)
932                                                         continue;
933                                                 if (r != tab.TabPages [i].Row)
934                                                         continue;
935                                                 Rectangle rect = tab.GetTabRect (i);
936                                                 if (!rect.IntersectsWith (area))
937                                                         continue;
938                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
939                                         }
940                                 }
941                         } else {
942                                 for (int r = 0; r < tab.TabPages.Count; r++) {
943                                         for (int i = tab.SliderPos; i < tab.TabPages.Count; i++) {
944                                                 if (i == tab.SelectedIndex)
945                                                         continue;
946                                                 if (r != tab.TabPages [i].Row)
947                                                         continue;
948                                                 Rectangle rect = tab.GetTabRect (i);
949                                                 if (!rect.IntersectsWith (area))
950                                                         continue;
951                                                 DrawTab (dc, tab.TabPages [i], tab, rect, false);
952                                         }
953                                 }
954                         }
955                         
956                         if (tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos) {
957                                 Rectangle rect = tab.GetTabRect (tab.SelectedIndex);
958                                 if (rect.IntersectsWith (area))
959                                         DrawTab (dc, tab.TabPages [tab.SelectedIndex], tab, rect, true);
960                         }
961                         
962                         if (tab.ShowSlider) {
963                                 Rectangle right = TabControlGetRightScrollRect (tab);
964                                 Rectangle left = TabControlGetLeftScrollRect (tab);
965                                 CPDrawScrollButton (dc, right, ScrollButton.Right, tab.RightSliderState);
966                                 CPDrawScrollButton (dc, left, ScrollButton.Left, tab.LeftSliderState);
967                         }
968                 }
969                 
970                 protected virtual int DrawTab (Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected)
971                 {
972                         int FlatButtonSpacing = 8;
973                         Rectangle interior;
974                         int res = bounds.Width;
975                         
976                         if (page.BackColor != tab_selected_gradient_second_color)
977                                 page.BackColor = tab_selected_gradient_second_color;
978                         
979                         // we can't fill the background right away because the bounds might be adjusted if the tab is selected
980                         
981                         StringFormat string_format = new StringFormat ();
982                         
983                         if (tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons) {
984                                 dc.FillRectangle (ResPool.GetSolidBrush (tab_selected_gradient_second_color), bounds);
985                                 
986                                 // Separators
987                                 if (tab.Appearance == TabAppearance.FlatButtons) {
988                                         int width = bounds.Width;
989                                         bounds.Width += (FlatButtonSpacing - 2);
990                                         res = bounds.Width;
991                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Etched, Border3DSide.Right);
992                                         bounds.Width = width;
993                                 }
994                                 
995                                 if (is_selected) {
996                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
997                                 } else if (tab.Appearance != TabAppearance.FlatButtons) {
998                                         CPDrawBorder3D (dc, bounds, Border3DStyle.Raised, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom);
999                                 }
1000                                 
1001                                 interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 4, bounds.Height - 4);
1002                                 
1003                                 string_format.Alignment = StringAlignment.Center;
1004                                 string_format.LineAlignment = StringAlignment.Center;
1005                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
1006                         } else {
1007                                 Color tab_first_color = is_selected ? tab_selected_gradient_first_color : tab_not_selected_gradient_first_color;
1008                                 Color tab_second_color = is_selected ? tab_selected_gradient_second_color : tab_not_selected_gradient_second_color;
1009                                 
1010                                 switch (tab.Alignment) {
1011                                 case TabAlignment.Top:
1012                                         
1013                                         Rectangle tab_interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 2, bounds.Height - 3);
1014                                         
1015                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left + 2, bounds.Top + 2), new Point (bounds.Left + 2, bounds.Bottom), tab_first_color, tab_second_color)) {
1016                                                 dc.FillRectangle (lgbr, tab_interior);
1017                                         }
1018                                         
1019                                         // edges
1020                                         Pen tmp_pen = ResPool.GetPen (tab_edge_color);
1021                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Top + 1, bounds.Left + 1, bounds.Top);
1022                                         dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Top, bounds.Right, bounds.Top + 1);
1023                                         
1024                                         // inner border
1025                                         tmp_pen = ResPool.GetPen (Color.White);
1026                                         dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Bottom - 2, bounds.Left + 1, bounds.Top + 1);
1027                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top + 1, bounds.Right - 1, bounds.Top + 1);
1028                                         
1029                                         // border
1030                                         tmp_pen = ResPool.GetPen (border_pressed_dark_color);
1031                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Top + 2, bounds.Left + 2, bounds.Top);
1032                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top, bounds.Right - 2, bounds.Top);
1033                                         dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right, bounds.Top + 2);
1034                                         
1035                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left, bounds.Top + 2), new Point (bounds.Left, bounds.Bottom - 1), border_pressed_dark_color, border_pressed_light_color)) {
1036                                                 int diff = is_selected ? 3 : 2;
1037                                                 using (Pen lgbrpen = new Pen (lgbr)) {
1038                                                         dc.DrawLine (lgbrpen, bounds.Left, bounds.Top + 2, bounds.Left, bounds.Bottom - diff);
1039                                                         dc.DrawLine (lgbrpen, bounds.Right, bounds.Top + 2, bounds.Right, bounds.Bottom - diff);
1040                                                 }
1041                                         }
1042                                         
1043                                         if (page.Focused) {
1044                                                 tmp_pen = ResPool.GetPen (tab_focus_color);
1045                                                 dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Top  + 2, bounds.Right - 1, bounds.Top + 2);
1046                                                 dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top + 1, bounds.Right - 2, bounds.Top + 1);
1047                                                 
1048                                                 tmp_pen = ResPool.GetPen (tab_top_border_focus_color);
1049                                                 dc.DrawLine (tmp_pen, bounds.Left, bounds.Top + 2, bounds.Left + 2, bounds.Top);
1050                                                 dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top, bounds.Right - 2, bounds.Top);
1051                                                 dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right, bounds.Top + 2);
1052                                         }
1053                                         
1054                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
1055                                         
1056                                         string_format.Alignment = StringAlignment.Center;
1057                                         string_format.LineAlignment = StringAlignment.Center;
1058                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1059                                         
1060                                         break;
1061                                         
1062                                 case TabAlignment.Bottom:
1063                                         
1064                                         tab_interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 2, bounds.Height - 3);
1065                                         
1066                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left + 2, bounds.Top + 2), new Point (bounds.Left + 2, bounds.Bottom - 1), tab_first_color, tab_second_color)) {
1067                                                 dc.FillRectangle (lgbr, tab_interior);
1068                                         }
1069                                         
1070                                         // edges
1071                                         tmp_pen = ResPool.GetPen (tab_edge_color);
1072                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Bottom - 1, bounds.Left + 1, bounds.Bottom);
1073                                         dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Bottom, bounds.Right, bounds.Bottom - 1);
1074                                         
1075                                         // inner border
1076                                         tmp_pen = ResPool.GetPen (Color.White);
1077                                         dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Bottom - 2, bounds.Left + 1, bounds.Top + 2);
1078                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Bottom - 1, bounds.Right - 1, bounds.Bottom - 1);
1079                                         
1080                                         // border
1081                                         tmp_pen = ResPool.GetPen (border_pressed_dark_color);
1082                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Bottom - 2, bounds.Left + 2, bounds.Bottom);
1083                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Bottom, bounds.Right - 2, bounds.Bottom);
1084                                         dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Bottom, bounds.Right, bounds.Bottom - 2);
1085                                         
1086                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left, bounds.Top + 2), new Point (bounds.Left, bounds.Bottom - 1), border_pressed_light_color, border_pressed_dark_color)) {
1087                                                 int diff = is_selected ? 3 : 2;
1088                                                 using (Pen lgbrpen = new Pen (lgbr)) {
1089                                                         dc.DrawLine (lgbrpen, bounds.Left, bounds.Top + 2, bounds.Left, bounds.Bottom - 1 - diff);
1090                                                         dc.DrawLine (lgbrpen, bounds.Right, bounds.Top + 2, bounds.Left, bounds.Bottom - 1 - diff);
1091                                                 }
1092                                         }
1093                                         
1094                                         if (page.Focused) {
1095                                                 tmp_pen = ResPool.GetPen (tab_focus_color);
1096                                                 dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Bottom - 2, bounds.Right - 1, bounds.Bottom - 2);
1097                                                 dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom - 1);
1098                                                 
1099                                                 tmp_pen = ResPool.GetPen (tab_top_border_focus_color);
1100                                                 dc.DrawLine (tmp_pen, bounds.Left, bounds.Bottom - 2, bounds.Left + 2, bounds.Bottom);
1101                                                 dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Bottom, bounds.Right - 2, bounds.Bottom);
1102                                                 dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Bottom, bounds.Right, bounds.Bottom - 2);
1103                                         }
1104                                         
1105                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
1106                                         
1107                                         string_format.Alignment = StringAlignment.Center;
1108                                         string_format.LineAlignment = StringAlignment.Center;
1109                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1110                                         
1111                                         break;
1112                                         
1113                                 case TabAlignment.Left:
1114                                         
1115                                         int w_diff = is_selected ? 2 : 0;
1116                                         
1117                                         tab_interior = new Rectangle (bounds.Left + 2, bounds.Top + 2, bounds.Width - 2 - w_diff, bounds.Height - 2);
1118                                         
1119                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left + 2, bounds.Top + 2), new Point (bounds.Right - w_diff, bounds.Top + 2), tab_first_color, tab_second_color)) {
1120                                                 dc.FillRectangle (lgbr, tab_interior);
1121                                         }
1122                                         
1123                                         // edges
1124                                         tmp_pen = ResPool.GetPen (tab_edge_color);
1125                                         dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Top, bounds.Left, bounds.Top + 1);
1126                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Bottom - 1, bounds.Left + 1, bounds.Bottom);
1127                                         
1128                                         // inner border
1129                                         tmp_pen = ResPool.GetPen (Color.White);
1130                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top + 1, bounds.Right - 3, bounds.Top + 1);
1131                                         dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Top + 2, bounds.Left + 1, bounds.Bottom - 2);
1132                                         
1133                                         // border
1134                                         tmp_pen = ResPool.GetPen (border_pressed_dark_color);
1135                                         dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top, bounds.Left, bounds.Top + 2);
1136                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Top + 2, bounds.Left, bounds.Bottom - 2);
1137                                         dc.DrawLine (tmp_pen, bounds.Left, bounds.Bottom - 2, bounds.Left + 2, bounds.Bottom);
1138                                         
1139                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left, bounds.Top + 2), new Point (bounds.Right - 2, bounds.Top + 2), border_pressed_dark_color, border_pressed_light_color)) {
1140                                                 int diff = is_selected ? 3 : 1;
1141                                                 
1142                                                 using (Pen lgbrpen = new Pen (lgbr)) {
1143                                                         dc.DrawLine (lgbrpen, bounds.Left + 2, bounds.Top, bounds.Right - diff, bounds.Left + 2);
1144                                                         dc.DrawLine (lgbrpen, bounds.Left + 2, bounds.Bottom, bounds.Right - diff, bounds.Left + 2);
1145                                                 }
1146                                         }
1147                                         
1148                                         if (page.Focused) {
1149                                                 tmp_pen = ResPool.GetPen (tab_focus_color);
1150                                                 dc.DrawLine (tmp_pen, bounds.Left + 3, bounds.Top + 1, bounds.Left + 3, bounds.Bottom - 1);
1151                                                 dc.DrawLine (tmp_pen, bounds.Left + 2, bounds.Top + 2, bounds.Left + 2, bounds.Bottom - 2);
1152                                                 
1153                                                 tmp_pen = ResPool.GetPen (tab_top_border_focus_color);
1154                                                 dc.DrawLine (tmp_pen, bounds.Left + 3, bounds.Top, bounds.Left + 1, bounds.Top + 2);
1155                                                 dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Top + 2, bounds.Left + 1, bounds.Bottom - 2);
1156                                                 dc.DrawLine (tmp_pen, bounds.Left + 1, bounds.Bottom - 2, bounds.Left + 3, bounds.Bottom);
1157                                         }
1158                                         
1159                                         interior = new Rectangle (bounds.Left + 2, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
1160                                         
1161                                         string_format.Alignment = StringAlignment.Center;
1162                                         string_format.LineAlignment = StringAlignment.Center;
1163                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1164                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
1165                                         
1166                                         break;
1167                                         
1168                                 default:
1169                                         // TabAlignment.Right
1170                                         
1171                                         tab_interior = new Rectangle (bounds.Left, bounds.Top + 2, bounds.Width - 2, bounds.Height - 2);
1172                                         
1173                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left, bounds.Top + 2), new Point (bounds.Right, bounds.Top + 2), tab_second_color, tab_first_color)) {
1174                                                 dc.FillRectangle (lgbr, tab_interior);
1175                                         }
1176                                         
1177                                         int l_diff = is_selected ? 2 : 0;
1178                                         
1179                                         // edges
1180                                         tmp_pen = ResPool.GetPen (tab_edge_color);
1181                                         dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right - 1, bounds.Top + 1);
1182                                         dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom);
1183                                         
1184                                         // inner border
1185                                         tmp_pen = ResPool.GetPen (Color.White);
1186                                         dc.DrawLine (tmp_pen, bounds.Left + l_diff, bounds.Top + 1, bounds.Right - 2, bounds.Top + 1);
1187                                         dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Top + 2, bounds.Right - 2, bounds.Bottom - 2);
1188                                         
1189                                         // border
1190                                         tmp_pen = ResPool.GetPen (border_pressed_dark_color);
1191                                         dc.DrawLine (tmp_pen, bounds.Right - 3, bounds.Top, bounds.Right - 1, bounds.Top + 2);
1192                                         dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Top + 2, bounds.Right - 1, bounds.Bottom - 2);
1193                                         dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Bottom - 2, bounds.Right - 3, bounds.Bottom);
1194                                         
1195                                         using (LinearGradientBrush lgbr = new LinearGradientBrush (new Point (bounds.Left, bounds.Top + 2), new Point (bounds.Right - 2, bounds.Top + 2), border_pressed_light_color, border_pressed_dark_color)) {
1196                                                 int diff = is_selected ? 3 : 1;
1197                                                 
1198                                                 using (Pen lgbrpen = new Pen (lgbr)) {
1199                                                         dc.DrawLine (lgbrpen, bounds.Left + l_diff, bounds.Top, bounds.Right - diff, bounds.Top);
1200                                                         dc.DrawLine (lgbrpen, bounds.Left + l_diff, bounds.Bottom, bounds.Right - diff, bounds.Bottom);
1201                                                 }
1202                                         }
1203                                         
1204                                         if (page.Focused) {
1205                                                 tmp_pen = ResPool.GetPen (tab_focus_color);
1206                                                 dc.DrawLine (tmp_pen, bounds.Right - 3, bounds.Top + 1, bounds.Right - 3, bounds.Bottom - 1);
1207                                                 dc.DrawLine (tmp_pen, bounds.Right - 2, bounds.Top + 2, bounds.Right - 2, bounds.Bottom - 2);
1208                                                 
1209                                                 tmp_pen = ResPool.GetPen (tab_top_border_focus_color);
1210                                                 dc.DrawLine (tmp_pen, bounds.Right - 3, bounds.Top, bounds.Right - 1, bounds.Top + 2);
1211                                                 dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Top + 2, bounds.Right - 1, bounds.Bottom - 2);
1212                                                 dc.DrawLine (tmp_pen, bounds.Right - 1, bounds.Bottom - 2, bounds.Right - 3, bounds.Bottom);
1213                                         }
1214                                         
1215                                         interior = new Rectangle (bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8);
1216                                         
1217                                         string_format.Alignment = StringAlignment.Center;
1218                                         string_format.LineAlignment = StringAlignment.Center;
1219                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1220                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
1221                                         
1222                                         break;
1223                                 }
1224                         }
1225                         
1226                         if (tab.DrawMode == TabDrawMode.Normal && page.Text != null) {
1227                                 if (tab.Alignment == TabAlignment.Left) {
1228                                         int wo = interior.Width / 2;
1229                                         int ho = interior.Height / 2;
1230                                         dc.TranslateTransform (interior.X + wo, interior.Y + ho);
1231                                         dc.RotateTransform (180);
1232                                         dc.DrawString (page.Text, page.Font, ResPool.GetSolidBrush (SystemColors.ControlText), 0, 0, string_format);
1233                                         dc.ResetTransform ();
1234                                 } else {
1235                                         dc.DrawString (page.Text, page.Font,
1236                                                        ResPool.GetSolidBrush (SystemColors.ControlText),
1237                                                        interior, string_format);
1238                                 }
1239                         } else if (page.Text != null) {
1240                                 DrawItemState state = DrawItemState.None;
1241                                 if (page == tab.SelectedTab)
1242                                         state |= DrawItemState.Selected;
1243                                 DrawItemEventArgs e = new DrawItemEventArgs (dc,
1244                                                                              tab.Font, bounds, tab.IndexForTabPage (page),
1245                                                                              state, page.ForeColor, page.BackColor);
1246                                 tab.OnDrawItemInternal (e);
1247                                 return res;
1248                         }
1249                         
1250                         return res;
1251                 }               
1252                 
1253                 public override void CPDrawComboButton( Graphics dc, Rectangle rectangle, ButtonState state ) {
1254                         Point[]                 arrow = new Point[ 3 ];
1255                         Point                           P1;
1256                         Point                           P2;
1257                         Point                           P3;
1258                         int                             centerX;
1259                         int                             centerY;
1260                         int                             shiftX;
1261                         int                             shiftY;
1262                         Rectangle               rect;
1263                         
1264                         bool pushed = false;
1265                         
1266                         Color first_color = Color.White;
1267                         Color second_color = combobox_button_second_gradient_color;
1268                         
1269                         dc.FillRectangle( ResPool.GetSolidBrush( Color.White ), rectangle );
1270                         
1271                         if ( state == ButtonState.Pushed ) {
1272                                 first_color = pressed_gradient_first_color;
1273                                 second_color = pressed_gradient_second_color;
1274                                 pushed = true;
1275                         }
1276                         
1277                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( rectangle.X, rectangle.Y + 2 ), new Point( rectangle.X, rectangle.Bottom - 2 ), first_color, second_color ) ) {
1278                                 dc.FillRectangle( lgbr, rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4 );
1279                         }
1280                         
1281                         // inner borders
1282                         Pen tmp_pen = ResPool.GetPen( !pushed ? Color.White : pressed_inner_border_dark_color );
1283                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 1, rectangle.Right - 2, rectangle.Y + 1 );
1284                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 1, rectangle.X + 1, rectangle.Bottom - 2 );
1285                         
1286                         tmp_pen = ResPool.GetPen( !pushed ? inner_border_dark_color : pressed_inner_border_dark_color  );
1287                         dc.DrawLine( tmp_pen, rectangle.Right - 2, rectangle.Y + 2, rectangle.Right - 2, rectangle.Bottom - 2 );
1288                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 2 );
1289                         
1290                         // border
1291                         Point[] points = new Point[] {
1292                                 new Point( rectangle.X, rectangle.Y ),
1293                                 new Point( rectangle.Right - 3, rectangle.Y ),
1294                                 new Point( rectangle.Right - 1, rectangle.Y + 2 ),
1295                                 new Point( rectangle.Right - 1, rectangle.Bottom - 3 ),
1296                                 new Point( rectangle.Right - 3, rectangle.Bottom - 1 ),
1297                                 new Point( rectangle.X, rectangle.Bottom - 1 ),
1298                                 new Point( rectangle.X, rectangle.Y )
1299                         };
1300                         
1301                         dc.DrawPolygon( ResPool.GetPen( pushed ? border_pressed_dark_color : border_normal_dark_color ), points );
1302                         
1303                         // edges on right side
1304                         tmp_pen = ResPool.GetPen( control_parent_backcolor );
1305                         dc.DrawLine( tmp_pen, rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Y + 1 );
1306                         dc.DrawLine( tmp_pen, rectangle.Right - 1, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 2 );
1307                         
1308                         tmp_pen = ResPool.GetPen( edge_bottom_inner_color );
1309                         dc.DrawLine( tmp_pen, rectangle.Right - 2, rectangle.Y, rectangle.Right - 1, rectangle.Y + 1 );
1310                         dc.DrawLine( tmp_pen, rectangle.Right - 2, rectangle.Bottom - 1, rectangle.Right - 1, rectangle.Bottom - 2 );
1311                         
1312                         rect = new Rectangle( rectangle.X + 1 + rectangle.Width / 4, rectangle.Y + rectangle.Height / 4, rectangle.Width / 2 - 1, rectangle.Height / 2 );
1313                         centerX = rect.Left + rect.Width / 2;
1314                         centerY = rect.Top + rect.Height / 2;
1315                         shiftX = Math.Max( 1, rect.Width / 8 );
1316                         shiftY = Math.Max( 1, rect.Height / 8 );
1317                         
1318                         if ( ( state & ButtonState.Pushed ) != 0 ) {
1319                                 shiftX--;
1320                                 shiftY--;
1321                         }
1322                         
1323                         rect.Y -= shiftY;
1324                         centerY -= shiftY;
1325                         
1326                         P1 = new Point( rect.Left, centerY );
1327                         P2 = new Point( centerX, rect.Bottom );
1328                         P3 = new Point( rect.Right - 1, centerY );
1329                         
1330                         arrow[ 0 ] = P1;
1331                         arrow[ 1 ] = P2;
1332                         arrow[ 2 ] = P3;
1333                         
1334                         SmoothingMode old_smoothing_mode = dc.SmoothingMode;
1335                         dc.SmoothingMode = SmoothingMode.AntiAlias;
1336                         
1337                         /* Draw the arrow */
1338                         if ( state == ButtonState.Inactive ) {
1339                                 /* Move away from the shadow */
1340                                 P1.X += 1;              P1.Y += 1;
1341                                 P2.X += 1;              P2.Y += 1;
1342                                 P3.X += 1;              P3.Y += 1;
1343                                 
1344                                 arrow[ 0 ] = P1;
1345                                 arrow[ 1 ] = P2;
1346                                 arrow[ 2 ] = P3;
1347                                 
1348                                 using ( Pen pen = new Pen( SystemColors.ControlLightLight, 2 ) ) {
1349                                         dc.DrawLines( pen, arrow );
1350                                 }
1351                                 
1352                                 P1 = new Point( rect.Left, centerY );
1353                                 P2 = new Point( centerX, rect.Bottom );
1354                                 P3 = new Point( rect.Right - 1, centerY );
1355                                 
1356                                 arrow[ 0 ] = P1;
1357                                 arrow[ 1 ] = P2;
1358                                 arrow[ 2 ] = P3;
1359                                 
1360                                 using ( Pen pen = new Pen( SystemColors.ControlDark, 2 ) ) {
1361                                         dc.DrawLines( pen, arrow );
1362                                 }
1363                         } else {
1364                                 using ( Pen pen = new Pen( SystemColors.ControlText, 2 ) ) {
1365                                         dc.DrawLines( pen, arrow );
1366                                 }
1367                         }
1368                         
1369                         dc.SmoothingMode = old_smoothing_mode;
1370                 }
1371                 
1372                 /* Scroll button: regular button + direction arrow */
1373                 public override void CPDrawScrollButton( Graphics dc, Rectangle area, ScrollButton scroll_button_type, ButtonState state ) {
1374                         bool enabled = ( state == ButtonState.Inactive ) ? false: true;
1375                         
1376                         DrawScrollButtonPrimitive( dc, area, state, scroll_button_type );
1377                         
1378                         Color color_arrow;
1379                         
1380                         if ( enabled )
1381                                 color_arrow = arrow_color;
1382                         else
1383                                 color_arrow = ColorGrayText;
1384                         
1385                         /* Paint arrows */
1386                         
1387                         int centerX = area.Left + area.Width / 2;
1388                         int centerY = area.Top + area.Height / 2;
1389                         
1390                         int shift = 0;
1391                         
1392                         if ( ( state & ButtonState.Pushed ) != 0 )
1393                                 shift = 1;
1394                         
1395                         int min_4 = 4;
1396                         int min_2 = 2;
1397                         if ( area.Width < 12 || area.Height < 12 ) {
1398                                 min_4 = 3;
1399                                 min_2 = 1;
1400                         }
1401                         
1402                         Point[] arrow = new Point[ 4 ];
1403                         
1404                         switch (scroll_button_type) {
1405                         case ScrollButton.Down:
1406                                 centerY += shift + 1;
1407                                 arrow [0] = new Point (centerX - min_4, centerY - min_2);
1408                                 arrow [1] = new Point (centerX, centerY + min_2);
1409                                 arrow [2] = new Point (centerX + min_4, centerY - min_2);
1410                                 arrow [3] = new Point (centerX - min_4, centerY - min_2);
1411                                 break;
1412                         case ScrollButton.Up:
1413                                 centerY -= shift;
1414                                 arrow [0] = new Point (centerX - min_4, centerY + min_2);
1415                                 arrow [1] = new Point (centerX, centerY - min_2);
1416                                 arrow [2] = new Point (centerX + min_4, centerY + min_2);
1417                                 arrow [3] = new Point (centerX - min_4, centerY + min_2);
1418                                 break;
1419                         case ScrollButton.Left:
1420                                 centerX -= shift;
1421                                 arrow [0] = new Point (centerX + min_2, centerY - min_4);
1422                                 arrow [1] = new Point (centerX + min_2, centerY + min_4);
1423                                 arrow [2] = new Point (centerX - min_2, centerY);
1424                                 arrow [3] = new Point (centerX + min_2, centerY - min_4);
1425                                 break;
1426                         case ScrollButton.Right:
1427                                 centerX += shift + 1;
1428                                 arrow [0] = new Point (centerX - min_2, centerY - min_4);
1429                                 arrow [1] = new Point (centerX + min_2, centerY);
1430                                 arrow [2] = new Point (centerX - min_2, centerY + min_4);
1431                                 arrow [3] = new Point (centerX - min_2, centerY - min_4);
1432                                 break;
1433                         default:
1434                                 break;
1435                         }
1436                         
1437                         SmoothingMode old_smoothing_mode = dc.SmoothingMode;
1438                         dc.SmoothingMode = SmoothingMode.AntiAlias;
1439                         dc.FillPolygon( ResPool.GetSolidBrush( color_arrow ), arrow );
1440                         dc.SmoothingMode = old_smoothing_mode;
1441                 }
1442                 
1443                 public override void CPDrawSizeGrip( Graphics dc, Color backColor, Rectangle bounds ) {
1444                         Point pt1 = new Point( bounds.Right - 3, bounds.Bottom );
1445                         Point pt2 = new Point( bounds.Right, bounds.Bottom - 3 );
1446                         
1447                         // diagonals
1448                         Pen tmp_pen = ResPool.GetPen( Color.White );
1449                         for ( int i = 0; i < 4; i++ ) {
1450                                 dc.DrawLine( tmp_pen, pt1.X - i * 4, pt1.Y, pt2.X, pt2.Y - i * 4 );
1451                         }
1452                         
1453                         pt1.X += 1;
1454                         pt2.Y += 1;
1455                         
1456                         tmp_pen = ResPool.GetPen( pressed_inner_border_dark_color );
1457                         for ( int i = 0; i < 4; i++ ) {
1458                                 dc.DrawLine( tmp_pen, pt1.X - i * 4, pt1.Y, pt2.X, pt2.Y - i * 4 );
1459                         }
1460                 }
1461                 
1462                 private void DrawScrollBarThumb( Graphics dc, Rectangle area, ScrollBar bar ) {
1463                         LinearGradientBrush lgbr = null;
1464                         
1465                         if ( bar.vert )
1466                                 lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y + 2 ), new Point( area.Right - 2, area.Y + 2 ), scrollbar_gradient_first_color, scrollbar_gradient_second_color );
1467                         else
1468                                 lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y + 2 ), new Point( area.X + 2, area.Bottom - 2 ), scrollbar_gradient_first_color, scrollbar_gradient_second_color );
1469                         
1470                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1471                         
1472                         lgbr.Dispose( );
1473                         
1474                         // outer border
1475                         Pen pen = ResPool.GetPen( border_normal_dark_color );
1476                         
1477                         dc.DrawRectangle( pen, area.X, area.Y, area.Width - 1, area.Height - 1 );
1478                         
1479                         // inner border
1480                         pen = ResPool.GetPen( Color.White );
1481                         dc.DrawLine( pen, area.X + 1, area.Bottom - 2, area.X + 1, area.Y + 1 );
1482                         dc.DrawLine( pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1483                         
1484                         pen = ResPool.GetPen( inner_border_dark_color );
1485                         dc.DrawLine( pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1486                         dc.DrawLine( pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1487                         
1488                         if ( bar.vert ) {
1489                                 if ( area.Height > 12 ) {
1490                                         int mid_y = area.Y + ( area.Height / 2 );
1491                                         int mid_x = area.X + ( area.Width / 2 );
1492                                         
1493                                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1494                                         dc.DrawLine( pen, mid_x - 3, mid_y, mid_x + 3, mid_y );
1495                                         dc.DrawLine( pen, mid_x - 3, mid_y - 3, mid_x + 3, mid_y - 3 );
1496                                         dc.DrawLine( pen, mid_x - 3, mid_y + 3, mid_x + 3, mid_y + 3 );
1497                                         
1498                                         Pen spen = ResPool.GetPen( Color.White );
1499                                         dc.DrawLine( spen, mid_x - 3, mid_y + 1, mid_x + 3, mid_y + 1 );
1500                                         dc.DrawLine( spen, mid_x - 3, mid_y - 2, mid_x + 3, mid_y - 2 );
1501                                         dc.DrawLine( spen, mid_x - 3, mid_y + 4, mid_x + 3, mid_y + 4 );
1502                                 }
1503                         } else {
1504                                 // draw grip lines only if there is enough space
1505                                 if ( area.Width > 12 ) {
1506                                         int mid_x = area.X +  ( area.Width / 2 );
1507                                         int mid_y = area.Y +  ( area.Height / 2 );
1508                                         
1509                                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1510                                         dc.DrawLine( pen, mid_x, mid_y - 3, mid_x, mid_y + 3 );
1511                                         dc.DrawLine( pen, mid_x - 3, mid_y - 3, mid_x - 3, mid_y + 3 );
1512                                         dc.DrawLine( pen, mid_x + 3, mid_y - 3, mid_x + 3, mid_y + 3 );
1513                                         
1514                                         Pen spen = ResPool.GetPen( Color.White );
1515                                         dc.DrawLine( spen, mid_x + 1, mid_y - 3, mid_x + 1, mid_y + 3 );
1516                                         dc.DrawLine( spen, mid_x - 2, mid_y - 3, mid_x - 2, mid_y + 3 );
1517                                         dc.DrawLine( spen, mid_x + 4, mid_y - 3, mid_x + 4, mid_y + 3 );
1518                                 }
1519                         }
1520                 }
1521                 
1522                 public void DrawScrollButtonPrimitive( Graphics dc, Rectangle area, ButtonState state, ScrollButton scroll_button_type ) {
1523                         Pen pen = ResPool.GetPen( border_normal_dark_color );
1524                         
1525                         Color first_gradient_color = gradient_first_color; 
1526                         Color second_gradient_color = gradient_second_color_nr2;
1527                         
1528                         bool pushed = false;
1529                         
1530                         if ( ( state & ButtonState.Pushed ) == ButtonState.Pushed ) {
1531                                 first_gradient_color = pressed_gradient_first_color;
1532                                 second_gradient_color = pressed_gradient_second_color;
1533                                 pushed = true;
1534                         }
1535                         
1536                         Point[] points = null;
1537                         
1538                         LinearGradientBrush lgbr = null;
1539                         
1540                         switch ( scroll_button_type ) {
1541                                 case ScrollButton.Left:
1542                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1543                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Y, area.X, area.Bottom - 1 );
1544                                         
1545                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y + 2 ), new Point( area.X + 2, area.Bottom - 2 ), first_gradient_color, second_gradient_color );
1546                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 2 );
1547                                         
1548                                         Pen tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1549                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 2, area.X + 1, area.Bottom - 2 );
1550                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1551                                         
1552                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1553                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1554                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1555                                         
1556                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1557                                         dc.DrawLine( tmp_pen, area.X, area.Y + 1, area.X + 1, area.Y );
1558                                         dc.DrawLine( tmp_pen, area.X, area.Bottom - 2, area.X + 1, area.Bottom - 1 );
1559                                         
1560                                         points = new Point[] {
1561                                                 new Point( area.X + 2, area.Y ),
1562                                                 new Point( area.Right - 1, area.Y ),
1563                                                 new Point( area.Right - 1, area.Bottom - 1 ),
1564                                                 new Point( area.X + 2, area.Bottom - 1 ),
1565                                                 new Point( area.X, area.Bottom - 3 ),
1566                                                 new Point( area.X, area.Y + 2 ),
1567                                                 new Point( area.X + 2, area.Y )
1568                                         };
1569                                         dc.DrawPolygon( pen, points );
1570                                         break;
1571                                 case ScrollButton.Right:
1572                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1573                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.Right - 1, area.Y, area.Right - 1, area.Bottom - 1 );
1574                                         
1575                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y + 2 ), new Point( area.X + 2, area.Bottom - 2 ), first_gradient_color, second_gradient_color );
1576                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 2 );
1577                                         
1578                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1579                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1580                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1581                                         
1582                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1583                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1584                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1585                                         
1586                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1587                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y, area.Right - 1, area.Y + 1 );
1588                                         dc.DrawLine( tmp_pen, area.Right - 1, area.Bottom - 2, area.Right - 2, area.Bottom - 1 );
1589                                         
1590                                         points = new Point[] {
1591                                                 new Point( area.X, area.Y ),
1592                                                 new Point( area.Right - 3, area.Y ),
1593                                                 new Point( area.Right - 1, area.Y + 2 ),
1594                                                 new Point( area.Right - 1, area.Bottom - 3 ),
1595                                                 new Point( area.Right - 3, area.Bottom - 1 ),
1596                                                 new Point( area.X, area.Bottom - 1 ),
1597                                                 new Point( area.X, area.Y ),
1598                                         };
1599                                         dc.DrawPolygon( pen, points );
1600                                         break;
1601                                 case ScrollButton.Up:
1602                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1603                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Y, area.Right - 1, area.Y );
1604                                         
1605                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y ), new Point( area.Right - 2, area.Y ), first_gradient_color, second_gradient_color );
1606                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1607                                         
1608                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1609                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1610                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1611                                         
1612                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1613                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1614                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1615                                         
1616                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1617                                         dc.DrawLine( tmp_pen, area.X, area.Y + 1, area.X + 1, area.Y );
1618                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y, area.Right - 1, area.Y + 1 );
1619                                         
1620                                         points = new Point[] {
1621                                                 new Point( area.X + 2, area.Y ),
1622                                                 new Point( area.Right - 3, area.Y ),
1623                                                 new Point( area.Right - 1, area.Y + 2 ),
1624                                                 new Point( area.Right - 1, area.Bottom - 1 ),
1625                                                 new Point( area.X, area.Bottom - 1 ),
1626                                                 new Point( area.X, area.Y + 2 ),
1627                                                 new Point( area.X + 2, area.Y )
1628                                         };
1629                                         dc.DrawPolygon( pen, points );
1630                                         break;
1631                                 case ScrollButton.Down:
1632                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1633                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Bottom - 1, area.Right - 1, area.Bottom - 1 );
1634                                         
1635                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y ), new Point( area.Right - 2, area.Y ), first_gradient_color, second_gradient_color );
1636                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1637                                         
1638                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1639                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1640                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1641                                         
1642                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1643                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1644                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1645                                         
1646                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1647                                         dc.DrawLine( tmp_pen, area.X, area.Bottom - 2, area.X + 1, area.Bottom - 1 );
1648                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Bottom - 1, area.Right - 1, area.Bottom - 2 );
1649                                         
1650                                         points = new Point[] {
1651                                                 new Point( area.X, area.Y ),
1652                                                 new Point( area.Right - 1, area.Y ),
1653                                                 new Point( area.Right - 1, area.Bottom - 3 ),
1654                                                 new Point( area.Right - 3, area.Bottom - 1 ),
1655                                                 new Point( area.X + 2, area.Bottom - 1 ),
1656                                                 new Point( area.X, area.Bottom - 3 ),
1657                                                 new Point( area.X, area.Y )
1658                                         };
1659                                         dc.DrawPolygon( pen, points );
1660                                         break;
1661                         }
1662                         
1663                         lgbr.Dispose( );
1664                 }
1665                 
1666                 #region ToolBar
1667
1668                 #endregion // ToolBar
1669
1670                 #region GroupBox
1671                 public override void DrawGroupBox( Graphics dc,  Rectangle area, GroupBox box ) {
1672                         StringFormat    text_format;
1673                         SizeF           size;
1674                         int             width;
1675                         int             y;
1676                         Rectangle       rect;
1677                         
1678                         rect = box.ClientRectangle;
1679                         
1680                         dc.FillRectangle( ResPool.GetSolidBrush( box.BackColor ), rect );
1681                         
1682                         text_format = new StringFormat( );
1683                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
1684                         
1685                         size = dc.MeasureString( box.Text, box.Font );
1686                         width = (int) size.Width;
1687                         
1688                         if ( width > box.Width - 16 )
1689                                 width = box.Width - 16;
1690                         
1691                         y = box.Font.Height / 2;
1692                         
1693                         Pen pen = ResPool.GetPen( pressed_inner_border_dark_color );
1694                         
1695                         /* Draw group box*/
1696                         Point[] points = {
1697                                 new Point( 8 + width, y ),
1698                                 new Point( box.Width - 3, y ),
1699                                 new Point( box.Width - 1, y + 2 ),
1700                                 new Point( box.Width - 1, box.Height - 3 ),
1701                                 new Point( box.Width - 3, box.Height - 1 ),
1702                                 new Point( 2, box.Height - 1 ),
1703                                 new Point( 0, box.Height - 3 ),
1704                                 new Point( 0, y + 2 ),
1705                                 new Point( 2, y ),
1706                                 new Point( 8, y )
1707                         };
1708                         dc.DrawLines( pen, points );
1709                         
1710                         /* Text */
1711                         if ( box.Enabled ) {
1712                                 dc.DrawString( box.Text, box.Font, ResPool.GetSolidBrush( box.ForeColor ), 10, 0, text_format );
1713                         } else {
1714                                 CPDrawStringDisabled( dc, box.Text, box.Font, box.ForeColor, 
1715                                                      new RectangleF( 10, 0, width,  box.Font.Height ), text_format );
1716                         }
1717                         text_format.Dispose( ); 
1718                 }
1719                 #endregion
1720                 
1721                 #region TrackBar
1722                 private void DrawTrackBar_Vertical( Graphics dc, Rectangle clip_rectangle, TrackBar tb,
1723                                                    ref Rectangle thumb_pos, ref Rectangle thumb_area,
1724                                                    float ticks, int value_pos, bool mouse_value ) {                     
1725                         
1726                         Point toptick_startpoint = new Point( );
1727                         Point bottomtick_startpoint = new Point( );
1728                         Point channel_startpoint = new Point( );
1729                         float pixel_len;
1730                         float pixels_betweenticks;
1731                         const int space_from_right = 8;
1732                         const int space_from_left = 8;
1733                         Rectangle area = tb.ClientRectangle;
1734                         
1735                         switch ( tb.TickStyle )         {
1736                                 case TickStyle.BottomRight:
1737                                 case TickStyle.None:
1738                                         channel_startpoint.Y = 8;
1739                                         channel_startpoint.X = 9;
1740                                         bottomtick_startpoint.Y = 13;
1741                                         bottomtick_startpoint.X = 24;                           
1742                                         break;
1743                                 case TickStyle.TopLeft:
1744                                         channel_startpoint.Y = 8;
1745                                         channel_startpoint.X = 19;
1746                                         toptick_startpoint.Y = 13;
1747                                         toptick_startpoint.X = 8;
1748                                         break;
1749                                 case TickStyle.Both:
1750                                         channel_startpoint.Y = 8;
1751                                         channel_startpoint.X = 18;      
1752                                         bottomtick_startpoint.Y = 13;
1753                                         bottomtick_startpoint.X = 32;                           
1754                                         toptick_startpoint.Y = 13;
1755                                         toptick_startpoint.X = 8;                               
1756                                         break;
1757                                 default:
1758                                         break;
1759                         }
1760                         
1761                         thumb_area.X = area.X + channel_startpoint.X;
1762                         thumb_area.Y = area.Y + channel_startpoint.Y;
1763                         thumb_area.Height = area.Height - space_from_right - space_from_left;
1764                         thumb_area.Width = 4;
1765                         
1766                         pixel_len = thumb_area.Height - 11;
1767                         pixels_betweenticks = pixel_len / ( tb.Maximum - tb.Minimum );
1768                         
1769                         /* Convert thumb position from mouse position to value*/
1770                         if ( mouse_value ) {
1771                                 
1772                                 if ( value_pos >= channel_startpoint.Y )
1773                                         value_pos = (int)( ( (float) ( value_pos - channel_startpoint.Y ) ) / pixels_betweenticks );
1774                                 else
1775                                         value_pos = 0;                  
1776                                 
1777                                 if ( value_pos + tb.Minimum > tb.Maximum )
1778                                         value_pos = tb.Maximum - tb.Minimum;
1779                                 
1780                                 tb.Value = value_pos + tb.Minimum;
1781                         }               
1782                         
1783                         thumb_pos.Width = 13;
1784                         thumb_pos.Height = 29;
1785                         
1786                         thumb_pos.Y = channel_startpoint.Y + (int) ( pixels_betweenticks * (float) value_pos ) - ( thumb_pos.Height / 3 );
1787                         
1788                         if ( thumb_pos.Y < channel_startpoint.Y )
1789                                 thumb_pos.Y = channel_startpoint.Y;
1790                         
1791                         if ( thumb_pos.Y > thumb_area.Bottom - 29 )
1792                                 thumb_pos.Y = thumb_area.Bottom - 29;
1793                         
1794                         /* Draw channel */
1795                         // bottom
1796                         Pen pen = ResPool.GetPen( tab_top_border_focus_color );
1797                         dc.DrawLine( pen, channel_startpoint.X, thumb_pos.Y + 29, channel_startpoint.X, thumb_area.Bottom );
1798                         dc.DrawLine( pen, channel_startpoint.X, thumb_area.Bottom, channel_startpoint.X + 4, thumb_area.Bottom );
1799                         dc.DrawLine( pen, channel_startpoint.X + 4, thumb_pos.Y + 29, channel_startpoint.X + 4, thumb_area.Bottom );
1800                         
1801                         pen = ResPool.GetPen( menuitem_gradient_first_color );
1802                         dc.DrawLine( pen, channel_startpoint.X + 1, thumb_pos.Y + 28, channel_startpoint.X + 1, thumb_area.Bottom - 1 );
1803                         pen = ResPool.GetPen( trackbar_second_gradient_color );
1804                         dc.DrawLine( pen, channel_startpoint.X + 2, thumb_pos.Y + 28, channel_startpoint.X + 2, thumb_area.Bottom - 1 );
1805                         pen = ResPool.GetPen( trackbar_third_gradient_color );
1806                         dc.DrawLine( pen, channel_startpoint.X + 3, thumb_pos.Y + 28, channel_startpoint.X + 3, thumb_area.Bottom - 1 );
1807                         
1808                         // top
1809                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1810                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 1, channel_startpoint.X + 1, thumb_pos.Y );
1811                         dc.DrawRectangle( ResPool.GetPen( scrollbar_background_color ), channel_startpoint.X + 2, channel_startpoint.Y + 1, 1, thumb_pos.Y );
1812                         
1813                         pen = ResPool.GetPen( scrollbar_border_color );
1814                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X, thumb_pos.Y );
1815                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X + 4, channel_startpoint.Y );
1816                         dc.DrawLine( pen, channel_startpoint.X + 4, channel_startpoint.Y, channel_startpoint.X + 4, thumb_pos.Y );
1817                         
1818                         /* Draw thumb */
1819                         thumb_pos.X = channel_startpoint.X - 4;
1820                         
1821                         // inner border
1822                         pen = ResPool.GetPen( Color.White );
1823                         dc.DrawLine( pen, thumb_pos.X + 1, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Bottom - 2 );
1824                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Y + 1, thumb_pos.Right - 2, thumb_pos.Y + 1 );
1825                         
1826                         pen = ResPool.GetPen( menu_separator_color );
1827                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
1828                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y + 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
1829                         
1830                         // outer border
1831                         Point[] points = {
1832                                 new Point( thumb_pos.X + 2, thumb_pos.Y ),
1833                                 new Point( thumb_pos.Right - 3 , thumb_pos.Y ),
1834                                 new Point( thumb_pos.Right - 1, thumb_pos.Y + 2 ),
1835                                 new Point( thumb_pos.Right - 1, thumb_pos.Bottom - 3 ),
1836                                 new Point( thumb_pos.Right - 3, thumb_pos.Bottom - 1 ),
1837                                 new Point( thumb_pos.X + 2, thumb_pos.Bottom - 1 ),
1838                                 new Point( thumb_pos.X, thumb_pos.Bottom - 3 ),
1839                                 new Point( thumb_pos.X, thumb_pos.Y + 2 ),
1840                                 new Point( thumb_pos.X + 2, thumb_pos.Y )
1841                         };
1842                         
1843                         dc.DrawLines( ResPool.GetPen( border_normal_dark_color ), points );
1844                         
1845                         Color first_gradient_color = mouse_value ? button_edge_bottom_outer_color : trackbar_inner_first_gradient_color;
1846                         Color second_gradient_color = mouse_value ? trackbar_inner_pressed_second_gradient_color : trackbar_inner_second_gradient_color;
1847                         
1848                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( thumb_pos.X, thumb_pos.Y + 2 ), new Point( thumb_pos.X, thumb_pos.Bottom - 2 ), first_gradient_color, second_gradient_color ) ) {
1849                                 dc.FillRectangle( lgbr, thumb_pos.X + 2, thumb_pos.Y + 2, thumb_pos.Width - 4, thumb_pos.Height - 4 );
1850                         }
1851                         
1852                         // outer egdes
1853                         pen = ResPool.GetPen( edge_top_inner_color );
1854                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Y );
1855                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y, thumb_pos.Right - 1, thumb_pos.Y + 1 );
1856                         
1857                         pen = ResPool.GetPen( edge_bottom_inner_color );
1858                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Bottom - 2, thumb_pos.X + 1, thumb_pos.Bottom - 1 );
1859                         dc.DrawLine( pen, thumb_pos.Right - 1, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 1 );
1860                         
1861                         // draw grip lines
1862                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1863                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 11, thumb_pos.X + 8, thumb_pos.Y + 11 );
1864                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 14, thumb_pos.X + 8, thumb_pos.Y + 14 );
1865                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 17, thumb_pos.X + 8, thumb_pos.Y + 17 );
1866                         
1867                         pen = ResPool.GetPen( Color.White );
1868                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 12, thumb_pos.X + 8, thumb_pos.Y + 12 );
1869                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 15, thumb_pos.X + 8, thumb_pos.Y + 15 );
1870                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 18, thumb_pos.X + 8, thumb_pos.Y + 18 );
1871                         
1872                         pixel_len = thumb_area.Height - 11;
1873                         pixels_betweenticks = pixel_len / ticks;
1874                         
1875                         /* Draw ticks*/
1876                         thumb_area.X = thumb_pos.X;
1877                         thumb_area.Y = channel_startpoint.Y;
1878                         thumb_area.Width = thumb_pos.Width;
1879                         
1880                         Region outside = new Region( area );
1881                         outside.Exclude( thumb_area );                  
1882                         
1883                         if ( outside.IsVisible( clip_rectangle ) ) {                            
1884                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.BottomRight ) == TickStyle.BottomRight ||
1885                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {       
1886                                         
1887                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks )      {                                       
1888                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
1889                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
1890                                                                     area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc );
1891                                                 else
1892                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
1893                                                                     area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc );
1894                                         }
1895                                 }
1896                                 
1897                                 if ( pixels_betweenticks > 0 &&  ( ( tb.TickStyle & TickStyle.TopLeft ) == TickStyle.TopLeft ||
1898                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {
1899                                         
1900                                         pixel_len = thumb_area.Height - 11;
1901                                         pixels_betweenticks = pixel_len / ticks;
1902                                         
1903                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
1904                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
1905                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
1906                                                                     area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc );
1907                                                 else
1908                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
1909                                                                     area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc );
1910                                         }                       
1911                                 }
1912                         }
1913                         
1914                         outside.Dispose( );
1915                         
1916                 }
1917                 
1918                 private void DrawTrackBar_Horizontal( Graphics dc, Rectangle clip_rectangle, TrackBar tb,
1919                                                      ref Rectangle thumb_pos, ref Rectangle thumb_area,
1920                                                      float ticks, int value_pos, bool mouse_value ) {                   
1921                         Point toptick_startpoint = new Point( );
1922                         Point bottomtick_startpoint = new Point( );
1923                         Point channel_startpoint = new Point( );
1924                         float pixel_len;
1925                         float pixels_betweenticks;
1926                         const int space_from_right = 8;
1927                         const int space_from_left = 8;
1928                         Rectangle area = tb.ClientRectangle;
1929                         
1930                         switch ( tb.TickStyle ) {
1931                                 case TickStyle.BottomRight:
1932                                 case TickStyle.None:
1933                                         channel_startpoint.X = 8;
1934                                         channel_startpoint.Y = 9;
1935                                         bottomtick_startpoint.X = 13;
1936                                         bottomtick_startpoint.Y = 24;                           
1937                                         break;
1938                                 case TickStyle.TopLeft:
1939                                         channel_startpoint.X = 8;
1940                                         channel_startpoint.Y = 19;
1941                                         toptick_startpoint.X = 13;
1942                                         toptick_startpoint.Y = 8;
1943                                         break;
1944                                 case TickStyle.Both:
1945                                         channel_startpoint.X = 8;
1946                                         channel_startpoint.Y = 18;      
1947                                         bottomtick_startpoint.X = 13;
1948                                         bottomtick_startpoint.Y = 32;                           
1949                                         toptick_startpoint.X = 13;
1950                                         toptick_startpoint.Y = 8;                               
1951                                         break;
1952                                 default:
1953                                         break;
1954                         }
1955                         
1956                         thumb_area.X = area.X + channel_startpoint.X;
1957                         thumb_area.Y = area.Y + channel_startpoint.Y;
1958                         thumb_area.Width = area.Width - space_from_right - space_from_left;
1959                         thumb_area.Height = 4;
1960                         
1961                         pixel_len = thumb_area.Width - 11;
1962                         pixels_betweenticks = pixel_len / ( tb.Maximum - tb.Minimum );
1963                         
1964                         /* Convert thumb position from mouse position to value*/
1965                         if ( mouse_value ) {                    
1966                                 if ( value_pos >= channel_startpoint.X )
1967                                         value_pos = (int)( ( (float) ( value_pos - channel_startpoint.X ) ) / pixels_betweenticks );
1968                                 else
1969                                         value_pos = 0;                          
1970                                 
1971                                 if ( value_pos + tb.Minimum > tb.Maximum )
1972                                         value_pos = tb.Maximum - tb.Minimum;
1973                                 
1974                                 tb.Value = value_pos + tb.Minimum;
1975                         }                       
1976                         
1977                         thumb_pos.Width = 29;
1978                         thumb_pos.Height = 13;
1979                         
1980                         thumb_pos.X = channel_startpoint.X + (int) ( pixels_betweenticks * (float) value_pos ) - ( thumb_pos.Width / 3 );
1981                         
1982                         if ( thumb_pos.X < channel_startpoint.X )
1983                                 thumb_pos.X = channel_startpoint.X;
1984                         
1985                         if ( thumb_pos.X > thumb_area.Right - 29 )
1986                                 thumb_pos.X = thumb_area.Right - 29;
1987                         
1988                         /* Draw channel */
1989                         // left side
1990                         Pen pen = ResPool.GetPen( tab_top_border_focus_color );
1991                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, thumb_pos.X, channel_startpoint.Y );
1992                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X, channel_startpoint.Y + 4 );
1993                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y + 4, thumb_pos.X, channel_startpoint.Y + 4 );
1994                         
1995                         pen = ResPool.GetPen( menuitem_gradient_first_color );
1996                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 1, thumb_pos.X, channel_startpoint.Y + 1 );
1997                         pen = ResPool.GetPen( trackbar_second_gradient_color );
1998                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 2, thumb_pos.X, channel_startpoint.Y + 2 );
1999                         pen = ResPool.GetPen( trackbar_third_gradient_color );
2000                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 3, thumb_pos.X, channel_startpoint.Y + 3 );
2001                         
2002                         // right side
2003                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
2004                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y + 1, thumb_area.Right - 1, channel_startpoint.Y + 1 );
2005                         dc.DrawRectangle( ResPool.GetPen( scrollbar_background_color ), thumb_pos.X + 29, channel_startpoint.Y + 2, thumb_area.Right - thumb_pos.X - 30, 1 );
2006                         
2007                         pen = ResPool.GetPen( scrollbar_border_color );
2008                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y, thumb_area.Right, channel_startpoint.Y );
2009                         dc.DrawLine( pen, thumb_area.Right, channel_startpoint.Y, thumb_area.Right, channel_startpoint.Y + 4 );
2010                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y + 4, thumb_area.Right, channel_startpoint.Y + 4 );
2011                         
2012                         /* Draw thumb */
2013                         
2014                         thumb_pos.Y = channel_startpoint.Y - 4;
2015                         
2016                         // inner border
2017                         pen = ResPool.GetPen( Color.White );
2018                         dc.DrawLine( pen, thumb_pos.X + 1, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Bottom - 2 );
2019                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Y + 1, thumb_pos.Right - 2, thumb_pos.Y + 1 );
2020                         
2021                         pen = ResPool.GetPen( menu_separator_color );
2022                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2023                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y + 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2024                         
2025                         // outer border
2026                         Point[] points = {
2027                                 new Point( thumb_pos.X + 2, thumb_pos.Y ),
2028                                 new Point( thumb_pos.Right - 3 , thumb_pos.Y ),
2029                                 new Point( thumb_pos.Right - 1, thumb_pos.Y + 2 ),
2030                                 new Point( thumb_pos.Right - 1, thumb_pos.Bottom - 3 ),
2031                                 new Point( thumb_pos.Right - 3, thumb_pos.Bottom - 1 ),
2032                                 new Point( thumb_pos.X + 2, thumb_pos.Bottom - 1 ),
2033                                 new Point( thumb_pos.X, thumb_pos.Bottom - 3 ),
2034                                 new Point( thumb_pos.X, thumb_pos.Y + 2 ),
2035                                 new Point( thumb_pos.X + 2, thumb_pos.Y )
2036                         };
2037                         
2038                         dc.DrawLines( ResPool.GetPen( border_normal_dark_color ), points );
2039                         
2040                         Color first_gradient_color = mouse_value ? button_edge_bottom_outer_color : trackbar_inner_first_gradient_color;
2041                         Color second_gradient_color = mouse_value ? trackbar_inner_pressed_second_gradient_color : trackbar_inner_second_gradient_color;
2042                         
2043                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( thumb_pos.X, thumb_pos.Y + 2 ), new Point( thumb_pos.X, thumb_pos.Bottom - 2 ), first_gradient_color, second_gradient_color ) ) {
2044                                 dc.FillRectangle( lgbr, thumb_pos.X + 2, thumb_pos.Y + 2, thumb_pos.Width - 4, thumb_pos.Height - 4 );
2045                         }
2046                         
2047                         // outer egdes
2048                         pen = ResPool.GetPen( edge_top_inner_color );
2049                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Y );
2050                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y, thumb_pos.Right - 1, thumb_pos.Y + 1 );
2051                         
2052                         pen = ResPool.GetPen( edge_bottom_inner_color );
2053                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Bottom - 2, thumb_pos.X + 1, thumb_pos.Bottom - 1 );
2054                         dc.DrawLine( pen, thumb_pos.Right - 1, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 1 );
2055                         
2056                         // draw grip lines
2057                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
2058                         dc.DrawLine( pen, thumb_pos.X + 11, thumb_pos.Y + 4, thumb_pos.X + 11, thumb_pos.Y + 8 );
2059                         dc.DrawLine( pen, thumb_pos.X + 14, thumb_pos.Y + 4, thumb_pos.X + 14, thumb_pos.Y + 8 );
2060                         dc.DrawLine( pen, thumb_pos.X + 17, thumb_pos.Y + 4, thumb_pos.X + 17, thumb_pos.Y + 8 );
2061                         
2062                         pen = ResPool.GetPen( Color.White );
2063                         dc.DrawLine( pen, thumb_pos.X + 12, thumb_pos.Y + 4, thumb_pos.X  + 12, thumb_pos.Y + 8 );
2064                         dc.DrawLine( pen, thumb_pos.X + 15, thumb_pos.Y + 4, thumb_pos.X + 15, thumb_pos.Y + 8 );
2065                         dc.DrawLine( pen, thumb_pos.X + 18, thumb_pos.Y + 4, thumb_pos.X + 18, thumb_pos.Y + 8 );
2066                         
2067                         pixel_len = thumb_area.Width - 11;
2068                         pixels_betweenticks = pixel_len / ticks;
2069                         
2070                         /* Draw ticks*/
2071                         thumb_area.Y = thumb_pos.Y;
2072                         thumb_area.X = channel_startpoint.X;
2073                         thumb_area.Height = thumb_pos.Height;
2074                         Region outside = new Region( area );
2075                         outside.Exclude( thumb_area );                  
2076                         
2077                         if ( outside.IsVisible( clip_rectangle ) ) {                            
2078                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.BottomRight ) == TickStyle.BottomRight ||
2079                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {                               
2080                                         
2081                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
2082                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2083                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
2084                                                                     area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3 );
2085                                                 else
2086                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
2087                                                                     area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2 );
2088                                         }
2089                                 }
2090                                 
2091                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.TopLeft ) == TickStyle.TopLeft ||
2092                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {
2093                                         
2094                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
2095                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2096                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
2097                                                                     area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y );
2098                                                 else
2099                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
2100                                                                     area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y );
2101                                         }                       
2102                                 }
2103                         }
2104                         
2105                         outside.Dispose( );                     
2106                 }
2107                 
2108                 public override void DrawTrackBar( Graphics dc, Rectangle clip_rectangle, TrackBar tb ) {
2109                         int             value_pos;
2110                         bool            mouse_value;
2111                         float           ticks = ( tb.Maximum - tb.Minimum ) / tb.tickFrequency; /* N of ticks draw*/
2112                         Rectangle       area;
2113                         Rectangle       thumb_pos = tb.ThumbPos;
2114                         Rectangle       thumb_area = tb.ThumbArea;
2115                         
2116                         if ( tb.thumb_pressed ) {
2117                                 value_pos = tb.thumb_mouseclick;
2118                                 mouse_value = true;
2119                         } else {
2120                                 value_pos = tb.Value - tb.Minimum;
2121                                 mouse_value = false;
2122                         }
2123                         
2124                         area = tb.ClientRectangle;
2125                         
2126                         /* Control Background */
2127                         if ( tb.BackColor == DefaultControlBackColor ) {
2128                                 dc.FillRectangle( ResPool.GetSolidBrush( ColorControl ), clip_rectangle );
2129                         } else {
2130                                 dc.FillRectangle( ResPool.GetSolidBrush( tb.BackColor ), clip_rectangle );
2131                         }
2132                         
2133                         if ( tb.Orientation == Orientation.Vertical ) {
2134                                 DrawTrackBar_Vertical( dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
2135                                                       ticks, value_pos, mouse_value );
2136                                 
2137                         } else {
2138                                 DrawTrackBar_Horizontal( dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
2139                                                         ticks, value_pos, mouse_value );
2140                         }
2141                         
2142                         // TODO: draw better focus rectangle
2143                         if ( tb.Focused ) {
2144                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y, area.Width - 1, 1 );
2145                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y + area.Height - 1, area.Width - 1, 1 );
2146                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y, 1, area.Height - 1 );
2147                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X + area.Width - 1, area.Y, 1, area.Height - 1 );
2148                         }
2149                         
2150                         tb.ThumbPos = thumb_pos;
2151                         tb.ThumbArea = thumb_area;
2152                 }
2153                 #endregion      // TrackBar
2154                 
2155                 #region ListView
2156                 // draws the ListViewItem of the given index
2157                 protected override void DrawListViewItem( Graphics dc, ListView control, ListViewItem item ) {                          
2158                         Rectangle rect_checkrect = item.CheckRectReal;
2159                         Rectangle rect_iconrect = item.GetBounds( ItemBoundsPortion.Icon );
2160                         Rectangle full_rect = item.GetBounds( ItemBoundsPortion.Entire );
2161                         Rectangle text_rect = item.GetBounds( ItemBoundsPortion.Label );                        
2162                         
2163                         if ( control.CheckBoxes ) {
2164                                 if ( control.StateImageList == null ) {
2165                                         // Make sure we've got at least a line width of 1
2166                                         int check_wd = Math.Max( 3, rect_checkrect.Width / 6 );
2167                                         int scale = Math.Max( 1, rect_checkrect.Width / 12 );
2168                                         
2169                                         // set the checkbox background
2170                                         dc.FillRectangle( this.ResPool.GetSolidBrush( this.ColorWindow ),
2171                                                          rect_checkrect );
2172                                         // define a rectangle inside the border area
2173                                         Rectangle rect = new Rectangle( rect_checkrect.X + 2,
2174                                                                        rect_checkrect.Y + 2,
2175                                                                        rect_checkrect.Width - 4,
2176                                                                        rect_checkrect.Height - 4 );
2177                                         Pen pen = new Pen( this.ColorWindowText, 2 );
2178                                         dc.DrawRectangle( pen, rect );
2179                                         
2180                                         // Need to draw a check-mark
2181                                         if ( item.Checked ) {
2182                                                 pen.Width = 1;
2183                                                 // adjustments to get the check-mark at the right place
2184                                                 rect.X ++; rect.Y ++;
2185                                                 // following logic is taken from DrawFrameControl method
2186                                                 for ( int i = 0; i < check_wd; i++ ) {
2187                                                         dc.DrawLine( pen, rect.Left + check_wd / 2,
2188                                                                     rect.Top + check_wd + i,
2189                                                                     rect.Left + check_wd / 2 + 2 * scale,
2190                                                                     rect.Top + check_wd + 2 * scale + i );
2191                                                         dc.DrawLine( pen,
2192                                                                     rect.Left + check_wd / 2 + 2 * scale,
2193                                                                     rect.Top + check_wd + 2 * scale + i,
2194                                                                     rect.Left + check_wd / 2 + 6 * scale,
2195                                                                     rect.Top + check_wd - 2 * scale + i );
2196                                                 }
2197                                         }
2198                                 } else {
2199                                         if ( item.Checked && control.StateImageList.Images.Count > 1 )
2200                                                 control.StateImageList.Draw( dc,
2201                                                                             rect_checkrect.Location, 1 );
2202                                         else if ( ! item.Checked && control.StateImageList.Images.Count > 0 )
2203                                                 control.StateImageList.Draw( dc,
2204                                                                             rect_checkrect.Location, 0 );
2205                                 }
2206                         }
2207                         
2208                         // Item is drawn as a special case, as it is not just text
2209                         if ( control.View == View.LargeIcon ) {
2210                                 if ( item.ImageIndex > -1 &&
2211                                     control.LargeImageList != null &&
2212                                     item.ImageIndex < control.LargeImageList.Images.Count ) {
2213                                         // center image
2214                                         Point image_location = rect_iconrect.Location;
2215                                         Image image = control.LargeImageList.Images[ item.ImageIndex ];
2216                                         if ( image.Width < rect_iconrect.Width ) {
2217                                                 int icon_rect_middle = rect_iconrect.Width / 2;
2218                                                 int image_middle = image.Width / 2;
2219                                                 image_location.X = image_location.X + icon_rect_middle - image_middle;
2220                                         }
2221                                         control.LargeImageList.Draw( dc, image_location,
2222                                                                     item.ImageIndex );
2223                                 }
2224                         } else {
2225                                 if ( item.ImageIndex > -1 &&
2226                                     control.SmallImageList != null &&
2227                                     item.ImageIndex < control.SmallImageList.Images.Count )
2228                                         control.SmallImageList.Draw( dc, rect_iconrect.Location,
2229                                                                     item.ImageIndex );
2230                         }
2231                         
2232                         // draw the item text                   
2233                         // format for the item text
2234                         StringFormat format = new StringFormat( );
2235                         format.LineAlignment = StringAlignment.Center;
2236                         if ( control.View == View.LargeIcon )
2237                                 format.Alignment = StringAlignment.Center; 
2238                         else
2239                                 format.Alignment = StringAlignment.Near;
2240                         
2241                         if ( !control.LabelWrap )
2242                                 format.FormatFlags = StringFormatFlags.NoWrap;
2243                         
2244                         if ( item.Selected ) {
2245                                 if ( control.View == View.Details ) {
2246                                         if ( control.FullRowSelect ) {
2247                                                 // fill the entire rect excluding the checkbox                                          
2248                                                 full_rect.Location = item.GetBounds (ItemBoundsPortion.Label).Location;
2249                                                 dc.FillRectangle( this.ResPool.GetSolidBrush
2250                                                                  ( this.ColorHighlight ), full_rect );
2251                                         } else {
2252                                                 Size text_size = Size.Ceiling( dc.MeasureString( item.Text,
2253                                                                                                 item.Font ) );
2254                                                 text_rect.Width = text_size.Width;
2255                                                 dc.FillRectangle( this.ResPool.GetSolidBrush
2256                                                                  ( this.ColorHighlight ), text_rect );
2257                                         }
2258                                 } else {
2259                                         /*Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
2260                                          item.Font));
2261                                          Point loc = text_rect.Location;
2262                                          loc.X += (text_rect.Width - text_size.Width) / 2;
2263                                          text_rect.Width = text_size.Width;*/
2264                                         dc.FillRectangle( this.ResPool.GetSolidBrush( this.ColorHighlight ),
2265                                                          text_rect );
2266                                 }
2267                         } else
2268                                 dc.FillRectangle( ResPool.GetSolidBrush( item.BackColor ), text_rect );
2269                         
2270                         if ( item.Text != null && item.Text.Length > 0 ) {
2271                                 
2272                                 if ( control.View != View.LargeIcon ) {
2273                                         if ( item.Selected )
2274                                                 dc.DrawString( item.Text, item.Font, this.ResPool.GetSolidBrush
2275                                                               ( this.ColorHighlightText ), text_rect, format );
2276                                         else
2277                                                 dc.DrawString( item.Text, item.Font, this.ResPool.GetSolidBrush
2278                                                               ( item.ForeColor ), text_rect, format );
2279                                 } else {
2280                                         // ListView CalcTextSize says wrapping is done for two lines only !?!
2281                                         // text is centered for the complete text_rect but it should be centered per available row/line
2282                                         
2283                                         // calculate how much lines we get out of text_rect and current item.Font
2284                                         int nr_lines = text_rect.Height / item.Font.Height;
2285                                         int rest = text_rect.Height % item.Font.Height;
2286                                         int line_height = item.Font.Height + ( rest > 1 ? 2 : 0 );
2287                                         
2288                                         Rectangle[] text_rects = new Rectangle[ nr_lines ];
2289                                         
2290                                         for ( int i = 0; i < nr_lines; i++ ) {
2291                                                 text_rects[ i ].X = text_rect.X;
2292                                                 text_rects[ i ].Y = text_rect.Y + i * line_height;
2293                                                 text_rects[ i ].Width = text_rect.Width;
2294                                                 text_rects[ i ].Height = line_height;
2295                                         }
2296                                         
2297                                         string[] lines = new string[ nr_lines ];
2298                                         
2299                                         string text = item.Text;
2300                                         
2301                                         int line_nr = 0;
2302                                         int current_pos = 0;
2303                                         for ( int k = 1; k <= text.Length; k++ ) {
2304                                                 lines[ line_nr ] = text.Substring( current_pos, k - current_pos );
2305                                                 
2306                                                 // FIXME: Graphics.MeasureString returns wrong results if there is a 
2307                                                 //        space char in the string
2308                                                 SizeF sizef = dc.MeasureString( lines[ line_nr ], item.Font, text_rect.Width, format );
2309                                                 
2310                                                 if ( (int)sizef.Width > text_rect.Width - 3 ) {
2311                                                         lines[ line_nr ] = lines[ line_nr ].Remove( lines[ line_nr ].Length - 1, 1 );
2312                                                         k--;
2313                                                         current_pos = k;
2314                                                         line_nr++;
2315                                                         if ( line_nr == nr_lines )
2316                                                                 break;
2317                                                 }
2318                                         }
2319                                         
2320                                         int j = 0;
2321                                         foreach ( Rectangle t_rect in text_rects ) {
2322                                                 if ( item.Selected )
2323                                                         dc.DrawString( lines[ j ], item.Font, this.ResPool.GetSolidBrush
2324                                                                       ( this.ColorHighlightText ), t_rect, format );
2325                                                 else
2326                                                         dc.DrawString( lines[ j ], item.Font, this.ResPool.GetSolidBrush
2327                                                                       ( item.ForeColor ), t_rect, format );
2328                                                 j++;
2329                                         }
2330                                 } 
2331                         }
2332                         
2333                         if ( control.View == View.Details && control.Columns.Count > 0 ) {
2334                                 // draw subitems for details view
2335                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
2336                                 int count = ( control.Columns.Count < subItems.Count ? 
2337                                         control.Columns.Count : subItems.Count );
2338                                 
2339                                 if ( count > 0 ) {
2340                                         ColumnHeader col;
2341                                         ListViewItem.ListViewSubItem subItem;
2342                                         Rectangle sub_item_rect = text_rect; 
2343                                         
2344                                         // set the format for subitems
2345                                         format.FormatFlags = StringFormatFlags.NoWrap;
2346                                         format.Alignment = StringAlignment.Near;
2347                                         
2348                                         // 0th subitem is the item already drawn
2349                                         for ( int index = 1; index < count; index++ ) {
2350                                                 subItem = subItems[ index ];
2351                                                 col = control.Columns[ index ];
2352                                                 sub_item_rect.X = col.Rect.Left;
2353                                                 sub_item_rect.Width = col.Wd;
2354                                                 sub_item_rect.X -= control.h_marker;
2355                                                 
2356                                                 SolidBrush sub_item_back_br = null;
2357                                                 SolidBrush sub_item_fore_br = null;
2358                                                 Font sub_item_font = null;
2359                                                 
2360                                                 if ( item.UseItemStyleForSubItems ) {
2361                                                         sub_item_back_br = this.ResPool.GetSolidBrush
2362                                                         ( item.BackColor );
2363                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
2364                                                         ( item.ForeColor );
2365                                                         sub_item_font = item.Font;
2366                                                 } else {
2367                                                         sub_item_back_br = this.ResPool.GetSolidBrush
2368                                                         ( subItem.BackColor );
2369                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
2370                                                         ( subItem.ForeColor );
2371                                                         sub_item_font = subItem.Font;
2372                                                 }
2373                                                 
2374                                                 // In case of fullrowselect, background is filled
2375                                                 // for the entire rect above
2376                                                 if ( item.Selected && control.FullRowSelect ) {
2377                                                         if ( subItem.Text != null && subItem.Text.Length > 0 )
2378                                                                 dc.DrawString( subItem.Text, sub_item_font,
2379                                                                               this.ResPool.GetSolidBrush
2380                                                                               ( this.ColorHighlightText ),
2381                                                                               sub_item_rect, format );
2382                                                 } else {
2383                                                         dc.FillRectangle( sub_item_back_br, sub_item_rect );
2384                                                         if ( subItem.Text != null && subItem.Text.Length > 0 )
2385                                                                 dc.DrawString( subItem.Text, sub_item_font,
2386                                                                               sub_item_fore_br,
2387                                                                               sub_item_rect, format );
2388                                                 }
2389                                                 sub_item_rect.X += col.Wd;
2390                                         }
2391                                 }
2392                         }
2393                         
2394                         if ( item.Focused ) {                           
2395                                 if ( item.Selected )
2396                                         CPDrawFocusRectangle( dc, text_rect, ColorHighlightText, ColorHighlight );
2397                                 else
2398                                         CPDrawFocusRectangle( dc, text_rect, control.ForeColor, control.BackColor );
2399                         }
2400                         
2401                         format.Dispose( );
2402                 }
2403                 #endregion ListView
2404                 
2405                 #region DateTimePicker
2406                 public override void DrawDateTimePicker (Graphics dc,  Rectangle clip_rectangle, DateTimePicker dtp) {
2407                         // if not showing the numeric updown control then render border
2408                         if (!dtp.ShowUpDown && clip_rectangle.IntersectsWith (dtp.ClientRectangle)) {
2409                                 // draw the outer border
2410                                 Rectangle button_bounds = dtp.ClientRectangle;
2411                                 CPDrawBorder3D (dc, button_bounds, Border3DStyle.Sunken, Border3DSide.Left | Border3DSide.Right | Border3DSide.Top | Border3DSide.Bottom, dtp.BackColor);
2412                                 
2413                                 // deflate by the border width
2414                                 if (clip_rectangle.IntersectsWith (dtp.drop_down_arrow_rect)) {
2415                                         button_bounds.Inflate (-2,-2);
2416                                         ButtonState state = dtp.is_drop_down_visible ? ButtonState.Pushed : ButtonState.Normal;
2417                                         Rectangle button_rect = new Rectangle(dtp.drop_down_arrow_rect.X, dtp.drop_down_arrow_rect.Y + 1,
2418                                                                               dtp.drop_down_arrow_rect.Width - 1, dtp.drop_down_arrow_rect.Height - 2);
2419                                         this.CPDrawComboButton ( 
2420                                                 dc, 
2421                                                 button_rect, 
2422                                                 state);
2423                                 }
2424                         }
2425                         
2426                         // render the date part
2427                         if (clip_rectangle.IntersectsWith (dtp.date_area_rect)) {
2428                                 // fill the background
2429                                 Rectangle date_area_rect = new Rectangle( dtp.date_area_rect.X + 1, dtp.date_area_rect.Y + 1,
2430                                                                          dtp.date_area_rect.Width - 2,  dtp.date_area_rect.Height - 2);
2431                                 dc.FillRectangle (ResPool.GetSolidBrush (ColorWindow), date_area_rect);
2432                                 
2433                                 // fill the currently highlighted area
2434                                 if (dtp.hilight_date_area != Rectangle.Empty) {
2435                                         dc.FillRectangle (ResPool.GetSolidBrush (ColorHighlight), dtp.hilight_date_area);
2436                                 }
2437                                 
2438                                 // draw the text part
2439                                 // TODO: if date format is CUstom then we need to draw the dates as separate parts
2440                                 StringFormat text_format = new StringFormat();
2441                                 text_format.LineAlignment = StringAlignment.Center;
2442                                 text_format.Alignment = StringAlignment.Near;                                   
2443                                 dc.DrawString (dtp.Text, dtp.Font, ResPool.GetSolidBrush (dtp.ForeColor), Rectangle.Inflate(dtp.date_area_rect, -1, -1), text_format);
2444                                 text_format.Dispose ();
2445                         }
2446                 }
2447                 #endregion // DateTimePicker
2448                 
2449                 #region MonthCalendar
2450                 // draw the month calendar
2451                 public override void DrawMonthCalendar(Graphics dc, Rectangle clip_rectangle, MonthCalendar mc) 
2452                 {
2453                         Rectangle client_rectangle = mc.ClientRectangle;
2454                         Size month_size = mc.SingleMonthSize;
2455                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
2456                         Size calendar_spacing = (Size)((object)mc.calendar_spacing);
2457                         Size date_cell_size = (Size)((object)mc.date_cell_size);
2458                         
2459                         // draw the singlecalendars
2460                         int x_offset = 1;
2461                         int y_offset = 1;
2462                         // adjust for the position of the specific month
2463                         for (int i=0; i < mc.CalendarDimensions.Height; i++) 
2464                         {
2465                                 if (i > 0) 
2466                                 {
2467                                         y_offset += month_size.Height + calendar_spacing.Height;
2468                                 }
2469                                 // now adjust for x position    
2470                                 for (int j=0; j < mc.CalendarDimensions.Width; j++) 
2471                                 {
2472                                         if (j > 0) 
2473                                         {
2474                                                 x_offset += month_size.Width + calendar_spacing.Width;
2475                                         } 
2476                                         else 
2477                                         {
2478                                                 x_offset = 1;
2479                                         }
2480                                         
2481                                         Rectangle month_rect = new Rectangle (x_offset, y_offset, month_size.Width, month_size.Height);
2482                                         if (month_rect.IntersectsWith (clip_rectangle)) {
2483                                                 DrawSingleMonth (
2484                                                         dc,
2485                                                         clip_rectangle,
2486                                                         month_rect,
2487                                                         mc,
2488                                                         i,
2489                                                         j);
2490                                         }
2491                                 }
2492                         }
2493                         
2494                         Rectangle bottom_rect = new Rectangle (
2495                                 client_rectangle.X,
2496                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height - 3, 0),
2497                                 client_rectangle.Width,
2498                                 date_cell_size.Height + 2);
2499                         // draw the today date if it's set
2500                         if (mc.ShowToday && bottom_rect.IntersectsWith (clip_rectangle)) 
2501                         {
2502                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), bottom_rect);
2503                                 if (mc.ShowToday) {
2504                                         int today_offset = 5;
2505                                         if (mc.ShowTodayCircle) 
2506                                         {
2507                                                 Rectangle today_circle_rect = new Rectangle (
2508                                                         client_rectangle.X + 5,
2509                                                         Math.Max(client_rectangle.Bottom - date_cell_size.Height - 2, 0),
2510                                                         date_cell_size.Width,
2511                                                         date_cell_size.Height);
2512                                                 DrawTodayCircle (dc, today_circle_rect);
2513                                                 today_offset += date_cell_size.Width + 5;
2514                                         }
2515                                         // draw today's date
2516                                         StringFormat text_format = new StringFormat();
2517                                         text_format.LineAlignment = StringAlignment.Center;
2518                                         text_format.Alignment = StringAlignment.Near;
2519                                         Font bold_font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
2520                                         Rectangle today_rect = new Rectangle (
2521                                                 today_offset + client_rectangle.X,
2522                                                 Math.Max(client_rectangle.Bottom - date_cell_size.Height, 0),
2523                                                 Math.Max(client_rectangle.Width - today_offset, 0),
2524                                                 date_cell_size.Height);
2525                                         dc.DrawString ("Today: " + DateTime.Now.ToShortDateString(), bold_font, ResPool.GetSolidBrush (mc.ForeColor), today_rect, text_format);
2526                                         text_format.Dispose ();
2527                                         bold_font.Dispose ();
2528                                 }                               
2529                         }
2530                         
2531                         // finally paint the borders of the calendars as required
2532                         for (int i = 0; i <= mc.CalendarDimensions.Width; i++) {
2533                                 if (i == 0 && clip_rectangle.X == client_rectangle.X) {
2534                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, 1, client_rectangle.Height));
2535                                 } else if (i == mc.CalendarDimensions.Width && clip_rectangle.Right == client_rectangle.Right) {
2536                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.Right-1, client_rectangle.Y, 1, client_rectangle.Height));
2537                                 } else { 
2538                                         Rectangle rect = new Rectangle (
2539                                                 client_rectangle.X + (month_size.Width*i) + (calendar_spacing.Width * (i-1)) + 1,
2540                                                 client_rectangle.Y,
2541                                                 calendar_spacing.Width,
2542                                                 client_rectangle.Height);
2543                                         if (i < mc.CalendarDimensions.Width && i > 0 && clip_rectangle.IntersectsWith (rect)) {
2544                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
2545                                         }
2546                                 }
2547                         }
2548                         for (int i = 0; i <= mc.CalendarDimensions.Height; i++) {
2549                                 if (i == 0 && clip_rectangle.Y == client_rectangle.Y) {
2550                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Y, client_rectangle.Width, 1));
2551                                 } else if (i == mc.CalendarDimensions.Height && clip_rectangle.Bottom == client_rectangle.Bottom) {
2552                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), new Rectangle (client_rectangle.X, client_rectangle.Bottom-1, client_rectangle.Width, 1));
2553                                 } else { 
2554                                         Rectangle rect = new Rectangle (
2555                                                 client_rectangle.X,
2556                                                 client_rectangle.Y + (month_size.Height*i) + (calendar_spacing.Height*(i-1)) + 1,
2557                                                 client_rectangle.Width,
2558                                                 calendar_spacing.Height);
2559                                         if (i < mc.CalendarDimensions.Height && i > 0 && clip_rectangle.IntersectsWith (rect)) {
2560                                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), rect);
2561                                         }
2562                                 }
2563                         }
2564                         
2565                         // draw the drop down border if need
2566                         if (mc.owner != null) {
2567                                 Rectangle bounds = mc.ClientRectangle;
2568                                 if (clip_rectangle.Contains (mc.Location)) {
2569                                         // find out if top or left line to draw
2570                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
2571                                                 
2572                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.X, bounds.Bottom-1);
2573                                         }
2574                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
2575                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Y, bounds.Right-1, bounds.Y);
2576                                         }
2577                                 }
2578                                 if (clip_rectangle.Contains (new Point(bounds.Right, bounds.Bottom))) {
2579                                         // find out if bottom or right line to draw
2580                                         if(clip_rectangle.Contains (new Point (bounds.Left, bounds.Bottom))) {
2581                                                 dc.DrawLine (SystemPens.ControlText, bounds.X, bounds.Bottom-1, bounds.Right-1, bounds.Bottom-1);
2582                                         }
2583                                         if(clip_rectangle.Contains (new Point (bounds.Right, bounds.Y))) {
2584                                                 dc.DrawLine (SystemPens.ControlText, bounds.Right-1, bounds.Y, bounds.Right-1, bounds.Bottom-1);
2585                                         }
2586                                 }
2587                         }
2588                 }
2589                 
2590                 // darws a single part of the month calendar (with one month)
2591                 private void DrawSingleMonth(Graphics dc, Rectangle clip_rectangle, Rectangle rectangle, MonthCalendar mc, int row, int col) 
2592                 {
2593                         // cache local copies of Marshal-by-ref internal members (gets around error CS0197)
2594                         Size title_size = (Size)((object)mc.title_size);
2595                         Size date_cell_size = (Size)((object)mc.date_cell_size);
2596                         DateTime current_month = (DateTime)((object)mc.current_month);
2597                         
2598                         // set up some standard string formating variables
2599                         StringFormat text_format = new StringFormat();
2600                         text_format.LineAlignment = StringAlignment.Center;
2601                         text_format.Alignment = StringAlignment.Center;
2602                         
2603                         
2604                         // draw the title back ground
2605                         DateTime this_month = current_month.AddMonths (row*mc.CalendarDimensions.Width+col);
2606                         Rectangle title_rect = new Rectangle(rectangle.X, rectangle.Y, title_size.Width, title_size.Height);
2607                         if (title_rect.IntersectsWith (clip_rectangle)) {
2608                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), title_rect);
2609                                 // draw the title                               
2610                                 string title_text = this_month.ToString ("MMMM yyyy");
2611                                 dc.DrawString (title_text, mc.Font, ResPool.GetSolidBrush (mc.TitleForeColor), title_rect, text_format);
2612                                 
2613                                 // draw previous and next buttons if it's time
2614                                 if (row == 0 && col == 0) 
2615                                 {
2616                                         // draw previous button
2617                                         DrawMonthCalendarButton (
2618                                                 dc,
2619                                                 rectangle,
2620                                                 mc,
2621                                                 title_size,
2622                                                 mc.button_x_offset,
2623                                                 (System.Drawing.Size)((object)mc.button_size),
2624                                                 true);
2625                                 }
2626                                 if (row == 0 && col == mc.CalendarDimensions.Width-1) 
2627                                 {
2628                                         // draw next button
2629                                         DrawMonthCalendarButton (
2630                                                 dc,
2631                                                 rectangle,
2632                                                 mc,
2633                                                 title_size,
2634                                                 mc.button_x_offset,
2635                                                 (System.Drawing.Size)((object)mc.button_size),
2636                                                 false);
2637                                 }
2638                         }
2639                         
2640                         // set the week offset and draw week nums if needed
2641                         int col_offset = (mc.ShowWeekNumbers) ? 1 : 0;
2642                         Rectangle day_name_rect = new Rectangle(
2643                                 rectangle.X,
2644                                 rectangle.Y + title_size.Height,
2645                                 (7 + col_offset) * date_cell_size.Width,
2646                                 date_cell_size.Height);
2647                         if (day_name_rect.IntersectsWith (clip_rectangle)) {
2648                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), day_name_rect);
2649                                 // draw the day names 
2650                                 DayOfWeek first_day_of_week = mc.GetDayOfWeek(mc.FirstDayOfWeek);
2651                                 for (int i=0; i < 7; i++) 
2652                                 {
2653                                         int position = i - (int) first_day_of_week;
2654                                         if (position < 0) 
2655                                         {
2656                                                 position = 7 + position;
2657                                         }
2658                                         // draw it
2659                                         Rectangle day_rect = new Rectangle(
2660                                                 day_name_rect.X + ((i + col_offset)* date_cell_size.Width),
2661                                                 day_name_rect.Y,
2662                                                 date_cell_size.Width,
2663                                                 date_cell_size.Height);
2664                                         dc.DrawString (((DayOfWeek)i).ToString().Substring(0, 3), mc.Font, ResPool.GetSolidBrush (mc.TitleBackColor), day_rect, text_format);
2665                                 }
2666                                 
2667                                 // draw the vertical divider
2668                                 int vert_divider_y = Math.Max(title_size.Height+ date_cell_size.Height-1, 0);
2669                                 dc.DrawLine (
2670                                         ResPool.GetPen (mc.ForeColor),
2671                                         rectangle.X + (col_offset * date_cell_size.Width) + mc.divider_line_offset,
2672                                         rectangle.Y + vert_divider_y,
2673                                         rectangle.Right - mc.divider_line_offset,
2674                                         rectangle.Y + vert_divider_y);
2675                         }
2676                         
2677                         
2678                         // draw the actual date items in the grid (including the week numbers)
2679                         Rectangle date_rect = new Rectangle (
2680                                 rectangle.X,
2681                                 rectangle.Y + title_size.Height + date_cell_size.Height,
2682                                 date_cell_size.Width,
2683                                 date_cell_size.Height);
2684                         int month_row_count = 0;
2685                         bool draw_week_num_divider = false;
2686                         DateTime current_date = mc.GetFirstDateInMonthGrid ( new DateTime (this_month.Year, this_month.Month, 1));
2687                         for (int i=0; i < 6; i++) 
2688                         {
2689                                 // establish if this row is in our clip_area
2690                                 Rectangle row_rect = new Rectangle (
2691                                         rectangle.X,
2692                                         rectangle.Y + title_size.Height + (date_cell_size.Height * (i+1)),
2693                                         date_cell_size.Width * 7,
2694                                         date_cell_size.Height);
2695                                 if (mc.ShowWeekNumbers) {
2696                                         row_rect.Width += date_cell_size.Width;
2697                                 }
2698                                 
2699                                 bool draw_row = row_rect.IntersectsWith (clip_rectangle);
2700                                 if (draw_row) {
2701                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.BackColor), row_rect);
2702                                 }
2703                                 // establish if this is a valid week to draw
2704                                 if (mc.IsValidWeekToDraw (this_month, current_date, row, col)) {
2705                                         month_row_count = i;
2706                                 }
2707                                 
2708                                 // draw the week number if required
2709                                 if (mc.ShowWeekNumbers && month_row_count == i) {
2710                                         if (!draw_week_num_divider) {
2711                                                 draw_week_num_divider = draw_row;
2712                                         }
2713                                         // get the week for this row
2714                                         int week = mc.GetWeekOfYear (current_date);     
2715                                         
2716                                         if (draw_row) {
2717                                                 dc.DrawString (
2718                                                         week.ToString(),
2719                                                         mc.Font,
2720                                                         ResPool.GetSolidBrush (mc.TitleBackColor),
2721                                                         date_rect,
2722                                                         text_format);
2723                                         }
2724                                         date_rect.Offset(date_cell_size.Width, 0);
2725                                 }
2726                                 
2727                                 // only draw the days if we have to
2728                                 if(month_row_count == i) {
2729                                         for (int j=0; j < 7; j++) 
2730                                         {
2731                                                 if (draw_row) {
2732                                                         DrawMonthCalendarDate (
2733                                                                 dc,
2734                                                                 date_rect,
2735                                                                 mc,
2736                                                                 current_date,
2737                                                                 this_month,
2738                                                                 row,
2739                                                                 col);
2740                                                 }
2741                                                 
2742                                                 // move the day on
2743                                                 current_date = current_date.AddDays(1);
2744                                                 date_rect.Offset(date_cell_size.Width, 0);
2745                                         }
2746                                         
2747                                         // shift the rectangle down one row
2748                                         int offset = (mc.ShowWeekNumbers) ? -8 : -7;
2749                                         date_rect.Offset(offset*date_cell_size.Width, date_cell_size.Height);
2750                                 }
2751                         }
2752                         
2753                         // month_row_count is zero based, so add one
2754                         month_row_count++;
2755                         
2756                         // draw week numbers if required
2757                         if (draw_week_num_divider) {
2758                                 col_offset = 1;
2759                                 dc.DrawLine (
2760                                         ResPool.GetPen (mc.ForeColor),
2761                                         rectangle.X + date_cell_size.Width - 1,
2762                                         rectangle.Y + title_size.Height + date_cell_size.Height + mc.divider_line_offset,
2763                                         rectangle.X + date_cell_size.Width - 1,
2764                                         rectangle.Y + title_size.Height + date_cell_size.Height + (month_row_count * date_cell_size.Height) - mc.divider_line_offset);
2765                         }
2766                         text_format.Dispose ();
2767                 }
2768                 
2769                 // draws the pervious or next button
2770                 private void DrawMonthCalendarButton (Graphics dc, Rectangle rectangle, MonthCalendar mc, Size title_size, int x_offset, Size button_size, bool is_previous) 
2771                 {
2772                         bool is_clicked = false;
2773                         Rectangle button_rect;
2774                         Rectangle arrow_rect = new Rectangle (rectangle.X, rectangle.Y, 4, 7);
2775                         Point[] arrow_path = new Point[3];
2776                         // prepare the button
2777                         if (is_previous) 
2778                         {
2779                                 is_clicked = mc.is_previous_clicked;
2780                                 button_rect = new Rectangle (
2781                                         rectangle.X + 1 + x_offset,
2782                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2783                                         Math.Max(button_size.Width - 1, 0),
2784                                         Math.Max(button_size.Height - 1, 0));
2785                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2786                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2787                                 if (is_clicked) {
2788                                         arrow_rect.Offset(1,1);
2789                                 }
2790                                 arrow_path[0] = new Point (arrow_rect.Right, arrow_rect.Y);
2791                                 arrow_path[1] = new Point (arrow_rect.X, arrow_rect.Y + arrow_rect.Height/2);
2792                                 arrow_path[2] = new Point (arrow_rect.Right, arrow_rect.Bottom);
2793                         }
2794                         else
2795                         {
2796                                 is_clicked = mc.is_next_clicked;
2797                                 button_rect = new Rectangle (
2798                                         rectangle.Right - 1 - x_offset - button_size.Width,
2799                                         rectangle.Y + 1 + ((title_size.Height - button_size.Height)/2),
2800                                         Math.Max(button_size.Width - 1, 0),
2801                                         Math.Max(button_size.Height - 1, 0));
2802                                 arrow_rect.X = button_rect.X + ((button_rect.Width - arrow_rect.Width)/2);
2803                                 arrow_rect.Y = button_rect.Y + ((button_rect.Height - arrow_rect.Height)/2);
2804                                 if (is_clicked) {
2805                                         arrow_rect.Offset(1,1);
2806                                 }
2807                                 arrow_path[0] = new Point (arrow_rect.X, arrow_rect.Y);
2808                                 arrow_path[1] = new Point (arrow_rect.Right, arrow_rect.Y + arrow_rect.Height/2);
2809                                 arrow_path[2] = new Point (arrow_rect.X, arrow_rect.Bottom);                            
2810                         }
2811                         
2812                         // fill the background
2813                         dc.FillRectangle (ResPool.GetSolidBrush(mc.TitleBackColor), button_rect);
2814                         
2815                         // draw the button
2816                         Color first_gradient_color = is_clicked ? pressed_gradient_first_color : gradient_first_color;
2817                         Color second_gradient_color = is_clicked ? pressed_gradient_second_color : gradient_second_color;
2818                         
2819                         CL_Draw_Button (dc, button_rect, FlatStyle.Standard,
2820                                            false, true, is_clicked, 
2821                                            first_gradient_color, second_gradient_color,
2822                                            false);
2823                                 
2824                         // draw the arrow
2825                         SmoothingMode old_smooting_mode = dc.SmoothingMode;
2826                         dc.SmoothingMode = SmoothingMode.AntiAlias;
2827                         dc.FillPolygon (SystemBrushes.ControlText, arrow_path);
2828                         dc.SmoothingMode = old_smooting_mode;
2829                 }
2830                 
2831                 
2832                 // draws one day in the calendar grid
2833                 private void DrawMonthCalendarDate (Graphics dc, Rectangle rectangle, MonthCalendar mc, DateTime date, DateTime month, int row, int col) {
2834                         Color date_color = mc.ForeColor;
2835                         Rectangle interior = new Rectangle (rectangle.X, rectangle.Y, Math.Max(rectangle.Width - 1, 0), Math.Max(rectangle.Height - 1, 0));
2836                         
2837                         // find out if we are the lead of the first calendar or the trail of the last calendar                                          
2838                         if (date.Year != month.Year || date.Month != month.Month) {
2839                                 DateTime check_date = month.AddMonths (-1);
2840                                 // check if it's the month before 
2841                                 if (check_date.Year == date.Year && check_date.Month == date.Month && row == 0 && col == 0) {
2842                                         date_color = mc.TrailingForeColor;
2843                                 } else {
2844                                         // check if it's the month after
2845                                         check_date = month.AddMonths (1);
2846                                         if (check_date.Year == date.Year && check_date.Month == date.Month && row == mc.CalendarDimensions.Height-1 && col == mc.CalendarDimensions.Width-1) {
2847                                                 date_color = mc.TrailingForeColor;
2848                                         } else {
2849                                                 return;
2850                                         }
2851                                 }
2852                         } else {
2853                                 date_color = mc.ForeColor;
2854                         }
2855                         
2856                         
2857                         if (date == mc.SelectionStart && date == mc.SelectionEnd) {
2858                                 // see if the date is in the start of selection
2859                                 date_color = mc.BackColor;
2860                                 // draw the left hand of the back ground
2861                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2862                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 0, 359);
2863                         } else if (date == mc.SelectionStart) {
2864                                 // see if the date is in the start of selection
2865                                 date_color = mc.BackColor;
2866                                 // draw the left hand of the back ground
2867                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);                                
2868                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 90, 180);
2869                                 // fill the other side as a straight rect
2870                                 if (date < mc.SelectionEnd) 
2871                                 {
2872                                         // use rectangle instead of rectangle to go all the way to edge of rect
2873                                         selection_rect.X = (int) Math.Floor((double)(rectangle.X + rectangle.Width / 2));
2874                                         selection_rect.Width = Math.Max(rectangle.Right - selection_rect.X, 0);
2875                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2876                                 }
2877                         } else if (date == mc.SelectionEnd) {
2878                                 // see if it is the end of selection
2879                                 date_color = mc.BackColor;
2880                                 // draw the left hand of the back ground
2881                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, -3, -3);
2882                                 dc.FillPie (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect, 270, 180);
2883                                 // fill the other side as a straight rect
2884                                 if (date > mc.SelectionStart) {
2885                                         selection_rect.X = rectangle.X;
2886                                         selection_rect.Width = rectangle.Width - (rectangle.Width / 2);
2887                                         dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2888                                 }
2889                         } else if (date > mc.SelectionStart && date < mc.SelectionEnd) {
2890                                 // now see if it's in the middle
2891                                 date_color = mc.BackColor;
2892                                 // draw the left hand of the back ground
2893                                 Rectangle selection_rect = Rectangle.Inflate(rectangle, 0, -3);
2894                                 dc.FillRectangle (ResPool.GetSolidBrush (mc.TitleBackColor), selection_rect);
2895                         }
2896                         
2897                         // set up some standard string formating variables
2898                         StringFormat text_format = new StringFormat();
2899                         text_format.LineAlignment = StringAlignment.Center;
2900                         text_format.Alignment = StringAlignment.Center;
2901                         
2902                         
2903                         // establish if it's a bolded font
2904                         Font font;
2905                         if (mc.IsBoldedDate (date)) {
2906                                 font = new Font (mc.Font.FontFamily, mc.Font.Size, mc.Font.Style | FontStyle.Bold);
2907                         } else {
2908                                 font = mc.Font;
2909                         }
2910                         
2911                         // just draw the date now
2912                         dc.DrawString (date.Day.ToString(), font, ResPool.GetSolidBrush (date_color), rectangle, text_format);
2913                         
2914                         // today circle if needed
2915                         if (mc.ShowTodayCircle && date == DateTime.Now.Date) {
2916                                 DrawTodayCircle (dc, interior);
2917                         }
2918                         
2919                         // draw the selection grid
2920                         if (mc.is_date_clicked && mc.clicked_date == date) {                            
2921                                 using (Pen pen = new Pen (Color.Black, 1) ) {
2922                                         pen.DashStyle = DashStyle.Dot;
2923                                         dc.DrawRectangle (pen, interior);
2924                                 }
2925                         }
2926                         text_format.Dispose ();
2927                 }
2928                 
2929                 private void DrawTodayCircle (Graphics dc, Rectangle rectangle) {
2930                         Color circle_color = Color.FromArgb (248, 0, 0);
2931                         // draw the left hand of the circle 
2932                         Rectangle lhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 4, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 5, 0));
2933                         Rectangle rhs_circle_rect = new Rectangle (rectangle.X + 1, rectangle.Y + 1, Math.Max(rectangle.Width - 2, 0), Math.Max(rectangle.Height - 2, 0));
2934                         Point [] curve_points = new Point [3];
2935                         curve_points [0] = new Point (lhs_circle_rect.X, rhs_circle_rect.Y + rhs_circle_rect.Height/12);
2936                         curve_points [1] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/9, rhs_circle_rect.Y);
2937                         curve_points [2] = new Point (lhs_circle_rect.X + lhs_circle_rect.Width/2 + 1, rhs_circle_rect.Y);
2938                         
2939                         SmoothingMode old_smoothing_mode = dc.SmoothingMode;
2940                         dc.SmoothingMode = SmoothingMode.AntiAlias;
2941                         
2942                         using (Pen pen = new Pen (circle_color, 2)) {
2943                                 dc.DrawArc (pen, lhs_circle_rect, 90, 180);
2944                                 dc.DrawArc (pen, rhs_circle_rect, 270, 180);                                    
2945                                 dc.DrawCurve (pen, curve_points);
2946                                 dc.DrawLine (ResPool.GetPen (circle_color), curve_points [2], new Point (curve_points [2].X, lhs_circle_rect.Y));
2947                         }
2948                         
2949                         dc.SmoothingMode = old_smoothing_mode;
2950                 }
2951                 #endregion      // MonthCalendar
2952                 
2953                 public override void CPDrawBorder3D( Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides ) {
2954                         CPDrawBorder3D( graphics, rectangle, style, sides, ColorControl );
2955                 }
2956                 
2957                 public override void CPDrawBorder3D( Graphics dc, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color ) {
2958                         // currently we don't take care of Border3DStyle or Border3DSide
2959                         
2960                         Pen tmp_pen = ResPool.GetPen( edge_bottom_inner_color );
2961                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 2, rectangle.X + 2, rectangle.Y + 1 );
2962                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Y + 1, rectangle.Right - 2, rectangle.Y + 2 );
2963                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 3 );
2964                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Bottom - 3, rectangle.X + 2, rectangle.Bottom - 2 );
2965                         
2966                         tmp_pen = ResPool.GetPen( theme_back_color );
2967                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Y + 2, rectangle.Right - 3, rectangle.Y + 2 );
2968                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Y + 3, rectangle.X + 2, rectangle.Bottom - 3 );
2969                         
2970                         tmp_pen = ResPool.GetPen( Color.White );
2971                         dc.DrawLine( tmp_pen, rectangle.X + 3, rectangle.Bottom - 3, rectangle.Right - 3, rectangle.Bottom - 3 );
2972                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Y + 3, rectangle.Right - 3, rectangle.Bottom - 3 );
2973                         
2974                         Point[] points = {
2975                                 new Point( rectangle.X + 3, rectangle.Y + 1 ),
2976                                 new Point( rectangle.Right - 4, rectangle.Y + 1 ),
2977                                 new Point( rectangle.Right - 2, rectangle.Y + 3 ),
2978                                 new Point( rectangle.Right - 2, rectangle.Bottom - 4 ),
2979                                 new Point( rectangle.Right - 4, rectangle.Bottom - 2 ),
2980                                 new Point( rectangle.X + 3, rectangle.Bottom - 2 ),
2981                                 new Point( rectangle.X + 1, rectangle.Bottom - 4 ),
2982                                 new Point( rectangle.X + 1, rectangle.Y + 3 ),
2983                                 new Point( rectangle.X + 3, rectangle.Y + 1 )
2984                         };
2985                         
2986                         dc.DrawLines( ResPool.GetPen( combobox_border_color ), points );
2987                         
2988                         Point[] points_top_outer = {
2989                                 new Point( rectangle.X + 1, rectangle.Y + 1 ),
2990                                 new Point( rectangle.X + 2, rectangle.Y ),
2991                                 new Point( rectangle.Right - 3, rectangle.Y ),
2992                                 new Point( rectangle.Right - 2 , rectangle.Y + 1 )
2993                         };
2994                         
2995                         Point[] points_bottom_outer = {
2996                                 new Point( rectangle.X + 1, rectangle.Bottom - 2 ),
2997                                 new Point( rectangle.X + 2, rectangle.Bottom - 1 ),
2998                                 new Point( rectangle.Right - 3, rectangle.Bottom - 1 ),
2999                                 new Point( rectangle.Right - 2, rectangle.Bottom - 2 )
3000                         };
3001                         
3002                         // outer border
3003                         tmp_pen = ResPool.GetPen( button_outer_border_dark_color );
3004                         dc.DrawLines( tmp_pen, points_top_outer );
3005                         tmp_pen = ResPool.GetPen( button_outer_border_light_color );
3006                         dc.DrawLines( tmp_pen, points_bottom_outer );
3007                         
3008                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( rectangle.X, rectangle.Y + 2 ), new Point( rectangle.X, rectangle.Bottom - 3 ), button_outer_border_dark_color, button_outer_border_light_color ) ) {
3009                                 using (Pen lgbrpen = new Pen (lgbr)) {
3010                                         dc.DrawLine (lgbrpen, rectangle.X, rectangle.Y + 2, rectangle.X, rectangle.Bottom - 3 );
3011                                         dc.DrawLine (lgbrpen, rectangle.Right - 1, rectangle.Y + 2, rectangle.Right - 1, rectangle.Bottom - 3 );
3012                                 }
3013                         }
3014                         
3015                         tmp_pen = ResPool.GetPen( button_edge_top_outer_color );
3016                         dc.DrawLine( tmp_pen, rectangle.X, rectangle.Y + 1, rectangle.X + 1, rectangle.Y );
3017                         dc.DrawLine( tmp_pen, rectangle.Right - 2, rectangle.Y, rectangle.Right - 1, rectangle.Y + 1 );
3018                         
3019                         tmp_pen = ResPool.GetPen( button_edge_bottom_outer_color );
3020                         dc.DrawLine( tmp_pen, rectangle.X, rectangle.Bottom - 2, rectangle.X + 1, rectangle.Bottom - 1 );
3021                         dc.DrawLine( tmp_pen, rectangle.Right - 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 1 );
3022                 }
3023                 
3024                 public override void CPDrawBorder( Graphics dc, Rectangle bounds, Color leftColor, int leftWidth,
3025                                                   ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
3026                                                   Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
3027                                                   int bottomWidth, ButtonBorderStyle bottomStyle ) {
3028                         dc.DrawRectangle( ResPool.GetPen( combobox_border_color ), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1 );
3029                 }
3030                 
3031                 // TODO: inactive...
3032                 public override void CPDrawCheckBox( Graphics dc, Rectangle rectangle, ButtonState state ) {
3033                         
3034                         bool pushed = ( state & ButtonState.Pushed ) != 0;
3035                         
3036                         int lineWidth;
3037                         Rectangle rect;
3038                         int scale;
3039                         
3040                         // background
3041                         dc.FillRectangle( ResPool.GetSolidBrush( pushed ? checkbox_pressed_backcolor : Color.White ), rectangle );
3042                         
3043                         // border
3044                         dc.DrawRectangle( ResPool.GetPen( scrollbar_border_color ), rectangle );
3045                         
3046                         Color inner_border_color = pushed ? checkbox_pressed_inner_boder_color : checkbox_inner_boder_color;
3047                         
3048                         Pen tmp_pen = ResPool.GetPen( inner_border_color );
3049                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 1, rectangle.Right - 1, rectangle.Y + 1 );
3050                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 2, rectangle.X + 1, rectangle.Bottom - 1 );
3051                         
3052                         /* Make sure we've got at least a line width of 1 */
3053                         lineWidth = Math.Max( 3, rectangle.Width / 6 );
3054                         scale = Math.Max( 1, rectangle.Width / 12 );
3055                         
3056                         // define a rectangle inside the border area
3057                         rect = new Rectangle( rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4 );
3058                         if ( ( state & ButtonState.Inactive ) != 0 ) {
3059                                 tmp_pen = SystemPens.ControlDark;
3060                         } else {
3061                                 tmp_pen = SystemPens.ControlText;
3062                         }
3063                         
3064                         if ( ( state & ButtonState.Checked ) != 0 ) { 
3065                                 /* Need to draw a check-mark */
3066                                 for ( int i=0; i < lineWidth; i++ ) {
3067                                         dc.DrawLine( tmp_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * scale, rect.Top + lineWidth + 2 * scale + i );
3068                                         dc.DrawLine( tmp_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 );
3069                                 }
3070                         }
3071                 }
3072                 
3073                 public  override void CPDrawStringDisabled( Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle,
3074                                                            StringFormat format ) {                      
3075                         
3076                         graphics.DrawString( s, font, ResPool.GetSolidBrush( ColorGrayText), layoutRectangle, format );                 
3077                         
3078                 }
3079                 
3080                 public override void CPDrawButton (Graphics dc, Rectangle buttonRectangle, ButtonState state)
3081                 {
3082                         bool is_enabled = true;
3083                         FlatStyle flat_style = FlatStyle.Standard;
3084                         bool is_pressed = false;
3085                         
3086                         if ((state & ButtonState.Pushed) != 0) {
3087                                 is_pressed = true;
3088                         }
3089                         
3090 //                      if ((state & ButtonState.Checked)!=0) {
3091 //                              dfcs |= DrawFrameControlStates.Checked;
3092 //                      }
3093                         
3094                         if ((state & ButtonState.Flat) != 0) {
3095                                 flat_style = FlatStyle.Flat;
3096                         }
3097                         
3098                         if ((state & ButtonState.Inactive) != 0) {
3099                                 is_enabled = false;
3100                         }
3101                         
3102                         Color first_gradient_color = gradient_first_color;
3103                         Color second_gradient_color = gradient_second_color;
3104                         
3105                         if (is_pressed) {
3106                                 first_gradient_color = pressed_gradient_first_color;
3107                                 second_gradient_color = pressed_gradient_second_color;
3108                         }
3109                         
3110                         CL_Draw_Button (dc, buttonRectangle, flat_style,
3111                                         false, is_enabled, is_pressed,
3112                                         first_gradient_color, second_gradient_color,
3113                                         false);
3114                 }
3115                 
3116                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
3117                 {
3118                         bool is_checked = false;
3119                         bool is_inactive = false;
3120                         
3121                         if ((state & ButtonState.Checked) != 0) {
3122                                 is_checked = true;
3123                         }
3124                         
3125                         if ((state & ButtonState.Inactive) != 0) {
3126                                 is_inactive = true;
3127                         }
3128                         
3129                         SmoothingMode old_smooting_mode = dc.SmoothingMode;
3130                         dc.SmoothingMode = SmoothingMode.AntiAlias;
3131                         
3132                         dc.FillPie (ResPool.GetSolidBrush (this.ColorWindow), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
3133                         
3134                         dc.DrawArc (ResPool.GetPen (radio_button_border_circle_color), rectangle.X + 1, rectangle.Y + 1, rectangle.Width - 2, rectangle.Height - 2, 0, 359);
3135                         
3136                         CL_Draw_RadioButton_Dot (dc, rectangle, is_checked, is_inactive);
3137                         
3138                         dc.SmoothingMode = old_smooting_mode;
3139                 }
3140
3141                 private void CL_Draw_RadioButton_Dot (Graphics dc,  Rectangle rectangle, bool is_checked, bool is_inactive)
3142                 {
3143                         if (is_checked) {
3144                                 int lineWidth = Math.Max (1, Math.Min (rectangle.Width, rectangle.Height) / 4);
3145                                 
3146                                 SolidBrush buttonBrush;
3147                                 
3148                                 if (is_inactive) {
3149                                         buttonBrush = SystemBrushes.ControlDark as SolidBrush;
3150                                 } else {
3151                                         buttonBrush = ResPool.GetSolidBrush (radio_button_dot_color);
3152                                 }
3153                                 dc.FillPie (buttonBrush, rectangle.X + lineWidth, rectangle.Y + lineWidth, rectangle.Width - lineWidth * 2, rectangle.Height - lineWidth * 2, 0, 359);
3154                                 
3155                                 // the white shiny dott
3156                                 buttonBrush = ResPool.GetSolidBrush (ColorWindow);
3157                                 dc.FillPie (buttonBrush, rectangle.X + lineWidth + lineWidth / 2, rectangle.Y + lineWidth + lineWidth / 2, (rectangle.Width - lineWidth * 2) / 3, (rectangle.Height - lineWidth * 2) / 3, 0, 359);
3158                         }
3159                 }
3160
3161                 #region ToolTip
3162                 public override void DrawToolTip (Graphics dc, Rectangle clip_rectangle, ToolTip.ToolTipWindow control)
3163                 {
3164                         dc.FillRectangle(ResPool.GetSolidBrush (ColorInfo), control.ClientRectangle);
3165                         dc.DrawRectangle(ResPool.GetPen (info_border_color), 0, 0, control.Width-1, control.Height-1);
3166         
3167                         TextFormatFlags flags = TextFormatFlags.HidePrefix | TextFormatFlags.SingleLine | TextFormatFlags.VerticalCenter | TextFormatFlags.HorizontalCenter;
3168                         TextRenderer.DrawTextInternal (dc, control.Text, control.Font, control.ClientRectangle, this.ColorInfoText, flags, false);
3169                 }
3170                 #endregion      // ToolTip
3171
3172                 #region BalloonWindow
3173                 NotifyIcon.BalloonWindow balloon_window;
3174                 
3175                 public override void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon)
3176                 {
3177                         Control control = Control.FromHandle(handle);
3178                         
3179                         if (control == null)
3180                                 return;
3181
3182                         if (balloon_window != null) {
3183                                 balloon_window.Close ();
3184                                 balloon_window.Dispose ();
3185                         }
3186
3187                         balloon_window = new NotifyIcon.BalloonWindow (handle);
3188                         balloon_window.Title = title;
3189                         balloon_window.Text = text;
3190                         balloon_window.Icon = icon;
3191                         balloon_window.Timeout = timeout;
3192                         balloon_window.Show ();
3193                 }
3194
3195                 private const int balloon_iconsize = 48;
3196                 private const int balloon_bordersize = 8; 
3197                 
3198                 public override void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control) 
3199                 {
3200                         Brush solidbrush = ResPool.GetSolidBrush(this.ColorInfoText);
3201                         Rectangle rect = control.ClientRectangle;
3202                         int iconsize = (control.Icon == ToolTipIcon.None) ? 0 : balloon_iconsize;
3203                         
3204                         // Rectangle borders and background.
3205                         dc.FillRectangle (ResPool.GetSolidBrush (ColorInfo), rect);
3206                         dc.FillRectangle (ResPool.GetSolidBrush (info_second_color), new Rectangle (rect.X, rect.Y, (balloon_iconsize/2)+balloon_bordersize, rect.Height));
3207                         dc.DrawRectangle (ResPool.GetPen (info_border_color), 0, 0, rect.Width - 1, rect.Height - 1);
3208
3209                         // Icon
3210                         Image image;
3211                         switch (control.Icon) {
3212                                 case ToolTipIcon.Info: {
3213                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxInfo, balloon_iconsize);
3214                                         break;
3215                                 }
3216
3217                                 case ToolTipIcon.Warning: {
3218                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxError, balloon_iconsize);
3219                                         break;
3220                                 }
3221
3222                                 case ToolTipIcon.Error: {
3223                                         image = ThemeEngine.Current.Images(UIIcon.MessageBoxWarning, balloon_iconsize);
3224                                         break;
3225                                 }
3226                                 
3227                                 default: {
3228                                         image = null;
3229                                         break;
3230                                 }
3231                         }
3232
3233                         if (control.Icon != ToolTipIcon.None)
3234                                 dc.DrawImage (image, new Rectangle (balloon_bordersize, (2*balloon_bordersize)+7, iconsize, iconsize));
3235                         
3236                         // Title
3237                         Rectangle titlerect = new Rectangle (rect.X + balloon_bordersize + (balloon_iconsize/2) + balloon_bordersize, 
3238                                                                                                 rect.Y + balloon_bordersize, 
3239                                                                                                 rect.Width - ((3 * balloon_bordersize) + (balloon_iconsize/2)), 
3240                                                                                                 rect.Height - (2 * balloon_bordersize));
3241                         
3242                         Font titlefont = new Font (control.Font.FontFamily, control.Font.Size, control.Font.Style | FontStyle.Bold, control.Font.Unit);
3243                         dc.DrawString (control.Title, titlefont, solidbrush, titlerect, control.Format);
3244                         
3245                         // Text
3246                         Rectangle textrect = new Rectangle (rect.X + (2 * balloon_bordersize) + balloon_iconsize, 
3247                                                                                                 rect.Y + balloon_bordersize, 
3248                                                                                                 rect.Width - ((2 * balloon_bordersize) + balloon_iconsize), 
3249                                                                                                 rect.Height - (2 * balloon_bordersize));
3250
3251                         StringFormat textformat = control.Format;
3252                         textformat.LineAlignment = StringAlignment.Far;
3253                         dc.DrawString (control.Text, control.Font, solidbrush, textrect, textformat);
3254                 }
3255
3256                 public override Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control)
3257                 {
3258                         Rectangle deskrect = Screen.GetWorkingArea (control);
3259                         SizeF maxsize = new SizeF (250, 200);
3260
3261                         SizeF titlesize = TextRenderer.MeasureString (control.Title, control.Font, maxsize, control.Format);
3262                         SizeF textsize = TextRenderer.MeasureString (control.Text, control.Font, maxsize, control.Format);
3263                         
3264                         if (textsize.Height < balloon_iconsize)
3265                                 textsize.Height = balloon_iconsize;
3266                         
3267                         Rectangle rect = new Rectangle ();
3268                         rect.Height = (int) (titlesize.Height + textsize.Height + (3 * balloon_bordersize));
3269                         rect.Width = (int) ((titlesize.Width > textsize.Width) ? titlesize.Width : textsize.Width) + (3 * balloon_bordersize) + balloon_iconsize;
3270                         rect.X = deskrect.Width - rect.Width - 2;
3271                         rect.Y = deskrect.Height - rect.Height - 2;
3272                         
3273                         return rect;
3274                 }
3275                 #endregion      // BalloonWindow
3276                 
3277         } //class
3278 }
3279
3280