* ThemeClearlooks.cs, FileDialog.cs:
[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) 2004-2005 Novell, Inc.
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 //      - RadioButton !?!
33 //      - TabControl: TabAlignment.Left and TabAlignment.Bottom
34 //      - if an other control draws over a ScrollBar button you can see artefacts on the rounded edges 
35 //        (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)
36 //      - correct drawing of disabled controls (for example ComboBox... )
37
38 using System.Drawing;
39 using System.Drawing.Drawing2D;
40 using System.Drawing.Imaging;
41 using System.Drawing.Text;
42
43 namespace System.Windows.Forms {
44         internal class ThemeClearlooks : ThemeWin32Classic {
45                 public override Version Version {
46                         get {
47                                 return new Version( 0, 0, 0, 1 );
48                         }
49                 }
50                 
51                 static readonly Color theme_back_color = Color.FromArgb( 239, 235, 231 );
52                 
53                 static readonly Color gradient_first_color = Color.FromArgb( 250, 248, 247 );
54                 static readonly Color gradient_second_color = Color.FromArgb( 226, 219, 212 );
55                 static readonly Color gradient_second_color_nr2 = Color.FromArgb( 234, 229, 224 );
56                 static readonly Color pressed_gradient_first_color = Color.FromArgb( 217, 207, 202 );
57                 static readonly Color pressed_gradient_second_color = Color.FromArgb( 199, 193, 187 );
58                 static readonly Color border_normal_dark_color = Color.FromArgb( 129, 117, 106 );
59                 static readonly Color border_normal_light_color = Color.FromArgb( 158, 145, 131 );
60                 static readonly Color border_pressed_dark_color = Color.FromArgb( 109, 103, 98 );
61                 static readonly Color border_pressed_light_color = Color.FromArgb( 120, 114, 107 );
62                 static readonly Color button_outer_border_dark_color = Color.FromArgb( 232, 226, 220 );
63                 static readonly Color button_outer_border_light_color = Color.FromArgb( 250, 248, 247 ); 
64                 static readonly Color inner_border_dark_color = Color.FromArgb( 226, 219, 212 );
65                 static readonly Color pressed_inner_border_dark_color = Color.FromArgb( 192, 181, 169 );
66                 static readonly Color edge_top_inner_color = Color.FromArgb( 206, 200, 194 );
67                 static readonly Color edge_bottom_inner_color = Color.FromArgb( 215, 209, 202 );
68                 static readonly Color button_edge_top_outer_color = Color.FromArgb( 237, 233, 228 );
69                 static readonly Color button_edge_bottom_outer_color = Color.FromArgb( 243, 239, 236 );
70                 static readonly Color button_focus_color = Color.FromArgb( 101, 94, 86 );
71                 static readonly Color button_mouse_entered_second_gradient_color = Color.FromArgb( 230, 226, 219 );
72                 
73                 static readonly Color scrollbar_background_color = Color.FromArgb( 209, 200, 191 );
74                 static readonly Color scrollbar_border_color = Color.FromArgb( 170, 156, 143 );
75                 static readonly Color scrollbar_gradient_first_color = Color.FromArgb( 248, 247, 245 );
76                 static readonly Color scrollbar_gradient_second_color = Color.FromArgb( 234, 229, 224 );
77                 
78                 static readonly Color arrow_color = Color.FromArgb( 16, 16, 16 );
79                 
80                 static readonly Color tab_border_color = Color.FromArgb( 166, 151, 138 );
81                 static readonly Color tab_not_selected_gradient_first_color = Color.FromArgb( 227, 223, 220 );
82                 static readonly Color tab_not_selected_gradient_second_color = Color.FromArgb( 214, 209, 204 );
83                 static readonly Color tab_selected_gradient_first_color = Color.FromArgb( 243, 239, 236 );
84                 static readonly Color tab_selected_gradient_second_color = Color.FromArgb( 234, 228, 223 );
85                 static readonly Color tab_edge_color = Color.FromArgb( 200, 196, 191 );
86                 static readonly Color tab_inner_border_color = Color.FromArgb( 221, 212, 205 );
87                 static readonly Color tab_top_border_focus_color = Color.FromArgb( 70, 91, 110 );
88                 static readonly Color tab_focus_color = Color.FromArgb( 105, 147, 185 );
89                 
90                 static readonly Color menuitem_gradient_first_color = Color.FromArgb( 98, 140, 178 );
91                 static readonly Color menuitem_gradient_second_color = Color.FromArgb( 81, 113, 142 );
92                 static readonly Color menuitem_border_color = Color.FromArgb( 80, 112, 141 );
93                 static readonly Color menu_separator_color = Color.FromArgb( 219, 211, 203 );
94                 static readonly Color menu_background_color = Color.FromArgb( 248, 245, 242 );
95                 static readonly Color menu_border_color = Color.FromArgb( 141, 122, 104 );
96                 static readonly Color menu_inner_border_color = Color.FromArgb( 236, 228, 221 );
97                 
98                 static readonly Color combobox_border_color = Color.FromArgb( 159, 146, 132 );
99                 static readonly Color combobox_focus_border_color = Color.FromArgb( 70, 91, 110 );
100                 static readonly Color combobox_focus_inner_border_color = Color.FromArgb( 167, 198, 225 );
101                 static readonly Color combobox_button_second_gradient_color = Color.FromArgb( 226, 220, 213 );
102                 
103                 static readonly Color progressbar_edge_dot_color = Color.FromArgb( 219, 212, 205 );
104                 static readonly Color progressbar_inner_border_color = Color.FromArgb( 139, 176, 209 );
105                 static readonly Color progressbar_first_gradient_color = Color.FromArgb( 104, 146, 184 );
106                 static readonly Color progressbar_second_gradient_color = Color.FromArgb( 91, 133, 172 );
107                 
108                 static readonly Color checkbox_inner_boder_color = Color.FromArgb( 237, 234, 231 );
109                 static readonly Color checkbox_pressed_inner_boder_color = Color.FromArgb( 203, 196, 189 );
110                 static readonly Color checkbox_pressed_backcolor = Color.FromArgb( 212, 207, 202 );
111                 
112                 static readonly Color trackbar_second_gradient_color = Color.FromArgb( 114, 154, 190 );
113                 static readonly Color trackbar_third_gradient_color = Color.FromArgb( 130, 168, 202 );
114                 static readonly Color trackbar_inner_first_gradient_color = Color.FromArgb( 238, 233, 229 );
115                 static readonly Color trackbar_inner_second_gradient_color = Color.FromArgb( 223, 215, 208 );
116                 static readonly Color trackbar_inner_pressed_second_gradient_color = Color.FromArgb( 224, 217, 210 );
117                 
118                 static readonly Color disabled_color_foreground = Color.FromArgb( 182, 180, 173 );
119                 
120                 const int SEPARATOR_HEIGHT = 7;
121                 const int MENU_TAB_SPACE = 8;           // Pixels added to the width of an item because of a tab
122                 const int MENU_BAR_ITEMS_SPACE = 8;     // Space between menu bar items
123                 
124                 int platform = (int) Environment.OSVersion.Platform;
125                 
126                 #region Principal Theme Methods
127                 public ThemeClearlooks( ) {
128                         ColorControl = theme_back_color;
129                         always_draw_hotkeys = true;
130                 }
131                 
132                 public override Color DefaultControlBackColor {
133                         get { return theme_back_color; }
134                 }
135                 
136                 public override Color DefaultWindowBackColor {
137                         get { return theme_back_color; }                        
138                 }
139                 
140                 public override Color ColorControl {
141                         get { return theme_back_color;}
142                 }
143                 
144                 public override Color ColorHighlight {
145                         get { return menuitem_gradient_first_color; }
146                 }
147                 
148                 public override Size Border3DSize {
149                         get {
150                                 return new Size( 3, 3 );
151                         }
152                 }
153                 
154                 public override Image Images(UIIcon index, int size) {
155                         switch (index) {
156                         case UIIcon.PlacesRecentDocuments:
157                                 if ((platform == 4) || (platform == 128))
158                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "recently/recently", new Size(size, size) );
159                                 else
160                                         return base.Images (UIIcon.PlacesRecentDocuments, size);
161                         case UIIcon.PlacesDesktop:
162                                 if ((platform == 4) || (platform == 128))
163                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "desktop/desktop", new Size(size, size) );
164                                 else
165                                         return base.Images (UIIcon.PlacesDesktop, size);
166                         case UIIcon.PlacesPersonal:
167                                 if ((platform == 4) || (platform == 128))
168                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "directory/home", new Size(size, size) );
169                                 else
170                                         return base.Images (UIIcon.PlacesPersonal, size);
171                         case UIIcon.PlacesMyComputer:
172                                 if ((platform == 4) || (platform == 128))
173                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "workplace/workplace", new Size(size, size) );
174                                 else
175                                         return base.Images (UIIcon.PlacesMyComputer, size);
176                         case UIIcon.PlacesMyNetwork:
177                                 if ((platform == 4) || (platform == 128))
178                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "network/network", new Size(size, size) );
179                                 else
180                                         return base.Images (UIIcon.PlacesMyNetwork, size);
181                                 
182                                 // Icons for message boxes
183                         case UIIcon.MessageBoxError:            return base.Images (UIIcon.MessageBoxError, size);
184                         case UIIcon.MessageBoxInfo:             return base.Images (UIIcon.MessageBoxInfo, size);
185                         case UIIcon.MessageBoxQuestion:         return base.Images (UIIcon.MessageBoxQuestion, size);
186                         case UIIcon.MessageBoxWarning:          return base.Images (UIIcon.MessageBoxWarning, size);
187                                 
188                                 // misc Icons
189                         case UIIcon.NormalFolder:
190                                 if ((platform == 4) || (platform == 128))
191                                         return MimeIconEngine.GetIconForMimeTypeAndSize( "inode/directory", new Size(size, size) );
192                                 else
193                                         return base.Images (UIIcon.NormalFolder, size);
194                                 
195                         default: {
196                                         throw new ArgumentException("Invalid Icon type requested", "index");
197                                 }
198                         }
199                 }
200                 #endregion      // Internal Methods
201                 
202                 #region ButtonBase
203                 // FIXME: button style flat ?
204                 protected override void ButtonBase_DrawButton( ButtonBase button, Graphics dc ) {
205                         Rectangle buttonRectangle;
206                         
207                         int width = button.ClientSize.Width;
208                         int height = button.ClientSize.Height;
209                         
210                         dc.FillRectangle( ResPool.GetSolidBrush( button.BackColor ), button.ClientRectangle );
211                         
212                         // set up the button rectangle
213                         buttonRectangle = button.ClientRectangle;
214                         
215                         Color first_gradient_color = button.has_focus ? Color.LightYellow : Color.White;
216                         Color second_gradient_color = Color.White;
217                         
218                         if ( ( ( button is CheckBox ) && ( ( (CheckBox)button ).check_state == CheckState.Checked ) ) ||
219                             ( ( button is RadioButton ) && ( ( (RadioButton)button ).check_state == CheckState.Checked ) ) ) {
220                                 first_gradient_color = button.is_entered ? gradient_second_color : pressed_gradient_first_color;
221                                 second_gradient_color = button.is_entered  ? gradient_second_color : pressed_gradient_second_color;
222                         } else
223                         if ( !button.is_enabled ) {
224                                 first_gradient_color = gradient_first_color;
225                                 second_gradient_color = gradient_second_color;
226                                 button.is_entered = false;
227                         } else
228                         if ( !button.is_entered ) {
229                                 first_gradient_color = gradient_first_color;
230                                 second_gradient_color = gradient_second_color;
231                         } else {
232                                 if ( !button.is_pressed ) {
233                                         first_gradient_color = Color.White;
234                                         second_gradient_color = button_mouse_entered_second_gradient_color;
235                                 } else {
236                                         first_gradient_color = pressed_gradient_first_color;
237                                         second_gradient_color = pressed_gradient_second_color;
238                                 }
239                         }
240                         
241                         Rectangle lgbRectangle = new Rectangle( buttonRectangle.X + 3, buttonRectangle.Y + 3, button.is_pressed ? buttonRectangle.Width - 5 : buttonRectangle.Width - 6, buttonRectangle.Height - 6 );
242                         
243                         if ( button.flat_style != FlatStyle.Popup || ( ( button.flat_style == FlatStyle.Popup ) && button.is_entered ) ) {
244                                 LinearGradientBrush lgbr;
245                                 if ( button.flat_style == FlatStyle.Flat )
246                                         lgbr = new LinearGradientBrush( new Point( 0, 3 ), new Point( 0, height - 3 ), second_gradient_color, first_gradient_color );
247                                 else
248                                         lgbr = new LinearGradientBrush( new Point( 0, 3 ), new Point( 0, height - 3 ), first_gradient_color, second_gradient_color );
249                                 dc.FillRectangle( lgbr, lgbRectangle );
250                                 lgbr.Dispose( );
251                                 
252                                 Point[] points_top = {
253                                         new Point( 2, 2 ),
254                                         new Point( 3, 1 ),
255                                         new Point( width - 4, 1 ),
256                                         new Point( width - 3 , 2 )
257                                 };
258                                 
259                                 Point[] points_bottom = {
260                                         new Point( 2, height - 3 ),
261                                         new Point( 3, height - 2 ),
262                                         new Point( width - 4, height - 2 ),
263                                         new Point( width - 3, height - 3 )
264                                 };
265                                 
266                                 Point[] points_top_outer = {
267                                         new Point( 1, 1 ),
268                                         new Point( 2, 0 ),
269                                         new Point( width - 3, 0 ),
270                                         new Point( width - 2 , 1 )
271                                 };
272                                 
273                                 Point[] points_bottom_outer = {
274                                         new Point( 1, height - 2 ),
275                                         new Point( 2, height - 1 ),
276                                         new Point( width - 3, height - 1 ),
277                                         new Point( width - 2, height - 2 )
278                                 };
279                                 
280                                 Pen pen = null; 
281                                 
282                                 // normal border
283                                 if ( button.is_enabled ) { 
284                                         bool paint_acceptbutton_black_border = false;
285                                         Form form = button.TopLevelControl as Form;
286                                         
287                                         if ( form != null && ( form.AcceptButton == button as IButtonControl ) )
288                                                 paint_acceptbutton_black_border = true;
289                                         
290                                         Color top_color = Color.Black;
291                                         Color bottom_color = Color.Black;
292                                         
293                                         if ( !paint_acceptbutton_black_border ) {
294                                                 top_color = button.is_pressed ? border_pressed_dark_color : border_normal_dark_color;
295                                                 bottom_color = button.is_pressed ? border_pressed_light_color : border_normal_light_color;
296                                         }
297                                         
298                                         pen = ResPool.GetPen( top_color );
299                                         dc.DrawLines( pen, points_top );
300                                         pen = ResPool.GetPen( bottom_color );
301                                         dc.DrawLines( pen, points_bottom );
302                                         
303                                         using ( LinearGradientBrush lgbr2 = new LinearGradientBrush( new Point( 0, 3 ), new Point( 0, height - 3 ), top_color, bottom_color ) ) {
304                                                 dc.FillRectangle( lgbr2, 1, 3, 1, height - 6 );
305                                                 dc.FillRectangle( lgbr2, width - 2, 3, 1, height - 6 );
306                                         }
307                                 } else {
308                                         Point[] points_button_complete = {
309                                                 new Point( 1, 3 ),
310                                                 new Point( 3, 1 ),
311                                                 new Point( width - 4, 1 ),
312                                                 new Point( width - 2, 3 ),
313                                                 new Point( width - 2, height - 4 ),
314                                                 new Point( width - 4, height - 2 ),
315                                                 new Point( 3, height - 2 ),
316                                                 new Point( 1, height - 4 ),
317                                                 new Point( 1, 3 )
318                                         };
319                                         
320                                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
321                                         dc.DrawLines( pen, points_button_complete );
322                                 }
323                                 
324                                 // outer border
325                                 pen = ResPool.GetPen( button_outer_border_dark_color );
326                                 dc.DrawLines( pen, points_top_outer );
327                                 pen = ResPool.GetPen( button_outer_border_light_color );
328                                 dc.DrawLines( pen, points_bottom_outer );
329                                 
330                                 using ( LinearGradientBrush lgbr2 = new LinearGradientBrush( new Point( 0, 2 ), new Point( 0, height - 1 ), button_outer_border_dark_color, button_outer_border_light_color ) ) {
331                                         dc.FillRectangle( lgbr2, 0, 2, 1, height - 4 );
332                                         dc.FillRectangle( lgbr2, width - 1, 2, 1, height - 4 );
333                                 }
334                                 
335                                 // inner border
336                                 pen = ResPool.GetPen( button.is_pressed ? pressed_inner_border_dark_color : inner_border_dark_color );
337                                 if ( !button.is_pressed ) {
338                                         dc.DrawLine( pen, width - 3, 3, width - 3, height - 4 );
339                                 }
340                                 dc.DrawLine( pen, 3, height - 3, width - 4, height - 3 );
341                                 pen = ResPool.GetPen( button.is_pressed ? pressed_inner_border_dark_color : Color.White );
342                                 dc.DrawLine( pen, 2, 3, 2, height - 4 );
343                                 dc.DrawLine( pen, 3 , 2, width - 4, 2 );
344                                 
345                                 // edges
346                                 pen = ResPool.GetPen( edge_top_inner_color );
347                                 dc.DrawLine( pen, 1, 2, 2, 1 );
348                                 dc.DrawLine( pen, width - 3, 1, width - 2, 2 );
349                                 
350                                 pen = ResPool.GetPen( button_edge_top_outer_color );
351                                 dc.DrawLine( pen, 0, 1, 1, 0 );
352                                 dc.DrawLine( pen, width - 2, 0, width - 1, 1 );
353                                 
354                                 pen = ResPool.GetPen( edge_bottom_inner_color );
355                                 dc.DrawLine( pen, 1, height - 3, 2, height - 2 );
356                                 dc.DrawLine( pen, width - 2, height - 3, width - 3, height - 2 );
357                                 
358                                 pen = ResPool.GetPen( button_edge_bottom_outer_color );
359                                 dc.DrawLine( pen, 0, height - 2, 1, height - 1 );
360                                 dc.DrawLine( pen, width - 1, height - 2, width - 2, height - 1 );
361                         }
362                 }
363                 
364                 protected override void ButtonBase_DrawFocus( ButtonBase button, Graphics dc ) {
365                         
366                         if ( !button.is_enabled || button.flat_style == FlatStyle.Popup )
367                                 return;
368                         
369                         Pen pen = ResPool.GetPen( button_focus_color );
370                         DashStyle old_dash_style = pen.DashStyle;
371                         pen.DashStyle = DashStyle.Dot;
372                         
373                         Rectangle focus_rect = new Rectangle( button.ClientRectangle.X + 4, button.ClientRectangle.Y + 4, button.ClientRectangle.Width - 9, button.ClientRectangle.Height - 9 );
374                         
375                         dc.DrawRectangle( pen, focus_rect );
376                         
377                         pen.DashStyle = old_dash_style;
378                 }
379                 
380                 protected override void ButtonBase_DrawText( ButtonBase button, Graphics dc ) {
381                         if ( !( button is CheckBox ) && !( button is RadioButton ) ) {
382                                 Rectangle buttonRectangle = button.ClientRectangle;
383                                 Rectangle text_rect = Rectangle.Inflate( buttonRectangle, -4, -4 );
384                                 
385                                 string text = button.Text;
386                                 
387                                 if ( text.Length > 1 ) {
388                                         SizeF sizef = dc.MeasureString( text, button.Font, text_rect.Width, button.text_format );
389                                         
390                                         if ( (int)sizef.Width > text_rect.Width - 3 ) {
391                                                 for ( int i = 1; i < text.Length + 1; i++ ) {
392                                                         sizef = dc.MeasureString( text.Substring( 0, i ), button.Font, text_rect.Width, button.text_format );
393                                                         
394                                                         if ( (int)sizef.Width > text_rect.Width - 3 ) {
395                                                                 text = text.Substring( 0, i - 1 );
396                                                                 break;
397                                                         }
398                                                 }
399                                         }
400                                 }
401                                 
402                                 if ( button.is_pressed ) {
403                                         text_rect.X++;
404                                         text_rect.Y++;
405                                 }
406                                 
407                                 if ( button.is_enabled ) {                                      
408                                         dc.DrawString( text, button.Font, ResPool.GetSolidBrush( button.ForeColor ), text_rect, button.text_format );
409                                 } else {
410                                         if ( button.FlatStyle == FlatStyle.Flat || button.FlatStyle == FlatStyle.Popup ) {
411                                                 dc.DrawString( text, button.Font, ResPool.GetSolidBrush( ControlPaint.DarkDark( this.ColorControl ) ), text_rect, button.text_format );
412                                         } else {
413                                                 CPDrawStringDisabled( dc, text, button.Font, ColorControlText, text_rect, button.text_format );
414                                         }
415                                 }
416                         }
417                 }
418                 #endregion      // ButtonBase
419                 
420                 #region CheckBox
421                 protected override void CheckBox_DrawCheckBox( Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle ) {
422                         dc.FillRectangle( ResPool.GetSolidBrush( checkbox.BackColor ), checkbox.ClientRectangle );
423                         // render as per normal button
424                         if ( checkbox.appearance == Appearance.Button ) {
425                                 DrawButtonBase( dc, checkbox.ClientRectangle, checkbox );
426                         } else {
427                                 // establish if we are rendering a flat style of some sort
428                                 if ( checkbox.FlatStyle == FlatStyle.Flat || checkbox.FlatStyle == FlatStyle.Popup ) {
429                                         DrawFlatStyleCheckBox( dc, checkbox_rectangle, checkbox );
430                                 } else {
431                                         ControlPaint.DrawCheckBox( dc, checkbox_rectangle, state );
432                                 }
433                         }
434                 }
435                 #endregion      // CheckBox
436                 
437                 #region ComboBox
438                 
439                 // Drawing
440                 // FIXME: sometimes there are some artefacts left...
441                 public override void DrawComboBoxEditDecorations( Graphics dc, ComboBox ctrl, Rectangle cl ) {
442                         
443                         if ( !ctrl.Focused ) {
444                                 Pen tmp_pen = ResPool.GetPen( theme_back_color );
445                                 dc.DrawLine( tmp_pen, cl.X + 1, cl.Y + 1, cl.X + 1, cl.Bottom - 3 );
446                                 dc.DrawLine( tmp_pen, cl.X + 2, cl.Y + 1, cl.Right - 2, cl.Y + 1 );
447                                 
448                                 tmp_pen = ResPool.GetPen( ctrl.Parent.BackColor );
449                                 dc.DrawLine( tmp_pen, cl.X, cl.Y, cl.X, cl.Y + 1 );
450                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom - 2, cl.X, cl.Bottom - 3 );
451                                 dc.DrawLine( tmp_pen, cl.Right - 1, cl.Y, cl.Right - 1, cl.Y + 1 );
452                                 dc.DrawLine( tmp_pen, cl.Right - 1, cl.Bottom - 2, cl.Right - 1, cl.Bottom - 3 );
453                                 
454                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom, cl.Right, cl.Bottom );
455                                 
456                                 dc.DrawLine( tmp_pen, cl.X, cl.Y + cl.Height - 1, cl.X + cl.Width, cl.Y + cl.Height - 1 );
457                                 
458                                 Point[] points = {
459                                         new Point( cl.X + 2, cl.Y ),
460                                         new Point( cl.Right - 3, cl.Y ),
461                                         new Point( cl.Right - 1, cl.Y + 2 ),
462                                         new Point( cl.Right - 1, cl.Bottom - 4 ),
463                                         new Point( cl.Right - 3, cl.Bottom - 2 ),
464                                         new Point( cl.X + 2, cl.Bottom - 2 ),
465                                         new Point( cl.X, cl.Bottom - 4 ),
466                                         new Point( cl.X, cl.Y + 2 ),
467                                         new Point( cl.X + 2, cl.Y )
468                                 };
469                                 
470                                 dc.DrawLines( ResPool.GetPen( combobox_border_color ), points );
471                                 
472                                 tmp_pen = ResPool.GetPen( edge_bottom_inner_color );
473                                 dc.DrawLine( tmp_pen, cl.X, cl.Y + 1, cl.X + 1, cl.Y );
474                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom - 3, cl.X + 1, cl.Bottom - 2 );
475                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Y, cl.Right - 1, cl.Y + 1 );
476                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Bottom - 2, cl.Right - 1, cl.Bottom - 3 );
477                         } else { 
478                                 Pen tmp_pen = ResPool.GetPen( combobox_focus_inner_border_color );
479                                 
480                                 dc.DrawLine( tmp_pen, cl.X + 1, cl.Y + 1, cl.X + 1, cl.Bottom - 3 );
481                                 dc.DrawLine( tmp_pen, cl.X + 2, cl.Y + 1, cl.Right - 2, cl.Y + 1 );
482                                 dc.DrawLine( tmp_pen, cl.X + 2, cl.Bottom - 3, cl.Right - 2, cl.Bottom - 3 );
483                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Y + 1, cl.Right - 2, cl.Bottom - 3 );
484                                 
485                                 tmp_pen = ResPool.GetPen( ctrl.Parent.BackColor );
486                                 dc.DrawLine( tmp_pen, cl.X, cl.Y, cl.X, cl.Y + 1 );
487                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom - 2, cl.X, cl.Bottom - 3 );
488                                 dc.DrawLine( tmp_pen, cl.Right - 1, cl.Y, cl.Right - 1, cl.Y + 1 );
489                                 dc.DrawLine( tmp_pen, cl.Right - 1, cl.Bottom - 2, cl.Right - 1, cl.Bottom - 3 );
490                                 
491                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom, cl.Right, cl.Bottom );
492                                 
493                                 dc.DrawLine( tmp_pen, cl.X, cl.Y + cl.Height - 1, cl.X + cl.Width, cl.Y + cl.Height - 1 );
494                                 
495                                 Point[] points = {
496                                         new Point( cl.X + 2, cl.Y ),
497                                         new Point( cl.Right - 3, cl.Y ),
498                                         new Point( cl.Right - 1, cl.Y + 2 ),
499                                         new Point( cl.Right - 1, cl.Bottom - 4 ),
500                                         new Point( cl.Right - 3, cl.Bottom - 2 ),
501                                         new Point( cl.X + 2, cl.Bottom - 2 ),
502                                         new Point( cl.X, cl.Bottom - 4 ),
503                                         new Point( cl.X, cl.Y + 2 ),
504                                         new Point( cl.X + 2, cl.Y )
505                                 };
506                                 
507                                 dc.DrawLines( ResPool.GetPen( combobox_focus_border_color ), points );
508                                 
509                                 tmp_pen = ResPool.GetPen( edge_bottom_inner_color );
510                                 dc.DrawLine( tmp_pen, cl.X, cl.Y + 1, cl.X + 1, cl.Y );
511                                 dc.DrawLine( tmp_pen, cl.X, cl.Bottom - 3, cl.X + 1, cl.Bottom - 2 );
512                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Y, cl.Right - 1, cl.Y + 1 );
513                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Bottom - 2, cl.Right - 1, cl.Bottom - 3 );
514                         }
515                         
516                         // FIXME:
517                         // here we need to draw the combobox button again,
518                         // as DrawComboBoxEditDecorations paints over a fullsize combox button
519                         // ComboBox code calls CPDrawComboButton first then DrawComboBoxEditDecorations
520                         // a fix should go to ComboBox
521                         
522                         if ( ctrl.combobox_info.show_button )
523                                 CPDrawComboButton( dc, ctrl.combobox_info.button_rect, ctrl.combobox_info.button_status );
524                         else {
525                                 // quick and ugly fix for combobox artefacts on the inner border of the right side if no button gets drawn
526                                 Pen tmp_pen = ResPool.GetPen( Color.White );
527                                 dc.DrawLine( tmp_pen, cl.Right - 2, cl.Y + 2, cl.Right - 2, cl.Bottom - 4 );
528                         }
529                 }
530                 
531                 public override void DrawComboListBoxDecorations( Graphics dc, ComboBox ctrl, Rectangle cl ) {
532                         if ( ctrl.DropDownStyle == ComboBoxStyle.Simple ) {
533                                 DrawComboBoxEditDecorations( dc, ctrl, cl );
534                         } else {
535                                 dc.DrawRectangle( ResPool.GetPen( ThemeEngine.Current.ColorWindowFrame ), cl.X, cl.Y, cl.Width - 1, cl.Height - 1 );
536                         }
537                 }               
538                 #endregion ComboBox
539                 
540                 #region Menus
541                 public override void CalcItemSize( Graphics dc, MenuItem item, int y, int x, bool menuBar ) {
542                         item.X = x;
543                         item.Y = y;
544                         
545                         if ( item.Visible == false )
546                                 return;
547                         
548                         if ( item.Separator == true ) {
549                                 item.Height = SEPARATOR_HEIGHT / 2;
550                                 item.Width = -1;
551                                 return;
552                         }
553                         
554                         if ( item.MeasureEventDefined ) {
555                                 MeasureItemEventArgs mi = new MeasureItemEventArgs( dc, item.Index );
556                                 item.PerformMeasureItem( mi );
557                                 item.Height = mi.ItemHeight;
558                                 item.Width = mi.ItemWidth;
559                                 return;
560                         } else {                
561                                 SizeF size;
562                                 size =  dc.MeasureString( item.Text, ThemeEngine.Current.MenuFont );
563                                 item.Width = (int) size.Width;
564                                 item.Height = (int) size.Height;
565                                 
566                                 if ( !menuBar ) {
567                                         if ( item.Shortcut != Shortcut.None && item.ShowShortcut ) {
568                                                 item.XTab = ThemeEngine.Current.MenuCheckSize.Width + MENU_TAB_SPACE + (int) size.Width;
569                                                 size =  dc.MeasureString( " " + item.GetShortCutText( ), ThemeEngine.Current.MenuFont );
570                                                 item.Width += MENU_TAB_SPACE + (int) size.Width;
571                                         }
572                                         
573                                         item.Width += 4 + ( ThemeEngine.Current.MenuCheckSize.Width * 2 );
574                                 } else {
575                                         item.Width += MENU_BAR_ITEMS_SPACE;
576                                         x += item.Width;
577                                 }
578                                 
579                                 if ( item.Height < ThemeEngine.Current.MenuHeight )
580                                         item.Height = ThemeEngine.Current.MenuHeight;
581                         }
582                 }
583                 
584                 public override void DrawMenuItem( MenuItem item, DrawItemEventArgs e ) {
585                         StringFormat string_format;
586                         Rectangle rect_text = e.Bounds;
587                         
588                         if ( item.Visible == false )
589                                 return; 
590                         
591                         if ( item.MenuBar ) {
592                                 string_format = string_format_menu_menubar_text;
593                         } else {
594                                 string_format = string_format_menu_text;
595                         }
596                         
597                         if ( item.Separator ) {
598                                 e.Graphics.DrawLine( ThemeEngine.Current.ResPool.GetPen( menu_separator_color ),
599                                                     e.Bounds.X, e.Bounds.Y + 1, e.Bounds.X + e.Bounds.Right - 4, e.Bounds.Y + 1 );
600                                 
601                                 e.Graphics.DrawLine( ThemeEngine.Current.ResPool.GetPen( Color.White ),
602                                                     e.Bounds.X, e.Bounds.Y + 2, e.Bounds.X + e.Bounds.Right - 4, e.Bounds.Y + 2 );
603                                 
604                                 return;
605                         }
606                         
607                         if ( !item.MenuBar )
608                                 rect_text.X += ThemeEngine.Current.MenuCheckSize.Width;
609                         
610                         if ( item.BarBreak ) { /* Draw vertical break bar*/
611                                 Rectangle rect = e.Bounds;
612                                 rect.Y++;
613                                 rect.Width = 3;
614                                 rect.Height = item.MenuHeight - 6;
615                                 
616                                 e.Graphics.DrawLine( ThemeEngine.Current.ResPool.GetPen( menu_separator_color ),
617                                                     rect.X, rect.Y , rect.X, rect.Y + rect.Height );
618                                 
619                                 e.Graphics.DrawLine( ThemeEngine.Current.ResPool.GetPen( ThemeEngine.Current.ColorControlLight ),
620                                                     rect.X + 1, rect.Y , rect.X + 1, rect.Y + rect.Height );
621                         }
622                         
623                         Color color_text = ThemeEngine.Current.ColorMenuText;
624                         Color color_back;
625                         
626                         /* Draw background */
627                         Rectangle rect_back = e.Bounds;
628                         rect_back.X++;
629                         rect_back.Width -= 2;
630                         
631                         if ( ( e.State & DrawItemState.Selected ) == DrawItemState.Selected ) {
632                                 color_text = ThemeEngine.Current.ColorHighlightText;
633                                 color_back = item.MenuBar ? theme_back_color : menu_background_color;
634                                 
635                                 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 ) ) {
636                                         e.Graphics.FillRectangle( lgbr, rect_back.X + 1, rect_back.Y + 1, rect_back.Width - 1, rect_back.Height - 1 );
637                                 }
638                                 
639                                 rect_back.Height--;
640                                 Pen tmp_pen = ResPool.GetPen( menuitem_border_color );
641                                 e.Graphics.DrawLine( tmp_pen, rect_back.X + 1, rect_back.Y, rect_back.Right - 1, rect_back.Y );
642                                 e.Graphics.DrawLine( tmp_pen, rect_back.Right, rect_back.Y + 1, rect_back.Right, rect_back.Bottom - 1 );
643                                 e.Graphics.DrawLine( tmp_pen, rect_back.Right - 1, rect_back.Bottom, rect_back.X + 1, rect_back.Bottom );
644                                 e.Graphics.DrawLine( tmp_pen, rect_back.X, rect_back.Bottom - 1, rect_back.X, rect_back.Y + 1 );
645                         } else {
646                                 color_text = ThemeEngine.Current.ColorMenuText;
647                                 color_back = item.MenuBar ? theme_back_color : menu_background_color;
648                                 
649                                 e.Graphics.FillRectangle( ThemeEngine.Current.ResPool.GetSolidBrush( color_back ), rect_back );
650                         }
651                         
652                         if ( item.Enabled ) {
653                                 e.Graphics.DrawString( item.Text, e.Font,
654                                                       ThemeEngine.Current.ResPool.GetSolidBrush( color_text ),
655                                                       rect_text, string_format );
656                                 
657                                 if ( !item.MenuBar && item.Shortcut != Shortcut.None && item.ShowShortcut ) {
658                                         string str = item.GetShortCutText( );
659                                         Rectangle rect = rect_text;
660                                         rect.X = item.XTab;
661                                         rect.Width -= item.XTab;
662                                         
663                                         e.Graphics.DrawString( str, e.Font, ThemeEngine.Current.ResPool.GetSolidBrush( color_text ),
664                                                               rect, string_format_menu_shortcut );
665                                 }
666                         } else {
667                                 ControlPaint.DrawStringDisabled( e.Graphics, item.Text, e.Font,
668                                                                 Color.Black, rect_text, string_format );
669                         }
670                         
671                         /* Draw arrow */
672                         if ( item.MenuBar == false && item.IsPopup ) {
673                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
674                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
675                                 using ( Bitmap  bmp = new Bitmap( cx, cy ) ) {
676                                         using ( Graphics dc = Graphics.FromImage( bmp ) ) {
677                                                 SmoothingMode old_smoothing_mode = dc.SmoothingMode;
678                                                 dc.SmoothingMode = SmoothingMode.AntiAlias;
679                                                 
680                                                 Rectangle rect_arrow = new Rectangle( 0, 0, cx, cy );
681                                                 ControlPaint.DrawMenuGlyph( dc, rect_arrow, MenuGlyph.Arrow );
682                                                 bmp.MakeTransparent( );
683                                                 
684                                                 if ( item.Enabled ) {
685                                                         e.Graphics.DrawImage( bmp, e.Bounds.X + e.Bounds.Width - cx,
686                                                                              e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ) );
687                                                 } else {
688                                                         ControlPaint.DrawImageDisabled( e.Graphics, bmp, e.Bounds.X + e.Bounds.Width - cx,
689                                                                                        e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ),  color_back );
690                                                 }
691                                                 
692                                                 dc.SmoothingMode = old_smoothing_mode;
693                                         }
694                                 }
695                         }
696                         
697                         /* Draw checked or radio */
698                         if ( item.MenuBar == false && item.Checked ) {
699                                 
700                                 Rectangle area = e.Bounds;
701                                 int cx = ThemeEngine.Current.MenuCheckSize.Width;
702                                 int cy = ThemeEngine.Current.MenuCheckSize.Height;
703                                 using ( Bitmap bmp = new Bitmap( cx, cy ) ) {
704                                         using ( Graphics gr = Graphics.FromImage( bmp ) ) {
705                                                 Rectangle rect_arrow = new Rectangle( 0, 0, cx, cy );
706                                                 
707                                                 if ( item.RadioCheck )
708                                                         ControlPaint.DrawMenuGlyph( gr, rect_arrow, MenuGlyph.Bullet );
709                                                 else
710                                                         ControlPaint.DrawMenuGlyph( gr, rect_arrow, MenuGlyph.Checkmark );
711                                                 
712                                                 bmp.MakeTransparent( );
713                                                 e.Graphics.DrawImage( bmp, area.X, e.Bounds.Y + ( ( e.Bounds.Height - cy ) / 2 ) );
714                                         }
715                                 }
716                         }
717                 }
718                 
719                 public override void DrawPopupMenu( Graphics dc, Menu menu, Rectangle cliparea, Rectangle rect ) {
720                         
721                         dc.FillRectangle( ThemeEngine.Current.ResPool.GetSolidBrush
722                                          ( menu_background_color ), cliparea );
723                         
724                         /* Draw menu borders */
725                         dc.DrawRectangle( ResPool.GetPen( menu_border_color ), rect.X, rect.Y, rect.Width - 1, rect.Height - 1 );
726                         
727                         // inner border
728                         Pen tmp_pen = ResPool.GetPen( Color.White );
729                         dc.DrawLine( tmp_pen, rect.X + 1, rect.Y + 1, rect.Right - 2, rect.Y + 1 );
730                         dc.DrawLine( tmp_pen, rect.X + 1, rect.Y + 2, rect.X + 1, rect.Bottom - 2 );
731                         
732                         tmp_pen = ResPool.GetPen( menu_inner_border_color );
733                         dc.DrawLine( tmp_pen, rect.Right - 2, rect.Y + 2, rect.Right - 2, rect.Bottom - 2 );
734                         dc.DrawLine( tmp_pen, rect.Right - 3, rect.Bottom - 2, rect.X + 2, rect.Bottom - 2 );
735                         
736                         for ( int i = 0; i < menu.MenuItems.Count; i++ )
737                                 if ( cliparea.IntersectsWith( menu.MenuItems[ i ].bounds ) ) {
738                                         MenuItem item = menu.MenuItems[ i ];
739                                         item.MenuHeight = menu.Height;
740                                         item.PerformDrawItem( new DrawItemEventArgs( dc, ThemeEngine.Current.MenuFont,
741                                                                                     item.bounds, i, item.Status ) );
742                                 }
743                 }
744                 #endregion // Menus
745                 
746                 #region ProgressBar
747                 public override void DrawProgressBar( Graphics dc, Rectangle clip_rect, ProgressBar ctrl ) {
748                         Rectangle       client_area = ctrl.client_area;
749                         int             barpos_pixels;
750                         Rectangle bar = ctrl.client_area;
751                         
752                         barpos_pixels = ( ( ctrl.Value - ctrl.Minimum ) * client_area.Width ) / ( ctrl.Maximum - ctrl.Minimum );
753                         
754                         bar.Width = barpos_pixels + 1;
755                         
756                         // Draw bar background
757                         dc.FillRectangle( ResPool.GetSolidBrush( menu_separator_color ), ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.Width - 2, ctrl.ClientRectangle.Height - 2 );
758                         
759                         /* Draw border */
760                         Pen tmp_pen = ResPool.GetPen( progressbar_edge_dot_color );
761                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y + 1 );
762                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 2 );
763                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y + 1 );
764                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 2 );
765                         
766                         tmp_pen = ResPool.GetPen( scrollbar_border_color );
767                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Y, ctrl.ClientRectangle.Right - 2, ctrl.ClientRectangle.Y );
768                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.Right - 1, ctrl.ClientRectangle.Bottom - 2 );
769                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X + 1, ctrl.ClientRectangle.Bottom - 1, ctrl.ClientRectangle.Right - 2, ctrl.ClientRectangle.Bottom - 1 );
770                         dc.DrawLine( tmp_pen, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Y + 1, ctrl.ClientRectangle.X, ctrl.ClientRectangle.Bottom - 2 );
771                         
772                         if ( barpos_pixels == 0 )
773                                 return;
774                         
775                         // Draw bar
776                         dc.DrawRectangle( ResPool.GetPen( combobox_focus_border_color ), bar.X - 1, bar.Y - 1, bar.Width, bar.Height + 1 );
777                         tmp_pen = ResPool.GetPen( progressbar_inner_border_color );
778                         dc.DrawLine( tmp_pen, bar.X, bar.Y, bar.Right - 2, bar.Y );
779                         dc.DrawLine( tmp_pen, bar.X, bar.Y, bar.X, bar.Bottom - 1 );
780                         
781                         using ( Bitmap bmp = new Bitmap( bar.Width - 2, bar.Height - 1 ) ) {
782                                 using ( Graphics gr = Graphics.FromImage( bmp ) ) {
783                                         gr.FillRectangle( ResPool.GetSolidBrush( tab_focus_color ), 0, 0, bmp.Width, bmp.Height );
784                                         
785                                         LinearGradientBrush lgbr = new LinearGradientBrush( new Rectangle( 0, 0, bmp.Height, bmp.Height ), progressbar_first_gradient_color, progressbar_second_gradient_color, 0.0f, true );
786                                         
787                                         lgbr.RotateTransform( 45.0f, MatrixOrder.Append );
788                                         
789                                         float pen_width = bmp.Height / 2;
790                                         
791                                         Pen pen = new Pen( lgbr, pen_width );
792                                         
793                                         int add = bmp.Height + (int)pen.Width / 2;
794                                         
795                                         int x_top = 0;
796                                         int x_bottom = - bmp.Height;
797                                         
798                                         while ( x_bottom < bmp.Width ) {
799                                                 gr.DrawLine( pen, x_top, 0, x_bottom, bmp.Height );
800                                                 x_top += add;
801                                                 x_bottom += add;
802                                         }
803                                         pen.Dispose( );
804                                         lgbr.Dispose( );
805                                 }
806                                 
807                                 dc.DrawImage( bmp, bar.X + 1, bar.Y + 1 );
808                         }
809                 }
810                 #endregion      // ProgressBar
811                 
812                 #region RadioButton
813                 protected override void RadioButton_DrawButton( RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle ) {
814                         SolidBrush sb = new SolidBrush( radio_button.BackColor );
815                         dc.FillRectangle( sb, radio_button.ClientRectangle );
816                         sb.Dispose( );
817                         
818                         if ( radio_button.appearance == Appearance.Button ) {
819                                 if ( radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup ) {
820                                         DrawFlatStyleButton( dc, radio_button.ClientRectangle, radio_button );
821                                 } else {
822                                         DrawButtonBase( dc, radio_button.ClientRectangle, radio_button );
823                                 }
824                         } else {
825                                 // establish if we are rendering a flat style of some sort
826                                 if ( radio_button.FlatStyle == FlatStyle.Flat || radio_button.FlatStyle == FlatStyle.Popup ) {
827                                         DrawFlatStyleRadioButton( dc, radiobutton_rectangle, radio_button );
828                                 } else {
829                                         ControlPaint.DrawRadioButton( dc, radiobutton_rectangle, state );
830                                 }
831                         }
832                 }
833                 
834                 protected override void RadioButton_DrawFocus( RadioButton radio_button, Graphics dc, Rectangle text_rectangle ) {
835                         if ( radio_button.Focused && radio_button.appearance != Appearance.Button ) {
836                                 if ( radio_button.FlatStyle != FlatStyle.Flat && radio_button.FlatStyle != FlatStyle.Popup ) {
837                                         DrawInnerFocusRectangle( dc, text_rectangle, radio_button.BackColor );
838                                 } 
839                         }
840                 }
841                 #endregion      // RadioButton
842                 
843                 #region ScrollBar
844                 public override void DrawScrollBar( Graphics dc, Rectangle clip, ScrollBar bar ) {
845                         int             scrollbutton_width = bar.scrollbutton_width;
846                         int             scrollbutton_height = bar.scrollbutton_height;
847                         Rectangle       first_arrow_area;
848                         Rectangle       second_arrow_area;                      
849                         Rectangle       thumb_pos;
850                         
851                         thumb_pos = bar.ThumbPos;
852                         
853                         if ( bar.vert ) {
854                                 first_arrow_area = new Rectangle( 0, 0, bar.Width, scrollbutton_height + 1 );
855                                 bar.FirstArrowArea = first_arrow_area;
856                                 
857                                 second_arrow_area = new Rectangle( 0, bar.ClientRectangle.Height - scrollbutton_height - 1, bar.Width, scrollbutton_height + 1 );
858                                 bar.SecondArrowArea = second_arrow_area;
859                                 
860                                 thumb_pos.Width = bar.Width;
861                                 bar.ThumbPos = thumb_pos;
862                                 
863                                 /* Background */
864                                 switch ( bar.thumb_moving ) {
865                                         case ScrollBar.ThumbMoving.None: {
866                                                         ScrollBar_Vertical_Draw_ThumbMoving_None( scrollbutton_height, bar, clip, dc );
867                                                         break;
868                                                 }
869                                         case ScrollBar.ThumbMoving.Forward: {
870                                                         ScrollBar_Vertical_Draw_ThumbMoving_Forward( scrollbutton_height, bar, thumb_pos, clip, dc );
871                                                         break;
872                                                 }
873                                                 
874                                         case ScrollBar.ThumbMoving.Backwards: {
875                                                         ScrollBar_Vertical_Draw_ThumbMoving_Backwards( scrollbutton_height, bar, thumb_pos, clip, dc );
876                                                         break;
877                                                 }
878                                                 
879                                         default:
880                                                 break;
881                                 }
882                                 
883                                 /* Buttons */
884                                 if ( clip.IntersectsWith( first_arrow_area ) )
885                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Up, bar.firstbutton_state );
886                                 if ( clip.IntersectsWith( second_arrow_area ) )
887                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Down, bar.secondbutton_state );
888                         } else {
889                                 first_arrow_area = new Rectangle( 0, 0, scrollbutton_width + 1, bar.Height );
890                                 bar.FirstArrowArea = first_arrow_area;
891                                 
892                                 second_arrow_area = new Rectangle( bar.ClientRectangle.Width - scrollbutton_width - 1, 0, scrollbutton_width + 1, bar.Height );
893                                 bar.SecondArrowArea = second_arrow_area;
894                                 
895                                 thumb_pos.Height = bar.Height;
896                                 bar.ThumbPos = thumb_pos;
897                                 
898                                 /* Background */                                        
899                                 switch ( bar.thumb_moving ) {
900                                         case ScrollBar.ThumbMoving.None: {
901                                                         ScrollBar_Horizontal_Draw_ThumbMoving_None( scrollbutton_width, bar, clip, dc );
902                                                         break;
903                                                 }
904                                                 
905                                         case ScrollBar.ThumbMoving.Forward: {
906                                                         ScrollBar_Horizontal_Draw_ThumbMoving_Forward( scrollbutton_width, thumb_pos, bar, clip, dc );
907                                                         break;
908                                                 }
909                                                 
910                                         case ScrollBar.ThumbMoving.Backwards: {
911                                                         ScrollBar_Horizontal_Draw_ThumbMoving_Backwards( scrollbutton_width, thumb_pos, bar, clip, dc );
912                                                         break;
913                                                 }
914                                 }
915                                 
916                                 /* Buttons */
917                                 if ( clip.IntersectsWith( first_arrow_area ) )
918                                         CPDrawScrollButton( dc, first_arrow_area, ScrollButton.Left, bar.firstbutton_state );
919                                 if ( clip.IntersectsWith( second_arrow_area ) )
920                                         CPDrawScrollButton( dc, second_arrow_area, ScrollButton.Right, bar.secondbutton_state );
921                         }
922                         
923                         /* Thumb */
924                         ScrollBar_DrawThumb( bar, thumb_pos, clip, dc );                                
925                 }
926                 
927                 protected override void ScrollBar_DrawThumb( ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) {
928                         if ( bar.Enabled && thumb_pos.Width > 0 && thumb_pos.Height > 0 && clip.IntersectsWith( thumb_pos ) )
929                                 DrawScrollBarThumb( dc, thumb_pos, bar );
930                 }
931                 
932                 protected override void ScrollBar_Vertical_Draw_ThumbMoving_None( int scrollbutton_height, ScrollBar bar, Rectangle clip, Graphics dc ) {
933                         Rectangle r = new Rectangle( 0,
934                                                     scrollbutton_height, bar.ClientRectangle.Width, bar.ClientRectangle.Height - ( scrollbutton_height * 2 ) );
935                         Rectangle intersect = Rectangle.Intersect( clip, r );
936                         
937                         if ( intersect != Rectangle.Empty ) {
938                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
939                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
940                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.X, intersect.Bottom - 1 );
941                                 dc.DrawLine( pen, intersect.Right - 1, intersect.Y, intersect.Right - 1, intersect.Bottom - 1 );
942                         }
943                 }
944                 
945                 protected override void ScrollBar_Vertical_Draw_ThumbMoving_Forward( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) {
946                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
947                                                     bar.ClientRectangle.Width, thumb_pos.Y  - scrollbutton_height );
948                         Rectangle intersect = Rectangle.Intersect( clip, r );
949                         
950                         if ( intersect != Rectangle.Empty ) {
951                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
952                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
953                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.X, intersect.Bottom - 1 );
954                                 dc.DrawLine( pen, intersect.Right - 1, intersect.Y, intersect.Right - 1, intersect.Bottom - 1 );
955                         }
956                         
957                         r.X = 0;
958                         r.Y = thumb_pos.Y + thumb_pos.Height;
959                         r.Width = bar.ClientRectangle.Width;
960                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
961                         
962                         intersect = Rectangle.Intersect( clip, r );
963                         if ( intersect != Rectangle.Empty ) {
964                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
965                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
966                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.X, intersect.Bottom - 1 );
967                                 dc.DrawLine( pen, intersect.Right - 1, intersect.Y, intersect.Right - 1, intersect.Bottom - 1 );
968                         }
969                 }
970                 
971                 protected override void ScrollBar_Vertical_Draw_ThumbMoving_Backwards( int scrollbutton_height, ScrollBar bar, Rectangle thumb_pos, Rectangle clip, Graphics dc ) {
972                         Rectangle r = new Rectangle( 0,  scrollbutton_height,
973                                                     bar.ClientRectangle.Width, thumb_pos.Y - scrollbutton_height );
974                         Rectangle intersect = Rectangle.Intersect( clip, r );
975                         
976                         if ( intersect != Rectangle.Empty ) {
977                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
978                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
979                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.X, intersect.Bottom - 1 );
980                                 dc.DrawLine( pen, intersect.Right - 1, intersect.Y, intersect.Right - 1, intersect.Bottom - 1 );
981                         }
982                         
983                         r.X = 0;
984                         r.Y = thumb_pos.Y + thumb_pos.Height;
985                         r.Width = bar.ClientRectangle.Width;
986                         r.Height = bar.ClientRectangle.Height -  ( thumb_pos.Y + thumb_pos.Height ) - scrollbutton_height;
987                         
988                         intersect = Rectangle.Intersect( clip, r );
989                         if ( intersect != Rectangle.Empty ) {
990                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
991                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
992                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.X, intersect.Bottom - 1 );
993                                 dc.DrawLine( pen, intersect.Right - 1, intersect.Y, intersect.Right - 1, intersect.Bottom - 1 );
994                         }
995                 }
996                 
997                 protected override void ScrollBar_Horizontal_Draw_ThumbMoving_None( int scrollbutton_width, ScrollBar bar, Rectangle clip, Graphics dc ) {
998                         Rectangle r = new Rectangle( scrollbutton_width,
999                                                     0, bar.ClientRectangle.Width - ( scrollbutton_width * 2 ), bar.ClientRectangle.Height );
1000                         Rectangle intersect = Rectangle.Intersect( clip, r );
1001                         
1002                         if ( intersect != Rectangle.Empty ) {
1003                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
1004                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
1005                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.Right - 1, intersect.Y );
1006                                 dc.DrawLine( pen, intersect.X, intersect.Bottom - 1, intersect.Right - 1, intersect.Bottom - 1 );
1007                         }
1008                 }
1009                 
1010                 protected override void ScrollBar_Horizontal_Draw_ThumbMoving_Forward( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc ) {
1011                         Rectangle r = new Rectangle( scrollbutton_width,  0,
1012                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
1013                         Rectangle intersect = Rectangle.Intersect( clip, r );
1014                         
1015                         if ( intersect != Rectangle.Empty ) {
1016                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
1017                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
1018                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.Right - 1, intersect.Y );
1019                                 dc.DrawLine( pen, intersect.X, intersect.Bottom - 1, intersect.Right - 1, intersect.Bottom - 1 );
1020                         }
1021                         
1022                         r.X = thumb_pos.X + thumb_pos.Width;
1023                         r.Y = 0;
1024                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
1025                         r.Height = bar.ClientRectangle.Height;
1026                         
1027                         intersect = Rectangle.Intersect( clip, r );
1028                         if ( intersect != Rectangle.Empty ) {
1029                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
1030                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
1031                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.Right - 1, intersect.Y );
1032                                 dc.DrawLine( pen, intersect.X, intersect.Bottom - 1, intersect.Right - 1, intersect.Bottom - 1 );
1033                         }
1034                 }
1035                 
1036                 protected override void ScrollBar_Horizontal_Draw_ThumbMoving_Backwards( int scrollbutton_width, Rectangle thumb_pos, ScrollBar bar, Rectangle clip, Graphics dc ) {
1037                         Rectangle r = new Rectangle( scrollbutton_width,  0,
1038                                                     thumb_pos.X - scrollbutton_width, bar.ClientRectangle.Height );
1039                         Rectangle intersect = Rectangle.Intersect( clip, r );
1040                         
1041                         if ( intersect != Rectangle.Empty ) {
1042                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
1043                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
1044                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.Right - 1, intersect.Y );
1045                                 dc.DrawLine( pen, intersect.X, intersect.Bottom - 1, intersect.Right - 1, intersect.Bottom - 1 );
1046                         }
1047                         
1048                         r.X = thumb_pos.X + thumb_pos.Width;
1049                         r.Y = 0;
1050                         r.Width = bar.ClientRectangle.Width -  ( thumb_pos.X + thumb_pos.Width ) - scrollbutton_width;
1051                         r.Height = bar.ClientRectangle.Height;
1052                         
1053                         intersect = Rectangle.Intersect( clip, r );
1054                         if ( intersect != Rectangle.Empty ) {
1055                                 dc.FillRectangle( ResPool.GetSolidBrush( scrollbar_background_color ), intersect );
1056                                 Pen pen = ResPool.GetPen( scrollbar_border_color );
1057                                 dc.DrawLine( pen, intersect.X, intersect.Y, intersect.Right - 1, intersect.Y );
1058                                 dc.DrawLine( pen, intersect.X, intersect.Bottom - 1, intersect.Right - 1, intersect.Bottom - 1 );
1059                         }
1060                 }
1061                 #endregion      // ScrollBar
1062                 
1063                 #region StatusBar
1064                 protected override void DrawStatusBarPanel( Graphics dc, Rectangle area, int index,
1065                                                            SolidBrush br_forecolor, StatusBarPanel panel ) {
1066                         int border_size = 3; // this is actually const, even if the border style is none
1067                         
1068                         area.Height -= border_size;
1069                         if ( panel.BorderStyle != StatusBarPanelBorderStyle.None ) {
1070                                 dc.DrawRectangle( ResPool.GetPen( pressed_inner_border_dark_color ), area );
1071                         }
1072                         
1073                         if ( panel.Style == StatusBarPanelStyle.OwnerDraw ) {
1074                                 StatusBarDrawItemEventArgs e = new StatusBarDrawItemEventArgs(
1075                                         dc, panel.Parent.Font, area, index, DrawItemState.Default,
1076                                         panel, panel.Parent.ForeColor, panel.Parent.BackColor );
1077                                 panel.Parent.OnDrawItemInternal( e );
1078                                 return;
1079                         }
1080                         
1081                         int left = area.Left;
1082                         if ( panel.Icon != null ) {
1083                                 left += 2;
1084                                 dc.DrawIcon( panel.Icon, left, area.Top );
1085                                 left += panel.Icon.Width;
1086                         }
1087                         
1088                         if ( panel.Text == String.Empty )
1089                                 return;
1090                         
1091                         string text = panel.Text;
1092                         StringFormat string_format = new StringFormat( );
1093                         string_format.Trimming = StringTrimming.Character;
1094                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1095                         
1096                         if ( text[ 0 ] == '\t' ) {
1097                                 string_format.Alignment = StringAlignment.Center;
1098                                 text = text.Substring( 1 );
1099                                 if ( text[ 0 ] == '\t' ) {
1100                                         string_format.Alignment = StringAlignment.Far;
1101                                         text = text.Substring( 1 );
1102                                 }
1103                         }
1104                         
1105                         int x = left + border_size;
1106                         int y = border_size + 2;
1107                         Rectangle r = new Rectangle( x, y,
1108                                                     area.Right - x - border_size,
1109                                                     area.Bottom - y - border_size );
1110                         
1111                         dc.DrawString( text, panel.Parent.Font, br_forecolor, r, string_format );
1112                 }
1113                 #endregion      // StatusBar
1114                 
1115                 // FIXME: regions near the borders don't get filles with the correct backcolor
1116                 // TODO: TabAlignment.Left and TabAlignment.Bottom
1117                 public override void DrawTabControl( Graphics dc, Rectangle area, TabControl tab ) {
1118                         dc.FillRectangle( ResPool.GetSolidBrush( tab.Parent.BackColor ), area ); 
1119                         Rectangle panel_rect = GetTabPanelRectExt( tab );
1120                         
1121                         if ( tab.Appearance == TabAppearance.Normal ) {
1122                                 
1123                                 switch ( tab.Alignment ) {
1124                                         case TabAlignment.Top:
1125                                                 // inner border...
1126                                                 Pen pen = ResPool.GetPen( Color.White );
1127                                                 
1128                                                 dc.DrawLine( pen, panel_rect.Left + 1, panel_rect.Top, panel_rect.Left + 1, panel_rect.Bottom - 1 );
1129                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top , panel_rect.Right - 2, panel_rect.Top );
1130                                                 
1131                                                 pen = ResPool.GetPen( tab_inner_border_color );
1132                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Top + 1, panel_rect.Right - 2, panel_rect.Bottom - 2 );
1133                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Bottom - 1, panel_rect.Left + 2, panel_rect.Bottom - 1 );
1134                                                 
1135                                                 // border
1136                                                 pen = ResPool.GetPen( tab_border_color );
1137                                                 
1138                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Top - 1, panel_rect.Right - 1, panel_rect.Top - 1 );
1139                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Top - 1, panel_rect.Right - 1, panel_rect.Bottom - 2 );
1140                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Bottom - 2, panel_rect.Right - 3, panel_rect.Bottom );
1141                                                 dc.DrawLine( pen, panel_rect.Right - 3, panel_rect.Bottom, panel_rect.Left + 2, panel_rect.Bottom );
1142                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Bottom, panel_rect.Left, panel_rect.Bottom - 2 );
1143                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Bottom - 2, panel_rect.Left, panel_rect.Top - 1 );
1144                                                 break;
1145                                                 
1146                                                 // FIXME: the size of the tab page is to big to draw the upper inner white border
1147                                         case TabAlignment.Right:
1148                                                 // inner border...
1149                                                 pen = ResPool.GetPen( Color.White );
1150                                                 
1151                                                 dc.DrawLine( pen, panel_rect.Left + 1, panel_rect.Top + 1, panel_rect.Left + 1, panel_rect.Bottom - 1 );
1152                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top + 1 , panel_rect.Right - 2, panel_rect.Top + 1 );
1153                                                 
1154                                                 pen = ResPool.GetPen( tab_inner_border_color );
1155                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Top + 1, panel_rect.Right - 2, panel_rect.Bottom - 2 );
1156                                                 dc.DrawLine( pen, panel_rect.Right - 2, panel_rect.Bottom - 1, panel_rect.Left + 2, panel_rect.Bottom - 1 );
1157                                                 
1158                                                 // border
1159                                                 pen = ResPool.GetPen( tab_border_color );
1160                                                 
1161                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Top, panel_rect.Right - 1, panel_rect.Top );
1162                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Top, panel_rect.Right - 1, panel_rect.Bottom );
1163                                                 dc.DrawLine( pen, panel_rect.Right - 1, panel_rect.Bottom, panel_rect.Left + 2, panel_rect.Bottom );
1164                                                 dc.DrawLine( pen, panel_rect.Left + 2, panel_rect.Bottom, panel_rect.Left, panel_rect.Bottom - 2 );
1165                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Bottom - 2, panel_rect.Left, panel_rect.Top + 2 );
1166                                                 dc.DrawLine( pen, panel_rect.Left, panel_rect.Top + 2, panel_rect.Left + 2, panel_rect.Top );
1167                                                 break;
1168                                 }
1169                         }
1170                         
1171                         if ( tab.Alignment == TabAlignment.Top ) {
1172                                 for ( int r = tab.TabPages.Count; r > 0; r-- ) {
1173                                         for ( int i = tab.SliderPos; i < tab.TabPages.Count; i++ ) {
1174                                                 if ( i == tab.SelectedIndex )
1175                                                         continue;
1176                                                 if ( r != tab.TabPages[ i ].Row )
1177                                                         continue;
1178                                                 Rectangle rect = tab.GetTabRect( i );
1179                                                 if ( !rect.IntersectsWith( area ) )
1180                                                         continue;
1181                                                 DrawTab( dc, tab.TabPages[ i ], tab, rect, false );
1182                                         }
1183                                 }
1184                         } else {
1185                                 for ( int r = 0; r < tab.TabPages.Count; r++ ) {
1186                                         for ( int i = tab.SliderPos; i < tab.TabPages.Count; i++ ) {
1187                                                 if ( i == tab.SelectedIndex )
1188                                                         continue;
1189                                                 if ( r != tab.TabPages[ i ].Row )
1190                                                         continue;
1191                                                 Rectangle rect = tab.GetTabRect( i );
1192                                                 if ( !rect.IntersectsWith( area ) )
1193                                                         continue;
1194                                                 DrawTab( dc, tab.TabPages[ i ], tab, rect, false );
1195                                         }
1196                                 }
1197                         }
1198                         
1199                         if ( tab.SelectedIndex != -1 && tab.SelectedIndex >= tab.SliderPos ) {
1200                                 Rectangle rect = tab.GetTabRect( tab.SelectedIndex );
1201                                 if ( rect.IntersectsWith( area ) )
1202                                         DrawTab( dc, tab.TabPages[ tab.SelectedIndex ], tab, rect, true );
1203                         }
1204                         
1205                         if ( tab.ShowSlider ) {
1206                                 Rectangle right = GetTabControlRightScrollRect( tab );
1207                                 Rectangle left = GetTabControlLeftScrollRect( tab );
1208                                 CPDrawScrollButton( dc, right, ScrollButton.Right, tab.RightSliderState );
1209                                 CPDrawScrollButton( dc, left, ScrollButton.Left, tab.LeftSliderState );
1210                         }
1211                 }
1212                 
1213                 protected override int DrawTab( Graphics dc, TabPage page, TabControl tab, Rectangle bounds, bool is_selected ) {
1214                         int FlatButtonSpacing = 8;
1215                         Rectangle interior;
1216                         int res = bounds.Width;
1217                         
1218                         if ( page.BackColor != tab_selected_gradient_second_color )
1219                                 page.BackColor = tab_selected_gradient_second_color;
1220                         
1221                         // we can't fill the background right away because the bounds might be adjusted if the tab is selected
1222                         
1223                         if ( tab.Appearance == TabAppearance.Buttons || tab.Appearance == TabAppearance.FlatButtons ) {
1224                                 dc.FillRectangle( ResPool.GetSolidBrush( tab_selected_gradient_second_color ), bounds );
1225                                 
1226                                 // Separators
1227                                 if ( tab.Appearance == TabAppearance.FlatButtons ) {
1228                                         int width = bounds.Width;
1229                                         bounds.Width += ( FlatButtonSpacing - 2 );
1230                                         res = bounds.Width;
1231                                         CPDrawBorder3D( dc, bounds, Border3DStyle.Etched, Border3DSide.Right );
1232                                         bounds.Width = width;
1233                                 }
1234                                 
1235                                 if ( is_selected ) {
1236                                         CPDrawBorder3D( dc, bounds, Border3DStyle.Sunken, Border3DSide.All );
1237                                 } else if ( tab.Appearance != TabAppearance.FlatButtons ) {
1238                                         CPDrawBorder3D( dc, bounds, Border3DStyle.Raised, Border3DSide.All );
1239                                 }
1240                                 
1241                                 interior = new Rectangle( bounds.Left + 2, bounds.Top + 2, bounds.Width - 4, bounds.Height - 4 );
1242                                 
1243                                 
1244                                 StringFormat string_format = new StringFormat( );
1245                                 string_format.Alignment = StringAlignment.Center;
1246                                 string_format.LineAlignment = StringAlignment.Center;
1247                                 string_format.FormatFlags = StringFormatFlags.NoWrap;
1248                                 
1249                                 interior.Y++;
1250                                 dc.DrawString( page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush( SystemColors.ControlText ), interior, string_format );
1251                                 interior.Y--;
1252                         } else {
1253                                 Pen border_pen = ResPool.GetPen( tab_border_color );
1254                                 
1255                                 Color tab_first_color = is_selected ? tab_selected_gradient_first_color : tab_not_selected_gradient_first_color;
1256                                 Color tab_second_color = is_selected ? tab_selected_gradient_second_color : tab_not_selected_gradient_second_color;
1257                                 
1258                                 switch ( tab.Alignment ) {
1259                                         case TabAlignment.Top:
1260                                                 
1261                                                 interior = new Rectangle( bounds.Left + 2, bounds.Top + 2, bounds.Width - 2, bounds.Height - 3 );
1262                                                 
1263                                                 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 ) ) {
1264                                                         dc.FillRectangle( lgbr, interior );
1265                                                 }
1266                                                 
1267                                                 // edges
1268                                                 Pen tmp_pen = ResPool.GetPen( tab_edge_color );
1269                                                 dc.DrawLine( tmp_pen, bounds.Left, bounds.Top + 1, bounds.Left + 1, bounds.Top );
1270                                                 dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Top, bounds.Right, bounds.Top + 1 );
1271                                                 
1272                                                 // inner border
1273                                                 tmp_pen = ResPool.GetPen( Color.White );
1274                                                 dc.DrawLine( tmp_pen, bounds.Left + 1, bounds.Bottom - 2, bounds.Left + 1, bounds.Top + 1 );
1275                                                 dc.DrawLine( tmp_pen, bounds.Left + 2, bounds.Top + 1, bounds.Right - 1, bounds.Top + 1 );
1276                                                 
1277                                                 // border
1278                                                 tmp_pen = ResPool.GetPen( border_pressed_dark_color );
1279                                                 dc.DrawLine( tmp_pen, bounds.Left, bounds.Top + 2, bounds.Left + 2, bounds.Top );
1280                                                 dc.DrawLine( tmp_pen, bounds.Left + 2, bounds.Top, bounds.Right - 2, bounds.Top );
1281                                                 dc.DrawLine( tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right, bounds.Top + 2 );
1282                                                 
1283                                                 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 ) ) {
1284                                                         int diff = is_selected ? 4 : 3;
1285                                                         dc.FillRectangle( lgbr, bounds.Left, bounds.Top + 2, 1, bounds.Height - diff );
1286                                                         dc.FillRectangle( lgbr, bounds.Right, bounds.Top + 2, 1, bounds.Height - diff );
1287                                                 }
1288                                                 
1289                                                 if ( page.Focused ) {
1290                                                         tmp_pen = ResPool.GetPen( tab_focus_color );
1291                                                         dc.DrawLine( tmp_pen, bounds.Left + 1, bounds.Top  + 2, bounds.Right - 1, bounds.Top + 2 );
1292                                                         dc.DrawLine( tmp_pen, bounds.Left + 2, bounds.Top + 1, bounds.Right - 2, bounds.Top + 1 );
1293                                                         
1294                                                         tmp_pen = ResPool.GetPen( tab_top_border_focus_color );
1295                                                         dc.DrawLine( tmp_pen, bounds.Left, bounds.Top + 2, bounds.Left + 2, bounds.Top );
1296                                                         dc.DrawLine( tmp_pen, bounds.Left + 2, bounds.Top, bounds.Right - 2, bounds.Top );
1297                                                         dc.DrawLine( tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right, bounds.Top + 2 );
1298                                                 }
1299                                                 
1300                                                 interior = new Rectangle( bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8 );
1301                                                 
1302                                                 if ( page.Text != String.Empty ) {
1303                                                         StringFormat string_format = new StringFormat( );
1304                                                         string_format.Alignment = StringAlignment.Center;
1305                                                         string_format.LineAlignment = StringAlignment.Center;
1306                                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1307                                                         interior.Y++;
1308                                                         dc.DrawString( page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush( SystemColors.ControlText ), interior, string_format );
1309                                                         interior.Y--;
1310                                                 }
1311                                                 
1312                                                 break;
1313                                                 
1314                                         case TabAlignment.Bottom:
1315                                                 
1316                                                 interior = new Rectangle( bounds.Left + 3, bounds.Top, bounds.Width - 3, bounds.Height );
1317                                                 
1318                                                 using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( bounds.Left + 3, bounds.Top ), new Point( bounds.Left + 3, bounds.Bottom ), tab_first_color, tab_second_color ) ) {
1319                                                         dc.FillRectangle( lgbr, interior );
1320                                                 }
1321                                                 
1322                                                 dc.DrawLine( border_pen, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom - 3 );
1323                                                 dc.DrawLine( border_pen, bounds.Left, bounds.Bottom - 3, bounds.Left + 3, bounds.Bottom );
1324                                                 dc.DrawLine( border_pen, bounds.Left + 3, bounds.Bottom, bounds.Right - 3, bounds.Bottom );
1325                                                 dc.DrawLine( border_pen, bounds.Right - 3, bounds.Bottom, bounds.Right, bounds.Bottom - 3 );
1326                                                 dc.DrawLine( border_pen, bounds.Right, bounds.Bottom - 3, bounds.Right, bounds.Top );
1327                                                 
1328                                                 if ( page.Focused ) {
1329                                                         dc.DrawLine( ResPool.GetPen( Color.DarkOrange ), bounds.Left - 1 , bounds.Bottom, bounds.Right - 1, bounds.Bottom );
1330                                                         dc.DrawLine( ResPool.GetPen( Color.Orange ), bounds.Left , bounds.Bottom - 1, bounds.Right , bounds.Bottom - 1 );
1331                                                         dc.DrawLine( ResPool.GetPen( Color.Orange ), bounds.Left , bounds.Bottom - 2, bounds.Right , bounds.Bottom - 2 );
1332                                                 }
1333                                                 
1334                                                 interior = new Rectangle( bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8 );
1335                                                 
1336                                                 if ( page.Text != String.Empty ) {
1337                                                         StringFormat string_format = new StringFormat( );
1338                                                         string_format.Alignment = StringAlignment.Center;
1339                                                         string_format.LineAlignment = StringAlignment.Center;
1340                                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1341                                                         interior.Y++;
1342                                                         dc.DrawString( page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush( SystemColors.ControlText ), interior, string_format );
1343                                                         interior.Y--;
1344                                                 }
1345                                                 
1346                                                 break;
1347                                                 
1348                                         case TabAlignment.Left:
1349                                                 
1350                                                 interior = new Rectangle( bounds.Left + 2, bounds.Top + 2, bounds.Width - 2, bounds.Height - 2 );
1351                                                 
1352                                                 using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( bounds.Left + 2, bounds.Top + 2 ), new Point( bounds.Right, bounds.Top + 2 ), tab_first_color, tab_second_color ) ) {
1353                                                         dc.FillRectangle( lgbr, interior );
1354                                                 }
1355                                                 
1356                                                 dc.DrawLine( border_pen, bounds.Right, bounds.Top, bounds.Left + 3, bounds.Top );
1357                                                 dc.DrawLine( border_pen, bounds.Left + 3, bounds.Top, bounds.Left, bounds.Top + 3 );
1358                                                 dc.DrawLine( border_pen, bounds.Left, bounds.Top + 3, bounds.Left, bounds.Bottom - 3 );
1359                                                 dc.DrawLine( border_pen, bounds.Left, bounds.Bottom - 3, bounds.Left + 3, bounds.Bottom );
1360                                                 dc.DrawLine( border_pen, bounds.Left + 3, bounds.Bottom, bounds.Right, bounds.Bottom );
1361                                                 
1362                                                 if ( page.Focused ) {
1363                                                         dc.DrawLine( ResPool.GetPen( Color.DarkOrange ), bounds.Left , bounds.Top + 1, bounds.Left , bounds.Bottom - 1 );
1364                                                         dc.DrawLine( ResPool.GetPen( Color.Orange ), bounds.Left + 1 , bounds.Top, bounds.Left + 1 , bounds.Bottom );
1365                                                         dc.DrawLine( ResPool.GetPen( Color.Orange ), bounds.Left + 2 , bounds.Top, bounds.Left + 2 , bounds.Bottom );
1366                                                 }
1367                                                 
1368                                                 interior = new Rectangle( bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8 );
1369                                                 
1370                                                 if ( page.Text != String.Empty ) {
1371                                                         StringFormat string_format = new StringFormat( );
1372                                                         // Flip the text around
1373                                                         string_format.Alignment = StringAlignment.Center;
1374                                                         string_format.LineAlignment = StringAlignment.Center;
1375                                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1376                                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
1377                                                         int wo = interior.Width / 2;
1378                                                         int ho = interior.Height / 2;
1379                                                         dc.TranslateTransform( interior.X + wo, interior.Y + ho );
1380                                                         dc.RotateTransform( 180 );
1381                                                         dc.DrawString( page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush( SystemColors.ControlText ), 0, 0, string_format );
1382                                                         dc.ResetTransform( );
1383                                                 }
1384                                                 
1385                                                 break;
1386                                                 
1387                                         default:
1388                                                 // TabAlignment.Right
1389                                                 
1390                                                 interior = new Rectangle( bounds.Left, bounds.Top + 2, bounds.Width - 2, bounds.Height - 2 );
1391                                                 
1392                                                 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 ) ) {
1393                                                         dc.FillRectangle( lgbr, interior );
1394                                                 }
1395                                                 
1396                                                 int l_diff = is_selected ? 2 : 0;
1397                                                 
1398                                                 // edges
1399                                                 tmp_pen = ResPool.GetPen( tab_edge_color );
1400                                                 dc.DrawLine( tmp_pen, bounds.Right - 2, bounds.Top, bounds.Right - 1, bounds.Top + 1 );
1401                                                 dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Bottom - 1, bounds.Right - 2, bounds.Bottom );
1402                                                 
1403                                                 // inner border
1404                                                 tmp_pen = ResPool.GetPen( Color.White );
1405                                                 dc.DrawLine( tmp_pen, bounds.Left + l_diff, bounds.Top + 1, bounds.Right - 2, bounds.Top + 1 );
1406                                                 dc.DrawLine( tmp_pen, bounds.Right - 2, bounds.Top + 2, bounds.Right - 2, bounds.Bottom - 2 );
1407                                                 
1408                                                 // border
1409                                                 tmp_pen = ResPool.GetPen( border_pressed_dark_color );
1410                                                 dc.DrawLine( tmp_pen, bounds.Right - 3, bounds.Top, bounds.Right - 1, bounds.Top + 2 );
1411                                                 dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Top + 2, bounds.Right - 1, bounds.Bottom - 2 );
1412                                                 dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Bottom - 2, bounds.Right - 3, bounds.Bottom );
1413                                                 
1414                                                 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 ) ) {
1415                                                         int diff = is_selected ? 4 : 2;
1416                                                         
1417                                                         dc.FillRectangle( lgbr, bounds.Left + l_diff, bounds.Top, bounds.Width - diff, 1 );
1418                                                         dc.FillRectangle( lgbr, bounds.Left + l_diff, bounds.Bottom, bounds.Width - diff, 1 );
1419                                                 }
1420                                                 
1421                                                 if ( page.Focused ) {
1422                                                         tmp_pen = ResPool.GetPen( tab_focus_color );
1423                                                         dc.DrawLine( tmp_pen, bounds.Right - 3, bounds.Top + 1, bounds.Right - 3, bounds.Bottom - 1 );
1424                                                         dc.DrawLine( tmp_pen, bounds.Right - 2, bounds.Top + 2, bounds.Right - 2, bounds.Bottom - 2 );
1425                                                         
1426                                                         tmp_pen = ResPool.GetPen( tab_top_border_focus_color );
1427                                                         dc.DrawLine( tmp_pen, bounds.Right - 3, bounds.Top, bounds.Right - 1, bounds.Top + 2 );
1428                                                         dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Top + 2, bounds.Right - 1, bounds.Bottom - 2 );
1429                                                         dc.DrawLine( tmp_pen, bounds.Right - 1, bounds.Bottom - 2, bounds.Right - 3, bounds.Bottom );
1430                                                 }
1431                                                 
1432                                                 interior = new Rectangle( bounds.Left + 4, bounds.Top + 4, bounds.Width - 8, bounds.Height - 8 );
1433                                                 
1434                                                 if ( page.Text != String.Empty ) {
1435                                                         StringFormat string_format = new StringFormat( );
1436                                                         string_format.Alignment = StringAlignment.Center;
1437                                                         string_format.LineAlignment = StringAlignment.Center;
1438                                                         string_format.FormatFlags = StringFormatFlags.NoWrap;
1439                                                         string_format.FormatFlags = StringFormatFlags.DirectionVertical;
1440                                                         interior.X++;
1441                                                         dc.DrawString( page.Text, page.Font, ThemeEngine.Current.ResPool.GetSolidBrush( SystemColors.ControlText ), interior, string_format );
1442                                                         interior.X--;
1443                                                 }
1444                                                 
1445                                                 break;
1446                                 }
1447                         }
1448                         
1449                         return res;
1450                 }               
1451                 
1452                 public override void CPDrawComboButton( Graphics dc, Rectangle rectangle, ButtonState state ) {
1453                         Point[]                 arrow = new Point[ 3 ];
1454                         Point                           P1;
1455                         Point                           P2;
1456                         Point                           P3;
1457                         int                             centerX;
1458                         int                             centerY;
1459                         int                             shiftX;
1460                         int                             shiftY;
1461                         Rectangle               rect;
1462                         
1463                         bool pushed = false;
1464                         
1465                         Color first_color = Color.White;
1466                         Color second_color = combobox_button_second_gradient_color;
1467                         
1468                         if ( ( state & ButtonState.Checked ) != 0 ) {
1469                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControlLightLight, ColorControlLight ), rectangle );
1470                         } else
1471                                 dc.FillRectangle( ResPool.GetSolidBrush( Color.White ), rectangle );
1472                         
1473                         if ( ( state & ButtonState.Flat ) != 0 ) {
1474                                 first_color = gradient_first_color;
1475                                 second_color = combobox_button_second_gradient_color;
1476                         } else {
1477                                 if ( ( state & ( ButtonState.Pushed | ButtonState.Checked ) ) != 0 ) {
1478                                         first_color = pressed_gradient_first_color;
1479                                         second_color = pressed_gradient_second_color;
1480                                         pushed = true;
1481                                 }
1482                         }
1483                         
1484                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( rectangle.X, rectangle.Y ), new Point( rectangle.X, rectangle.Bottom ), first_color, second_color ) ) {
1485                                 dc.FillRectangle( lgbr, rectangle.X + 2, rectangle.Y, rectangle.Width - 2, rectangle.Height - 1 );
1486                         }
1487                         
1488                         // inner border
1489                         Pen tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1490                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y - 1, rectangle.Right, rectangle.Y - 1 );
1491                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y - 1, rectangle.X + 1, rectangle.Bottom - 1 );
1492                         
1493                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1494                         dc.DrawLine( tmp_pen, rectangle.Right, rectangle.Y, rectangle.Right, rectangle.Bottom - 1 );
1495                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Bottom - 1, rectangle.Right, rectangle.Bottom - 1 );
1496                         
1497                         // border
1498                         Point[] points = new Point[] {
1499                                 new Point( rectangle.X, rectangle.Y - 2 ),
1500                                 new Point( rectangle.Right - 1, rectangle.Y - 2 ),
1501                                 new Point( rectangle.Right + 1, rectangle.Y ),
1502                                 new Point( rectangle.Right + 1, rectangle.Bottom - 2 ),
1503                                 new Point( rectangle.Right - 1, rectangle.Bottom ),
1504                                 new Point( rectangle.X, rectangle.Bottom ),
1505                                 new Point( rectangle.X, rectangle.Y - 2 )
1506                         };
1507                         
1508                         dc.DrawPolygon( ResPool.GetPen( pushed ? border_pressed_dark_color : border_normal_dark_color ), points );
1509                         
1510                         rect = new Rectangle( rectangle.X + rectangle.Width / 4, rectangle.Y + rectangle.Height / 4, rectangle.Width / 2, rectangle.Height / 2 );
1511                         centerX = rect.Left + rect.Width / 2;
1512                         centerY = rect.Top + rect.Height / 2;
1513                         shiftX = Math.Max( 1, rect.Width / 8 );
1514                         shiftY = Math.Max( 1, rect.Height / 8 );
1515                         
1516                         if ( ( state & ButtonState.Pushed ) != 0 ) {
1517                                 shiftX--;
1518                                 shiftY--;
1519                         }
1520                         
1521                         rect.Y -= shiftY;
1522                         centerY -= shiftY;
1523                         
1524                         P1 = new Point( rect.Left, centerY );
1525                         P2 = new Point( centerX, rect.Bottom );
1526                         P3 = new Point( rect.Right, centerY );
1527                         
1528                         arrow[ 0 ] = P1;
1529                         arrow[ 1 ] = P2;
1530                         arrow[ 2 ] = P3;
1531                         
1532                         SmoothingMode old_smoothing_mode = dc.SmoothingMode;
1533                         dc.SmoothingMode = SmoothingMode.AntiAlias;
1534                         
1535                         /* Draw the arrow */
1536                         if ( ( state & ButtonState.Inactive ) != 0 ) {
1537                                 using ( Pen pen = new Pen( SystemColors.ControlLightLight, 2 ) ) {
1538                                         dc.DrawLines( pen, arrow );
1539                                 }
1540                                 
1541                                 /* Move away from the shadow */
1542                                 P1.X -= 1;              P1.Y -= 1;
1543                                 P2.X -= 1;              P2.Y -= 1;
1544                                 P3.X -= 1;              P3.Y -= 1;
1545                                 
1546                                 arrow[ 0 ] = P1;
1547                                 arrow[ 1 ] = P2;
1548                                 arrow[ 2 ] = P3;
1549                                 
1550                                 using ( Pen pen = new Pen( SystemColors.ControlDark, 2 ) ) {
1551                                         dc.DrawLines( pen, arrow );
1552                                 }
1553                         } else {
1554                                 using ( Pen pen = new Pen( SystemColors.ControlText, 2 ) ) {
1555                                         dc.DrawLines( pen, arrow );
1556                                 }
1557                         }
1558                         
1559                         dc.SmoothingMode = old_smoothing_mode;
1560                         
1561                 }
1562                 
1563                 /* Scroll button: regular button + direction arrow */
1564                 public override void CPDrawScrollButton( Graphics dc, Rectangle area, ScrollButton scroll_button_type, ButtonState state ) {
1565                         bool enabled = ( state == ButtonState.Inactive ) ? false: true;
1566                         
1567                         DrawScrollButtonPrimitive( dc, area, state, scroll_button_type );
1568                         
1569                         if ( area.Width < 12 || area.Height < 12 ) /* Cannot see a thing at smaller sizes */
1570                                 return;
1571                         
1572                         Color color_arrow;
1573                         
1574                         if ( enabled )
1575                                 color_arrow = arrow_color;
1576                         else
1577                                 color_arrow = ColorGrayText;
1578                         
1579                         /* Paint arrows */
1580                         
1581                         int centerX = area.Left + area.Width / 2;
1582                         int centerY = area.Top + area.Height / 2;
1583                         
1584                         int shift = 0;
1585                         
1586                         if ( ( state & ButtonState.Pushed ) != 0 )
1587                                 shift = 1;
1588                         
1589                         Point[] arrow = new Point[ 4 ];
1590                         
1591                         switch ( scroll_button_type ) {
1592                                 case ScrollButton.Down:
1593                                         centerY += shift + 1;
1594                                         arrow[ 0 ] = new Point( centerX - 4, centerY - 2 );
1595                                         arrow[ 1 ] = new Point( centerX, centerY + 2 );
1596                                         arrow[ 2 ] = new Point( centerX + 4, centerY - 2 );
1597                                         arrow[ 3 ] = new Point( centerX - 4, centerY - 2 );
1598                                         break;
1599                                 case ScrollButton.Up:
1600                                         centerY -= shift;
1601                                         arrow[ 0 ] = new Point( centerX - 4, centerY + 2 );
1602                                         arrow[ 1 ] = new Point( centerX, centerY - 2 );
1603                                         arrow[ 2 ] = new Point( centerX + 4, centerY + 2 );
1604                                         arrow[ 3 ] = new Point( centerX - 4, centerY + 2 );
1605                                         break;
1606                                 case ScrollButton.Left:
1607                                         centerX -= shift;
1608                                         arrow[ 0 ] = new Point( centerX + 2, centerY - 4 );
1609                                         arrow[ 1 ] = new Point( centerX + 2, centerY + 4 );
1610                                         arrow[ 2 ] = new Point( centerX - 2, centerY );
1611                                         arrow[ 3 ] = new Point( centerX + 2, centerY - 4 );
1612                                         break;
1613                                 case ScrollButton.Right:
1614                                         centerX += shift + 1;
1615                                         arrow[ 0 ] = new Point( centerX - 2, centerY - 4 );
1616                                         arrow[ 1 ] = new Point( centerX + 2, centerY );
1617                                         arrow[ 2 ] = new Point( centerX - 2, centerY + 4 );
1618                                         arrow[ 3 ] = new Point( centerX - 2, centerY - 4 );
1619                                         break;
1620                                 default:
1621                                         break;
1622                         }
1623                         
1624                         SmoothingMode old_smoothing_mode = dc.SmoothingMode;
1625                         dc.SmoothingMode = SmoothingMode.AntiAlias;
1626                         dc.FillPolygon( ResPool.GetSolidBrush( color_arrow ), arrow );
1627                         dc.SmoothingMode = old_smoothing_mode;
1628                 }
1629                 
1630                 public override void CPDrawSizeGrip( Graphics dc, Color backColor, Rectangle bounds ) {
1631                         Point pt1 = new Point( bounds.Right - 3, bounds.Bottom );
1632                         Point pt2 = new Point( bounds.Right, bounds.Bottom - 3 );
1633                         
1634                         // diagonals
1635                         Pen tmp_pen = ResPool.GetPen( Color.White );
1636                         for ( int i = 0; i < 4; i++ ) {
1637                                 dc.DrawLine( tmp_pen, pt1.X - i * 4, pt1.Y, pt2.X, pt2.Y - i * 4 );
1638                         }
1639                         
1640                         pt1.X += 1;
1641                         pt2.Y += 1;
1642                         
1643                         tmp_pen = ResPool.GetPen( pressed_inner_border_dark_color );
1644                         for ( int i = 0; i < 4; i++ ) {
1645                                 dc.DrawLine( tmp_pen, pt1.X - i * 4, pt1.Y, pt2.X, pt2.Y - i * 4 );
1646                         }
1647                 }
1648                 
1649                 private void DrawScrollBarThumb( Graphics dc, Rectangle area, ScrollBar bar ) {
1650                         LinearGradientBrush lgbr = null;
1651                         
1652                         if ( bar.vert )
1653                                 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 );
1654                         else
1655                                 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 );
1656                         
1657                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1658                         
1659                         lgbr.Dispose( );
1660                         
1661                         // outer border
1662                         Pen pen = ResPool.GetPen( border_normal_dark_color );
1663                         
1664                         dc.DrawRectangle( pen, area.X, area.Y, area.Width - 1, area.Height - 1 );
1665                         
1666                         // inner border
1667                         pen = ResPool.GetPen( Color.White );
1668                         dc.DrawLine( pen, area.X + 1, area.Bottom - 2, area.X + 1, area.Y + 1 );
1669                         dc.DrawLine( pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1670                         
1671                         pen = ResPool.GetPen( inner_border_dark_color );
1672                         dc.DrawLine( pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1673                         dc.DrawLine( pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1674                         
1675                         if ( bar.vert ) {
1676                                 if ( area.Height > 12 ) {
1677                                         int mid_y = area.Y + ( area.Height / 2 );
1678                                         int mid_x = area.X + ( area.Width / 2 );
1679                                         
1680                                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1681                                         dc.DrawLine( pen, mid_x - 3, mid_y, mid_x + 3, mid_y );
1682                                         dc.DrawLine( pen, mid_x - 3, mid_y - 3, mid_x + 3, mid_y - 3 );
1683                                         dc.DrawLine( pen, mid_x - 3, mid_y + 3, mid_x + 3, mid_y + 3 );
1684                                         
1685                                         Pen spen = ResPool.GetPen( Color.White );
1686                                         dc.DrawLine( spen, mid_x - 3, mid_y + 1, mid_x + 3, mid_y + 1 );
1687                                         dc.DrawLine( spen, mid_x - 3, mid_y - 2, mid_x + 3, mid_y - 2 );
1688                                         dc.DrawLine( spen, mid_x - 3, mid_y + 4, mid_x + 3, mid_y + 4 );
1689                                 }
1690                         } else {
1691                                 // draw grip lines only if there is enough space
1692                                 if ( area.Width > 12 ) {
1693                                         int mid_x = area.X +  ( area.Width / 2 );
1694                                         int mid_y = area.Y +  ( area.Height / 2 );
1695                                         
1696                                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1697                                         dc.DrawLine( pen, mid_x, mid_y - 3, mid_x, mid_y + 3 );
1698                                         dc.DrawLine( pen, mid_x - 3, mid_y - 3, mid_x - 3, mid_y + 3 );
1699                                         dc.DrawLine( pen, mid_x + 3, mid_y - 3, mid_x + 3, mid_y + 3 );
1700                                         
1701                                         Pen spen = ResPool.GetPen( Color.White );
1702                                         dc.DrawLine( spen, mid_x + 1, mid_y - 3, mid_x + 1, mid_y + 3 );
1703                                         dc.DrawLine( spen, mid_x - 2, mid_y - 3, mid_x - 2, mid_y + 3 );
1704                                         dc.DrawLine( spen, mid_x + 4, mid_y - 3, mid_x + 4, mid_y + 3 );
1705                                 }
1706                         }
1707                 }
1708                 
1709                 public void DrawScrollButtonPrimitive( Graphics dc, Rectangle area, ButtonState state, ScrollButton scroll_button_type ) {
1710                         Pen pen = ResPool.GetPen( border_normal_dark_color );
1711                         
1712                         Color first_gradient_color = gradient_first_color; 
1713                         Color second_gradient_color = gradient_second_color_nr2;
1714                         
1715                         bool pushed = false;
1716                         
1717                         if ( ( state & ButtonState.Pushed ) == ButtonState.Pushed ) {
1718                                 first_gradient_color = pressed_gradient_first_color;
1719                                 second_gradient_color = pressed_gradient_second_color;
1720                                 pushed = true;
1721                         }
1722                         
1723                         Point[] points = null;
1724                         
1725                         LinearGradientBrush lgbr = null;
1726                         
1727                         switch ( scroll_button_type ) {
1728                                 case ScrollButton.Left:
1729                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1730                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Y, area.X, area.Bottom - 1 );
1731                                         
1732                                         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 );
1733                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 2 );
1734                                         
1735                                         Pen tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1736                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 2, area.X + 1, area.Bottom - 2 );
1737                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1738                                         
1739                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1740                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1741                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1742                                         
1743                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1744                                         dc.DrawLine( tmp_pen, area.X, area.Y + 1, area.X + 1, area.Y );
1745                                         dc.DrawLine( tmp_pen, area.X, area.Bottom - 2, area.X + 1, area.Bottom - 1 );
1746                                         
1747                                         points = new Point[] {
1748                                                 new Point( area.X + 2, area.Y ),
1749                                                 new Point( area.Right - 1, area.Y ),
1750                                                 new Point( area.Right - 1, area.Bottom - 1 ),
1751                                                 new Point( area.X + 2, area.Bottom - 1 ),
1752                                                 new Point( area.X, area.Bottom - 3 ),
1753                                                 new Point( area.X, area.Y + 2 ),
1754                                                 new Point( area.X + 2, area.Y )
1755                                         };
1756                                         dc.DrawPolygon( pen, points );
1757                                         break;
1758                                 case ScrollButton.Right:
1759                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1760                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.Right - 1, area.Y, area.Right - 1, area.Bottom - 1 );
1761                                         
1762                                         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 );
1763                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 2 );
1764                                         
1765                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1766                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1767                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1768                                         
1769                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1770                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1771                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1772                                         
1773                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1774                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y, area.Right - 1, area.Y + 1 );
1775                                         dc.DrawLine( tmp_pen, area.Right - 1, area.Bottom - 2, area.Right - 2, area.Bottom - 1 );
1776                                         
1777                                         points = new Point[] {
1778                                                 new Point( area.X, area.Y ),
1779                                                 new Point( area.Right - 3, area.Y ),
1780                                                 new Point( area.Right - 1, area.Y + 2 ),
1781                                                 new Point( area.Right - 1, area.Bottom - 3 ),
1782                                                 new Point( area.Right - 3, area.Bottom - 1 ),
1783                                                 new Point( area.X, area.Bottom - 1 ),
1784                                                 new Point( area.X, area.Y ),
1785                                         };
1786                                         dc.DrawPolygon( pen, points );
1787                                         break;
1788                                 case ScrollButton.Up:
1789                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1790                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Y, area.Right - 1, area.Y );
1791                                         
1792                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y ), new Point( area.Right - 2, area.Y ), first_gradient_color, second_gradient_color );
1793                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1794                                         
1795                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1796                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1797                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1798                                         
1799                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1800                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1801                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1802                                         
1803                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1804                                         dc.DrawLine( tmp_pen, area.X, area.Y + 1, area.X + 1, area.Y );
1805                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y, area.Right - 1, area.Y + 1 );
1806                                         
1807                                         points = new Point[] {
1808                                                 new Point( area.X + 2, area.Y ),
1809                                                 new Point( area.Right - 3, area.Y ),
1810                                                 new Point( area.Right - 1, area.Y + 2 ),
1811                                                 new Point( area.Right - 1, area.Bottom - 1 ),
1812                                                 new Point( area.X, area.Bottom - 1 ),
1813                                                 new Point( area.X, area.Y + 2 ),
1814                                                 new Point( area.X + 2, area.Y )
1815                                         };
1816                                         dc.DrawPolygon( pen, points );
1817                                         break;
1818                                 case ScrollButton.Down:
1819                                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
1820                                         dc.DrawLine( ResPool.GetPen( ColorControl ), area.X, area.Bottom - 1, area.Right - 1, area.Bottom - 1 );
1821                                         
1822                                         lgbr = new LinearGradientBrush( new Point( area.X + 2, area.Y ), new Point( area.Right - 2, area.Y ), first_gradient_color, second_gradient_color );
1823                                         dc.FillRectangle( lgbr, area.X + 2, area.Y + 2, area.Width - 4, area.Height - 4 );
1824                                         
1825                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : Color.White );
1826                                         dc.DrawLine( tmp_pen, area.X + 1, area.Y + 1, area.X + 1, area.Bottom - 2 );
1827                                         dc.DrawLine( tmp_pen, area.X + 2, area.Y + 1, area.Right - 2, area.Y + 1 );
1828                                         
1829                                         tmp_pen = ResPool.GetPen( pushed ? pressed_inner_border_dark_color : inner_border_dark_color );
1830                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Y + 2, area.Right - 2, area.Bottom - 2 );
1831                                         dc.DrawLine( tmp_pen, area.X + 2, area.Bottom - 2, area.Right - 3, area.Bottom - 2 );
1832                                         
1833                                         tmp_pen = ResPool.GetPen( edge_top_inner_color );
1834                                         dc.DrawLine( tmp_pen, area.X, area.Bottom - 2, area.X + 1, area.Bottom - 1 );
1835                                         dc.DrawLine( tmp_pen, area.Right - 2, area.Bottom - 1, area.Right - 1, area.Bottom - 2 );
1836                                         
1837                                         points = new Point[] {
1838                                                 new Point( area.X, area.Y ),
1839                                                 new Point( area.Right - 1, area.Y ),
1840                                                 new Point( area.Right - 1, area.Bottom - 3 ),
1841                                                 new Point( area.Right - 3, area.Bottom - 1 ),
1842                                                 new Point( area.X + 2, area.Bottom - 1 ),
1843                                                 new Point( area.X, area.Bottom - 3 ),
1844                                                 new Point( area.X, area.Y )
1845                                         };
1846                                         dc.DrawPolygon( pen, points );
1847                                         break;
1848                         }
1849                         
1850                         lgbr.Dispose( );
1851                 }
1852                 
1853                 #region GroupBox
1854                 public override void DrawGroupBox( Graphics dc,  Rectangle area, GroupBox box ) {
1855                         StringFormat    text_format;
1856                         SizeF           size;
1857                         int             width;
1858                         int             y;
1859                         Rectangle       rect;
1860                         
1861                         rect = box.ClientRectangle;
1862                         
1863                         dc.FillRectangle( ResPool.GetSolidBrush( box.BackColor ), rect );
1864                         
1865                         text_format = new StringFormat( );
1866                         text_format.HotkeyPrefix = HotkeyPrefix.Show;
1867                         
1868                         size = dc.MeasureString( box.Text, box.Font );
1869                         width = (int) size.Width;
1870                         
1871                         if ( width > box.Width - 16 )
1872                                 width = box.Width - 16;
1873                         
1874                         y = box.Font.Height / 2;
1875                         
1876                         Pen pen = ResPool.GetPen( pressed_inner_border_dark_color );
1877                         
1878                         /* Draw group box*/
1879                         Point[] points = {
1880                                 new Point( 8 + width, y ),
1881                                 new Point( box.Width - 3, y ),
1882                                 new Point( box.Width - 1, y + 2 ),
1883                                 new Point( box.Width - 1, box.Height - 3 ),
1884                                 new Point( box.Width - 3, box.Height - 1 ),
1885                                 new Point( 2, box.Height - 1 ),
1886                                 new Point( 0, box.Height - 3 ),
1887                                 new Point( 0, y + 2 ),
1888                                 new Point( 2, y ),
1889                                 new Point( 8, y )
1890                         };
1891                         dc.DrawLines( pen, points );
1892                         
1893                         /* Text */
1894                         if ( box.Enabled ) {
1895                                 dc.DrawString( box.Text, box.Font, ResPool.GetSolidBrush( box.ForeColor ), 10, 0, text_format );
1896                         } else {
1897                                 CPDrawStringDisabled( dc, box.Text, box.Font, box.ForeColor, 
1898                                                      new RectangleF( 10, 0, width,  box.Font.Height ), text_format );
1899                         }
1900                         text_format.Dispose( ); 
1901                 }
1902                 #endregion
1903                 
1904                 #region TrackBar
1905                 private void DrawTrackBar_Vertical( Graphics dc, Rectangle clip_rectangle, TrackBar tb,
1906                                                    ref Rectangle thumb_pos, ref Rectangle thumb_area,
1907                                                    float ticks, int value_pos, bool mouse_value ) {                     
1908                         
1909                         Point toptick_startpoint = new Point( );
1910                         Point bottomtick_startpoint = new Point( );
1911                         Point channel_startpoint = new Point( );
1912                         float pixel_len;
1913                         float pixels_betweenticks;
1914                         const int space_from_right = 8;
1915                         const int space_from_left = 8;
1916                         Rectangle area = tb.ClientRectangle;
1917                         
1918                         switch ( tb.TickStyle )         {
1919                                 case TickStyle.BottomRight:
1920                                 case TickStyle.None:
1921                                         channel_startpoint.Y = 8;
1922                                         channel_startpoint.X = 9;
1923                                         bottomtick_startpoint.Y = 13;
1924                                         bottomtick_startpoint.X = 24;                           
1925                                         break;
1926                                 case TickStyle.TopLeft:
1927                                         channel_startpoint.Y = 8;
1928                                         channel_startpoint.X = 19;
1929                                         toptick_startpoint.Y = 13;
1930                                         toptick_startpoint.X = 8;
1931                                         break;
1932                                 case TickStyle.Both:
1933                                         channel_startpoint.Y = 8;
1934                                         channel_startpoint.X = 18;      
1935                                         bottomtick_startpoint.Y = 13;
1936                                         bottomtick_startpoint.X = 32;                           
1937                                         toptick_startpoint.Y = 13;
1938                                         toptick_startpoint.X = 8;                               
1939                                         break;
1940                                 default:
1941                                         break;
1942                         }
1943                         
1944                         thumb_area.X = area.X + channel_startpoint.X;
1945                         thumb_area.Y = area.Y + channel_startpoint.Y;
1946                         thumb_area.Height = area.Height - space_from_right - space_from_left;
1947                         thumb_area.Width = 4;
1948                         
1949                         pixel_len = thumb_area.Height - 11;
1950                         pixels_betweenticks = pixel_len / ( tb.Maximum - tb.Minimum );
1951                         
1952                         /* Convert thumb position from mouse position to value*/
1953                         if ( mouse_value ) {
1954                                 
1955                                 if ( value_pos >= channel_startpoint.Y )
1956                                         value_pos = (int)( ( (float) ( value_pos - channel_startpoint.Y ) ) / pixels_betweenticks );
1957                                 else
1958                                         value_pos = 0;                  
1959                                 
1960                                 if ( value_pos + tb.Minimum > tb.Maximum )
1961                                         value_pos = tb.Maximum - tb.Minimum;
1962                                 
1963                                 tb.Value = value_pos + tb.Minimum;
1964                         }               
1965                         
1966                         thumb_pos.Width = 13;
1967                         thumb_pos.Height = 29;
1968                         
1969                         thumb_pos.Y = channel_startpoint.Y + (int) ( pixels_betweenticks * (float) value_pos ) - ( thumb_pos.Height / 3 );
1970                         
1971                         if ( thumb_pos.Y < channel_startpoint.Y )
1972                                 thumb_pos.Y = channel_startpoint.Y;
1973                         
1974                         if ( thumb_pos.Y > thumb_area.Bottom - 29 )
1975                                 thumb_pos.Y = thumb_area.Bottom - 29;
1976                         
1977                         /* Draw channel */
1978                         // bottom
1979                         Pen pen = ResPool.GetPen( tab_top_border_focus_color );
1980                         dc.DrawLine( pen, channel_startpoint.X, thumb_pos.Y + 29, channel_startpoint.X, thumb_area.Bottom );
1981                         dc.DrawLine( pen, channel_startpoint.X, thumb_area.Bottom, channel_startpoint.X + 4, thumb_area.Bottom );
1982                         dc.DrawLine( pen, channel_startpoint.X + 4, thumb_pos.Y + 29, channel_startpoint.X + 4, thumb_area.Bottom );
1983                         
1984                         pen = ResPool.GetPen( menuitem_gradient_first_color );
1985                         dc.DrawLine( pen, channel_startpoint.X + 1, thumb_pos.Y + 28, channel_startpoint.X + 1, thumb_area.Bottom - 1 );
1986                         pen = ResPool.GetPen( trackbar_second_gradient_color );
1987                         dc.DrawLine( pen, channel_startpoint.X + 2, thumb_pos.Y + 28, channel_startpoint.X + 2, thumb_area.Bottom - 1 );
1988                         pen = ResPool.GetPen( trackbar_third_gradient_color );
1989                         dc.DrawLine( pen, channel_startpoint.X + 3, thumb_pos.Y + 28, channel_startpoint.X + 3, thumb_area.Bottom - 1 );
1990                         
1991                         // top
1992                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
1993                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 1, channel_startpoint.X + 1, thumb_pos.Y );
1994                         dc.DrawRectangle( ResPool.GetPen( scrollbar_background_color ), channel_startpoint.X + 2, channel_startpoint.Y + 1, 1, thumb_pos.Y );
1995                         
1996                         pen = ResPool.GetPen( scrollbar_border_color );
1997                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X, thumb_pos.Y );
1998                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X + 4, channel_startpoint.Y );
1999                         dc.DrawLine( pen, channel_startpoint.X + 4, channel_startpoint.Y, channel_startpoint.X + 4, thumb_pos.Y );
2000                         
2001                         /* Draw thumb */
2002                         thumb_pos.X = channel_startpoint.X - 4;
2003                         
2004                         // inner border
2005                         pen = ResPool.GetPen( Color.White );
2006                         dc.DrawLine( pen, thumb_pos.X + 1, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Bottom - 2 );
2007                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Y + 1, thumb_pos.Right - 2, thumb_pos.Y + 1 );
2008                         
2009                         pen = ResPool.GetPen( menu_separator_color );
2010                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2011                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y + 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2012                         
2013                         // outer border
2014                         Point[] points = {
2015                                 new Point( thumb_pos.X + 2, thumb_pos.Y ),
2016                                 new Point( thumb_pos.Right - 3 , thumb_pos.Y ),
2017                                 new Point( thumb_pos.Right - 1, thumb_pos.Y + 2 ),
2018                                 new Point( thumb_pos.Right - 1, thumb_pos.Bottom - 3 ),
2019                                 new Point( thumb_pos.Right - 3, thumb_pos.Bottom - 1 ),
2020                                 new Point( thumb_pos.X + 2, thumb_pos.Bottom - 1 ),
2021                                 new Point( thumb_pos.X, thumb_pos.Bottom - 3 ),
2022                                 new Point( thumb_pos.X, thumb_pos.Y + 2 ),
2023                                 new Point( thumb_pos.X + 2, thumb_pos.Y )
2024                         };
2025                         
2026                         dc.DrawLines( ResPool.GetPen( border_normal_dark_color ), points );
2027                         
2028                         Color first_gradient_color = mouse_value ? button_edge_bottom_outer_color : trackbar_inner_first_gradient_color;
2029                         Color second_gradient_color = mouse_value ? trackbar_inner_pressed_second_gradient_color : trackbar_inner_second_gradient_color;
2030                         
2031                         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 ) ) {
2032                                 dc.FillRectangle( lgbr, thumb_pos.X + 2, thumb_pos.Y + 2, thumb_pos.Width - 4, thumb_pos.Height - 4 );
2033                         }
2034                         
2035                         // outer egdes
2036                         pen = ResPool.GetPen( edge_top_inner_color );
2037                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Y );
2038                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y, thumb_pos.Right - 1, thumb_pos.Y + 1 );
2039                         
2040                         pen = ResPool.GetPen( edge_bottom_inner_color );
2041                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Bottom - 2, thumb_pos.X + 1, thumb_pos.Bottom - 1 );
2042                         dc.DrawLine( pen, thumb_pos.Right - 1, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 1 );
2043                         
2044                         // draw grip lines
2045                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
2046                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 11, thumb_pos.X + 8, thumb_pos.Y + 11 );
2047                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 14, thumb_pos.X + 8, thumb_pos.Y + 14 );
2048                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 17, thumb_pos.X + 8, thumb_pos.Y + 17 );
2049                         
2050                         pen = ResPool.GetPen( Color.White );
2051                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 12, thumb_pos.X + 8, thumb_pos.Y + 12 );
2052                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 15, thumb_pos.X + 8, thumb_pos.Y + 15 );
2053                         dc.DrawLine( pen, thumb_pos.X + 4, thumb_pos.Y + 18, thumb_pos.X + 8, thumb_pos.Y + 18 );
2054                         
2055                         pixel_len = thumb_area.Height - 11;
2056                         pixels_betweenticks = pixel_len / ticks;
2057                         
2058                         /* Draw ticks*/
2059                         thumb_area.X = thumb_pos.X;
2060                         thumb_area.Y = channel_startpoint.Y;
2061                         thumb_area.Width = thumb_pos.Width;
2062                         
2063                         Region outside = new Region( area );
2064                         outside.Exclude( thumb_area );                  
2065                         
2066                         if ( outside.IsVisible( clip_rectangle ) ) {                            
2067                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.BottomRight ) == TickStyle.BottomRight ||
2068                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {       
2069                                         
2070                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks )      {                                       
2071                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2072                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X , area.Y + bottomtick_startpoint.Y  + inc, 
2073                                                                     area.X + bottomtick_startpoint.X  + 3, area.Y + bottomtick_startpoint.Y + inc );
2074                                                 else
2075                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X, area.Y + bottomtick_startpoint.Y  + inc, 
2076                                                                     area.X + bottomtick_startpoint.X  + 2, area.Y + bottomtick_startpoint.Y + inc );
2077                                         }
2078                                 }
2079                                 
2080                                 if ( pixels_betweenticks > 0 &&  ( ( tb.TickStyle & TickStyle.TopLeft ) == TickStyle.TopLeft ||
2081                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {
2082                                         
2083                                         pixel_len = thumb_area.Height - 11;
2084                                         pixels_betweenticks = pixel_len / ticks;
2085                                         
2086                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
2087                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2088                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X  - 3 , area.Y + toptick_startpoint.Y + inc, 
2089                                                                     area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y + inc );
2090                                                 else
2091                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X  - 2, area.Y + toptick_startpoint.Y + inc, 
2092                                                                     area.X + toptick_startpoint.X, area.Y + toptick_startpoint.Y  + inc );
2093                                         }                       
2094                                 }
2095                         }
2096                         
2097                         outside.Dispose( );
2098                         
2099                 }
2100                 
2101                 private void DrawTrackBar_Horizontal( Graphics dc, Rectangle clip_rectangle, TrackBar tb,
2102                                                      ref Rectangle thumb_pos, ref Rectangle thumb_area,
2103                                                      float ticks, int value_pos, bool mouse_value ) {                   
2104                         Point toptick_startpoint = new Point( );
2105                         Point bottomtick_startpoint = new Point( );
2106                         Point channel_startpoint = new Point( );
2107                         float pixel_len;
2108                         float pixels_betweenticks;
2109                         const int space_from_right = 8;
2110                         const int space_from_left = 8;
2111                         Rectangle area = tb.ClientRectangle;
2112                         
2113                         switch ( tb.TickStyle ) {
2114                                 case TickStyle.BottomRight:
2115                                 case TickStyle.None:
2116                                         channel_startpoint.X = 8;
2117                                         channel_startpoint.Y = 9;
2118                                         bottomtick_startpoint.X = 13;
2119                                         bottomtick_startpoint.Y = 24;                           
2120                                         break;
2121                                 case TickStyle.TopLeft:
2122                                         channel_startpoint.X = 8;
2123                                         channel_startpoint.Y = 19;
2124                                         toptick_startpoint.X = 13;
2125                                         toptick_startpoint.Y = 8;
2126                                         break;
2127                                 case TickStyle.Both:
2128                                         channel_startpoint.X = 8;
2129                                         channel_startpoint.Y = 18;      
2130                                         bottomtick_startpoint.X = 13;
2131                                         bottomtick_startpoint.Y = 32;                           
2132                                         toptick_startpoint.X = 13;
2133                                         toptick_startpoint.Y = 8;                               
2134                                         break;
2135                                 default:
2136                                         break;
2137                         }
2138                         
2139                         thumb_area.X = area.X + channel_startpoint.X;
2140                         thumb_area.Y = area.Y + channel_startpoint.Y;
2141                         thumb_area.Width = area.Width - space_from_right - space_from_left;
2142                         thumb_area.Height = 4;
2143                         
2144                         pixel_len = thumb_area.Width - 11;
2145                         pixels_betweenticks = pixel_len / ( tb.Maximum - tb.Minimum );
2146                         
2147                         /* Convert thumb position from mouse position to value*/
2148                         if ( mouse_value ) {                    
2149                                 if ( value_pos >= channel_startpoint.X )
2150                                         value_pos = (int)( ( (float) ( value_pos - channel_startpoint.X ) ) / pixels_betweenticks );
2151                                 else
2152                                         value_pos = 0;                          
2153                                 
2154                                 if ( value_pos + tb.Minimum > tb.Maximum )
2155                                         value_pos = tb.Maximum - tb.Minimum;
2156                                 
2157                                 tb.Value = value_pos + tb.Minimum;
2158                         }                       
2159                         
2160                         thumb_pos.Width = 29;
2161                         thumb_pos.Height = 13;
2162                         
2163                         thumb_pos.X = channel_startpoint.X + (int) ( pixels_betweenticks * (float) value_pos ) - ( thumb_pos.Width / 3 );
2164                         
2165                         if ( thumb_pos.X < channel_startpoint.X )
2166                                 thumb_pos.X = channel_startpoint.X;
2167                         
2168                         if ( thumb_pos.X > thumb_area.Right - 29 )
2169                                 thumb_pos.X = thumb_area.Right - 29;
2170                         
2171                         /* Draw channel */
2172                         // left side
2173                         Pen pen = ResPool.GetPen( tab_top_border_focus_color );
2174                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, thumb_pos.X, channel_startpoint.Y );
2175                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y, channel_startpoint.X, channel_startpoint.Y + 4 );
2176                         dc.DrawLine( pen, channel_startpoint.X, channel_startpoint.Y + 4, thumb_pos.X, channel_startpoint.Y + 4 );
2177                         
2178                         pen = ResPool.GetPen( menuitem_gradient_first_color );
2179                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 1, thumb_pos.X, channel_startpoint.Y + 1 );
2180                         pen = ResPool.GetPen( trackbar_second_gradient_color );
2181                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 2, thumb_pos.X, channel_startpoint.Y + 2 );
2182                         pen = ResPool.GetPen( trackbar_third_gradient_color );
2183                         dc.DrawLine( pen, channel_startpoint.X + 1, channel_startpoint.Y + 3, thumb_pos.X, channel_startpoint.Y + 3 );
2184                         
2185                         // right side
2186                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
2187                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y + 1, thumb_area.Right - 1, channel_startpoint.Y + 1 );
2188                         dc.DrawRectangle( ResPool.GetPen( scrollbar_background_color ), thumb_pos.X + 29, channel_startpoint.Y + 2, thumb_area.Right - thumb_pos.X - 30, 1 );
2189                         
2190                         pen = ResPool.GetPen( scrollbar_border_color );
2191                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y, thumb_area.Right, channel_startpoint.Y );
2192                         dc.DrawLine( pen, thumb_area.Right, channel_startpoint.Y, thumb_area.Right, channel_startpoint.Y + 4 );
2193                         dc.DrawLine( pen, thumb_pos.X + 29, channel_startpoint.Y + 4, thumb_area.Right, channel_startpoint.Y + 4 );
2194                         
2195                         /* Draw thumb */
2196                         
2197                         thumb_pos.Y = channel_startpoint.Y - 4;
2198                         
2199                         // inner border
2200                         pen = ResPool.GetPen( Color.White );
2201                         dc.DrawLine( pen, thumb_pos.X + 1, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Bottom - 2 );
2202                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Y + 1, thumb_pos.Right - 2, thumb_pos.Y + 1 );
2203                         
2204                         pen = ResPool.GetPen( menu_separator_color );
2205                         dc.DrawLine( pen, thumb_pos.X + 2, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2206                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y + 2, thumb_pos.Right - 2, thumb_pos.Bottom - 2 );
2207                         
2208                         // outer border
2209                         Point[] points = {
2210                                 new Point( thumb_pos.X + 2, thumb_pos.Y ),
2211                                 new Point( thumb_pos.Right - 3 , thumb_pos.Y ),
2212                                 new Point( thumb_pos.Right - 1, thumb_pos.Y + 2 ),
2213                                 new Point( thumb_pos.Right - 1, thumb_pos.Bottom - 3 ),
2214                                 new Point( thumb_pos.Right - 3, thumb_pos.Bottom - 1 ),
2215                                 new Point( thumb_pos.X + 2, thumb_pos.Bottom - 1 ),
2216                                 new Point( thumb_pos.X, thumb_pos.Bottom - 3 ),
2217                                 new Point( thumb_pos.X, thumb_pos.Y + 2 ),
2218                                 new Point( thumb_pos.X + 2, thumb_pos.Y )
2219                         };
2220                         
2221                         dc.DrawLines( ResPool.GetPen( border_normal_dark_color ), points );
2222                         
2223                         Color first_gradient_color = mouse_value ? button_edge_bottom_outer_color : trackbar_inner_first_gradient_color;
2224                         Color second_gradient_color = mouse_value ? trackbar_inner_pressed_second_gradient_color : trackbar_inner_second_gradient_color;
2225                         
2226                         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 ) ) {
2227                                 dc.FillRectangle( lgbr, thumb_pos.X + 2, thumb_pos.Y + 2, thumb_pos.Width - 4, thumb_pos.Height - 4 );
2228                         }
2229                         
2230                         // outer egdes
2231                         pen = ResPool.GetPen( edge_top_inner_color );
2232                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Y + 1, thumb_pos.X + 1, thumb_pos.Y );
2233                         dc.DrawLine( pen, thumb_pos.Right - 2, thumb_pos.Y, thumb_pos.Right - 1, thumb_pos.Y + 1 );
2234                         
2235                         pen = ResPool.GetPen( edge_bottom_inner_color );
2236                         dc.DrawLine( pen, thumb_pos.X, thumb_pos.Bottom - 2, thumb_pos.X + 1, thumb_pos.Bottom - 1 );
2237                         dc.DrawLine( pen, thumb_pos.Right - 1, thumb_pos.Bottom - 2, thumb_pos.Right - 2, thumb_pos.Bottom - 1 );
2238                         
2239                         // draw grip lines
2240                         pen = ResPool.GetPen( pressed_inner_border_dark_color );
2241                         dc.DrawLine( pen, thumb_pos.X + 11, thumb_pos.Y + 4, thumb_pos.X + 11, thumb_pos.Y + 8 );
2242                         dc.DrawLine( pen, thumb_pos.X + 14, thumb_pos.Y + 4, thumb_pos.X + 14, thumb_pos.Y + 8 );
2243                         dc.DrawLine( pen, thumb_pos.X + 17, thumb_pos.Y + 4, thumb_pos.X + 17, thumb_pos.Y + 8 );
2244                         
2245                         pen = ResPool.GetPen( Color.White );
2246                         dc.DrawLine( pen, thumb_pos.X + 12, thumb_pos.Y + 4, thumb_pos.X  + 12, thumb_pos.Y + 8 );
2247                         dc.DrawLine( pen, thumb_pos.X + 15, thumb_pos.Y + 4, thumb_pos.X + 15, thumb_pos.Y + 8 );
2248                         dc.DrawLine( pen, thumb_pos.X + 18, thumb_pos.Y + 4, thumb_pos.X + 18, thumb_pos.Y + 8 );
2249                         
2250                         pixel_len = thumb_area.Width - 11;
2251                         pixels_betweenticks = pixel_len / ticks;
2252                         
2253                         /* Draw ticks*/
2254                         thumb_area.Y = thumb_pos.Y;
2255                         thumb_area.X = channel_startpoint.X;
2256                         thumb_area.Height = thumb_pos.Height;
2257                         Region outside = new Region( area );
2258                         outside.Exclude( thumb_area );                  
2259                         
2260                         if ( outside.IsVisible( clip_rectangle ) ) {                            
2261                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.BottomRight ) == TickStyle.BottomRight ||
2262                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {                               
2263                                         
2264                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
2265                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2266                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y, 
2267                                                                     area.X + bottomtick_startpoint.X + inc , area.Y + bottomtick_startpoint.Y + 3 );
2268                                                 else
2269                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y, 
2270                                                                     area.X + bottomtick_startpoint.X + inc, area.Y + bottomtick_startpoint.Y + 2 );
2271                                         }
2272                                 }
2273                                 
2274                                 if ( pixels_betweenticks > 0 && ( ( tb.TickStyle & TickStyle.TopLeft ) == TickStyle.TopLeft ||
2275                                     ( ( tb.TickStyle & TickStyle.Both ) == TickStyle.Both ) ) ) {
2276                                         
2277                                         for ( float inc = 0; inc < ( pixel_len + 1 ); inc += pixels_betweenticks ) {                                    
2278                                                 if ( inc == 0 || ( inc +  pixels_betweenticks ) >= pixel_len + 1 )
2279                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y - 3, 
2280                                                                     area.X + toptick_startpoint.X + inc , area.Y + toptick_startpoint.Y );
2281                                                 else
2282                                                         dc.DrawLine( ResPool.GetPen( pen_ticks_color ), area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y - 2, 
2283                                                                     area.X + toptick_startpoint.X + inc, area.Y + toptick_startpoint.Y );
2284                                         }                       
2285                                 }
2286                         }
2287                         
2288                         outside.Dispose( );                     
2289                 }
2290                 
2291                 public override void DrawTrackBar( Graphics dc, Rectangle clip_rectangle, TrackBar tb ) {
2292                         int             value_pos;
2293                         bool            mouse_value;
2294                         float           ticks = ( tb.Maximum - tb.Minimum ) / tb.tickFrequency; /* N of ticks draw*/
2295                         Rectangle       area;
2296                         Rectangle       thumb_pos = tb.ThumbPos;
2297                         Rectangle       thumb_area = tb.ThumbArea;
2298                         
2299                         if ( tb.thumb_pressed ) {
2300                                 value_pos = tb.thumb_mouseclick;
2301                                 mouse_value = true;
2302                         } else {
2303                                 value_pos = tb.Value - tb.Minimum;
2304                                 mouse_value = false;
2305                         }
2306                         
2307                         area = tb.ClientRectangle;
2308                         
2309                         /* Control Background */
2310                         if ( tb.BackColor == DefaultControlBackColor ) {
2311                                 dc.FillRectangle( ResPool.GetSolidBrush( ColorControl ), clip_rectangle );
2312                         } else {
2313                                 dc.FillRectangle( ResPool.GetSolidBrush( tb.BackColor ), clip_rectangle );
2314                         }
2315                         
2316                         if ( tb.Orientation == Orientation.Vertical ) {
2317                                 DrawTrackBar_Vertical( dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
2318                                                       ticks, value_pos, mouse_value );
2319                                 
2320                         } else {
2321                                 DrawTrackBar_Horizontal( dc, clip_rectangle, tb, ref thumb_pos, ref thumb_area,
2322                                                         ticks, value_pos, mouse_value );
2323                         }
2324                         
2325                         // TODO: draw better focus rectangle
2326                         if ( tb.Focused ) {
2327                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y, area.Width - 1, 1 );
2328                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y + area.Height - 1, area.Width - 1, 1 );
2329                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X, area.Y, 1, area.Height - 1 );
2330                                 dc.FillRectangle( ResPool.GetHatchBrush( HatchStyle.Percent50, ColorControl, Color.Black ), area.X + area.Width - 1, area.Y, 1, area.Height - 1 );
2331                         }
2332                         
2333                         tb.ThumbPos = thumb_pos;
2334                         tb.ThumbArea = thumb_area;
2335                 }
2336                 #endregion      // TrackBar
2337                 
2338                 #region ListView
2339                 // draws the ListViewItem of the given index
2340                 protected override void DrawListViewItem( Graphics dc, ListView control, ListViewItem item ) {                          
2341                         Rectangle rect_checkrect = item.CheckRectReal;
2342                         Rectangle rect_iconrect = item.GetBounds( ItemBoundsPortion.Icon );
2343                         Rectangle full_rect = item.GetBounds( ItemBoundsPortion.Entire );
2344                         Rectangle text_rect = item.GetBounds( ItemBoundsPortion.Label );                        
2345                         
2346                         if ( control.CheckBoxes ) {
2347                                 if ( control.StateImageList == null ) {
2348                                         // Make sure we've got at least a line width of 1
2349                                         int check_wd = Math.Max( 3, rect_checkrect.Width / 6 );
2350                                         int scale = Math.Max( 1, rect_checkrect.Width / 12 );
2351                                         
2352                                         // set the checkbox background
2353                                         dc.FillRectangle( this.ResPool.GetSolidBrush( this.ColorWindow ),
2354                                                          rect_checkrect );
2355                                         // define a rectangle inside the border area
2356                                         Rectangle rect = new Rectangle( rect_checkrect.X + 2,
2357                                                                        rect_checkrect.Y + 2,
2358                                                                        rect_checkrect.Width - 4,
2359                                                                        rect_checkrect.Height - 4 );
2360                                         Pen pen = new Pen( this.ColorWindowText, 2 );
2361                                         dc.DrawRectangle( pen, rect );
2362                                         
2363                                         // Need to draw a check-mark
2364                                         if ( item.Checked ) {
2365                                                 pen.Width = 1;
2366                                                 // adjustments to get the check-mark at the right place
2367                                                 rect.X ++; rect.Y ++;
2368                                                 // following logic is taken from DrawFrameControl method
2369                                                 for ( int i = 0; i < check_wd; i++ ) {
2370                                                         dc.DrawLine( pen, rect.Left + check_wd / 2,
2371                                                                     rect.Top + check_wd + i,
2372                                                                     rect.Left + check_wd / 2 + 2 * scale,
2373                                                                     rect.Top + check_wd + 2 * scale + i );
2374                                                         dc.DrawLine( pen,
2375                                                                     rect.Left + check_wd / 2 + 2 * scale,
2376                                                                     rect.Top + check_wd + 2 * scale + i,
2377                                                                     rect.Left + check_wd / 2 + 6 * scale,
2378                                                                     rect.Top + check_wd - 2 * scale + i );
2379                                                 }
2380                                         }
2381                                 } else {
2382                                         if ( item.Checked && control.StateImageList.Images.Count > 1 )
2383                                                 control.StateImageList.Draw( dc,
2384                                                                             rect_checkrect.Location, 1 );
2385                                         else if ( ! item.Checked && control.StateImageList.Images.Count > 0 )
2386                                                 control.StateImageList.Draw( dc,
2387                                                                             rect_checkrect.Location, 0 );
2388                                 }
2389                         }
2390                         
2391                         // Item is drawn as a special case, as it is not just text
2392                         if ( control.View == View.LargeIcon ) {
2393                                 if ( item.ImageIndex > -1 &&
2394                                     control.LargeImageList != null &&
2395                                     item.ImageIndex < control.LargeImageList.Images.Count ) {
2396                                         // center image
2397                                         Point image_location = rect_iconrect.Location;
2398                                         Image image = control.LargeImageList.Images[ item.ImageIndex ];
2399                                         if ( image.Width < rect_iconrect.Width ) {
2400                                                 int icon_rect_middle = rect_iconrect.Width / 2;
2401                                                 int image_middle = image.Width / 2;
2402                                                 image_location.X = image_location.X + icon_rect_middle - image_middle;
2403                                         }
2404                                         control.LargeImageList.Draw( dc, image_location,
2405                                                                     item.ImageIndex );
2406                                 }
2407                         } else {
2408                                 if ( item.ImageIndex > -1 &&
2409                                     control.SmallImageList != null &&
2410                                     item.ImageIndex < control.SmallImageList.Images.Count )
2411                                         control.SmallImageList.Draw( dc, rect_iconrect.Location,
2412                                                                     item.ImageIndex );
2413                         }
2414                         
2415                         // draw the item text                   
2416                         // format for the item text
2417                         StringFormat format = new StringFormat( );
2418                         format.LineAlignment = StringAlignment.Center;
2419                         if ( control.View == View.LargeIcon )
2420                                 format.Alignment = StringAlignment.Center; 
2421                         else
2422                                 format.Alignment = StringAlignment.Near;
2423                         
2424                         if ( !control.LabelWrap )
2425                                 format.FormatFlags = StringFormatFlags.NoWrap;
2426                         
2427                         if ( item.Selected ) {
2428                                 if ( control.View == View.Details ) {
2429                                         if ( control.FullRowSelect ) {
2430                                                 // fill the entire rect excluding the checkbox                                          
2431                                                 full_rect.Location = item.LabelRect.Location;
2432                                                 dc.FillRectangle( this.ResPool.GetSolidBrush
2433                                                                  ( this.ColorHighlight ), full_rect );
2434                                         } else {
2435                                                 Size text_size = Size.Ceiling( dc.MeasureString( item.Text,
2436                                                                                                 item.Font ) );
2437                                                 text_rect.Width = text_size.Width;
2438                                                 dc.FillRectangle( this.ResPool.GetSolidBrush
2439                                                                  ( this.ColorHighlight ), text_rect );
2440                                         }
2441                                 } else {
2442                                         /*Size text_size = Size.Ceiling (dc.MeasureString (item.Text,
2443                                          item.Font));
2444                                          Point loc = text_rect.Location;
2445                                          loc.X += (text_rect.Width - text_size.Width) / 2;
2446                                          text_rect.Width = text_size.Width;*/
2447                                         dc.FillRectangle( this.ResPool.GetSolidBrush( this.ColorHighlight ),
2448                                                          text_rect );
2449                                 }
2450                         } else
2451                                 dc.FillRectangle( ResPool.GetSolidBrush( item.BackColor ), text_rect );
2452                         
2453                         if ( item.Text != null && item.Text.Length > 0 ) {
2454                                 
2455                                 if ( control.View != View.LargeIcon ) {
2456                                         if ( item.Selected )
2457                                                 dc.DrawString( item.Text, item.Font, this.ResPool.GetSolidBrush
2458                                                               ( this.ColorHighlightText ), text_rect, format );
2459                                         else
2460                                                 dc.DrawString( item.Text, item.Font, this.ResPool.GetSolidBrush
2461                                                               ( item.ForeColor ), text_rect, format );
2462                                 } else {
2463                                         // ListView CalcTextSize says wrapping is done for two lines only !?!
2464                                         // text is centered for the complete text_rect but it should be centered per available row/line
2465                                         
2466                                         // calculate how much lines we get out of text_rect and current item.Font
2467                                         int nr_lines = text_rect.Height / item.Font.Height;
2468                                         int rest = text_rect.Height % item.Font.Height;
2469                                         int line_height = item.Font.Height + ( rest > 1 ? 2 : 0 );
2470                                         
2471                                         Rectangle[] text_rects = new Rectangle[ nr_lines ];
2472                                         
2473                                         for ( int i = 0; i < nr_lines; i++ ) {
2474                                                 text_rects[ i ].X = text_rect.X;
2475                                                 text_rects[ i ].Y = text_rect.Y + i * line_height;
2476                                                 text_rects[ i ].Width = text_rect.Width;
2477                                                 text_rects[ i ].Height = line_height;
2478                                         }
2479                                         
2480                                         string[] lines = new string[ nr_lines ];
2481                                         
2482                                         string text = item.Text;
2483                                         
2484                                         int line_nr = 0;
2485                                         int current_pos = 0;
2486                                         for ( int k = 1; k <= text.Length; k++ ) {
2487                                                 lines[ line_nr ] = text.Substring( current_pos, k - current_pos );
2488                                                 
2489                                                 // FIXME: Graphics.MeasureString returns wrong results if there is a 
2490                                                 //        space char in the string
2491                                                 SizeF sizef = dc.MeasureString( lines[ line_nr ], item.Font, text_rect.Width, format );
2492                                                 
2493                                                 if ( (int)sizef.Width > text_rect.Width - 3 ) {
2494                                                         lines[ line_nr ] = lines[ line_nr ].Remove( lines[ line_nr ].Length - 1, 1 );
2495                                                         k--;
2496                                                         current_pos = k;
2497                                                         line_nr++;
2498                                                         if ( line_nr == nr_lines )
2499                                                                 break;
2500                                                 }
2501                                         }
2502                                         
2503                                         int j = 0;
2504                                         foreach ( Rectangle t_rect in text_rects ) {
2505                                                 if ( item.Selected )
2506                                                         dc.DrawString( lines[ j ], item.Font, this.ResPool.GetSolidBrush
2507                                                                       ( this.ColorHighlightText ), t_rect, format );
2508                                                 else
2509                                                         dc.DrawString( lines[ j ], item.Font, this.ResPool.GetSolidBrush
2510                                                                       ( item.ForeColor ), t_rect, format );
2511                                                 j++;
2512                                         }
2513                                 } 
2514                         }
2515                         
2516                         if ( control.View == View.Details && control.Columns.Count > 0 ) {
2517                                 // draw subitems for details view
2518                                 ListViewItem.ListViewSubItemCollection subItems = item.SubItems;
2519                                 int count = ( control.Columns.Count < subItems.Count ? 
2520                                         control.Columns.Count : subItems.Count );
2521                                 
2522                                 if ( count > 0 ) {
2523                                         ColumnHeader col;
2524                                         ListViewItem.ListViewSubItem subItem;
2525                                         Rectangle sub_item_rect = text_rect; 
2526                                         
2527                                         // set the format for subitems
2528                                         format.FormatFlags = StringFormatFlags.NoWrap;
2529                                         format.Alignment = StringAlignment.Near;
2530                                         
2531                                         // 0th subitem is the item already drawn
2532                                         for ( int index = 1; index < count; index++ ) {
2533                                                 subItem = subItems[ index ];
2534                                                 col = control.Columns[ index ];
2535                                                 sub_item_rect.X = col.Rect.Left;
2536                                                 sub_item_rect.Width = col.Wd;
2537                                                 sub_item_rect.X -= control.h_marker;
2538                                                 
2539                                                 SolidBrush sub_item_back_br = null;
2540                                                 SolidBrush sub_item_fore_br = null;
2541                                                 Font sub_item_font = null;
2542                                                 
2543                                                 if ( item.UseItemStyleForSubItems ) {
2544                                                         sub_item_back_br = this.ResPool.GetSolidBrush
2545                                                         ( item.BackColor );
2546                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
2547                                                         ( item.ForeColor );
2548                                                         sub_item_font = item.Font;
2549                                                 } else {
2550                                                         sub_item_back_br = this.ResPool.GetSolidBrush
2551                                                         ( subItem.BackColor );
2552                                                         sub_item_fore_br = this.ResPool.GetSolidBrush
2553                                                         ( subItem.ForeColor );
2554                                                         sub_item_font = subItem.Font;
2555                                                 }
2556                                                 
2557                                                 // In case of fullrowselect, background is filled
2558                                                 // for the entire rect above
2559                                                 if ( item.Selected && control.FullRowSelect ) {
2560                                                         if ( subItem.Text != null && subItem.Text.Length > 0 )
2561                                                                 dc.DrawString( subItem.Text, sub_item_font,
2562                                                                               this.ResPool.GetSolidBrush
2563                                                                               ( this.ColorHighlightText ),
2564                                                                               sub_item_rect, format );
2565                                                 } else {
2566                                                         dc.FillRectangle( sub_item_back_br, sub_item_rect );
2567                                                         if ( subItem.Text != null && subItem.Text.Length > 0 )
2568                                                                 dc.DrawString( subItem.Text, sub_item_font,
2569                                                                               sub_item_fore_br,
2570                                                                               sub_item_rect, format );
2571                                                 }
2572                                                 sub_item_rect.X += col.Wd;
2573                                         }
2574                                 }
2575                         }
2576                         
2577                         if ( item.Focused ) {                           
2578                                 if ( item.Selected )
2579                                         CPDrawFocusRectangle( dc, text_rect, ColorHighlightText, ColorHighlight );
2580                                 else
2581                                         CPDrawFocusRectangle( dc, text_rect, control.ForeColor, control.BackColor );
2582                         }
2583                         
2584                         format.Dispose( );
2585                 }
2586                 #endregion ListView
2587                 
2588                 public override void CPDrawBorder3D( Graphics graphics, Rectangle rectangle, Border3DStyle style, Border3DSide sides ) {
2589                         CPDrawBorder3D( graphics, rectangle, style, sides, ColorControl );
2590                 }
2591                 
2592                 private void CPDrawBorder3D( Graphics dc, Rectangle rectangle, Border3DStyle style, Border3DSide sides, Color control_color ) {
2593                         // currently we don't take care of Border3DStyle or Border3DSide
2594                         
2595                         // FIXME: temporary fix for artefacts, it should use the backcolor of the parent control
2596                         dc.DrawLine( ResPool.GetPen( ColorControl ), rectangle.X, rectangle.Y, rectangle.X, rectangle.Bottom - 1 );
2597                         dc.DrawLine( ResPool.GetPen( ColorControl ), rectangle.Right - 1, rectangle.Y, rectangle.Right - 1, rectangle.Bottom - 1 );
2598                         
2599                         Pen tmp_pen = ResPool.GetPen( edge_bottom_inner_color );
2600                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 2, rectangle.X + 2, rectangle.Y + 1 );
2601                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Y + 1, rectangle.Right - 2, rectangle.Y + 2 );
2602                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 3 );
2603                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Bottom - 3, rectangle.X + 2, rectangle.Bottom - 2 );
2604                         
2605                         tmp_pen = ResPool.GetPen( theme_back_color );
2606                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Y + 2, rectangle.Right - 3, rectangle.Y + 2 );
2607                         dc.DrawLine( tmp_pen, rectangle.X + 2, rectangle.Y + 3, rectangle.X + 2, rectangle.Bottom - 3 );
2608                         
2609                         tmp_pen = ResPool.GetPen( Color.White );
2610                         dc.DrawLine( tmp_pen, rectangle.X + 3, rectangle.Bottom - 3, rectangle.Right - 3, rectangle.Bottom - 3 );
2611                         dc.DrawLine( tmp_pen, rectangle.Right - 3, rectangle.Y + 3, rectangle.Right - 3, rectangle.Bottom - 3 );
2612                         
2613                         Point[] points = {
2614                                 new Point( rectangle.X + 3, rectangle.Y + 1 ),
2615                                 new Point( rectangle.Right - 4, rectangle.Y + 1 ),
2616                                 new Point( rectangle.Right - 2, rectangle.Y + 3 ),
2617                                 new Point( rectangle.Right - 2, rectangle.Bottom - 4 ),
2618                                 new Point( rectangle.Right - 4, rectangle.Bottom - 2 ),
2619                                 new Point( rectangle.X + 3, rectangle.Bottom - 2 ),
2620                                 new Point( rectangle.X + 1, rectangle.Bottom - 4 ),
2621                                 new Point( rectangle.X + 1, rectangle.Y + 3 ),
2622                                 new Point( rectangle.X + 3, rectangle.Y + 1 )
2623                         };
2624                         
2625                         dc.DrawLines( ResPool.GetPen( combobox_border_color ), points );
2626                         
2627                         Point[] points_top_outer = {
2628                                 new Point( rectangle.X + 1, rectangle.Y + 1 ),
2629                                 new Point( rectangle.X + 2, rectangle.Y ),
2630                                 new Point( rectangle.Right - 3, rectangle.Y ),
2631                                 new Point( rectangle.Right - 2 , rectangle.Y + 1 )
2632                         };
2633                         
2634                         Point[] points_bottom_outer = {
2635                                 new Point( rectangle.X + 1, rectangle.Bottom - 2 ),
2636                                 new Point( rectangle.X + 2, rectangle.Bottom - 1 ),
2637                                 new Point( rectangle.Right - 3, rectangle.Bottom - 1 ),
2638                                 new Point( rectangle.Right - 2, rectangle.Bottom - 2 )
2639                         };
2640                         
2641                         // outer border
2642                         tmp_pen = ResPool.GetPen( button_outer_border_dark_color );
2643                         dc.DrawLines( tmp_pen, points_top_outer );
2644                         tmp_pen = ResPool.GetPen( button_outer_border_light_color );
2645                         dc.DrawLines( tmp_pen, points_bottom_outer );
2646                         
2647                         using ( LinearGradientBrush lgbr = new LinearGradientBrush( new Point( 0, 2 ), new Point( 0, rectangle.Height - 1 ), button_outer_border_dark_color, button_outer_border_light_color ) ) {
2648                                 dc.FillRectangle( lgbr, rectangle.X, rectangle.Y + 2, 1, rectangle.Height - 4 );
2649                                 dc.FillRectangle( lgbr, rectangle.Right - 1, rectangle.Y + 2, 1, rectangle.Height - 4 );
2650                         }
2651                         
2652                         tmp_pen = ResPool.GetPen( button_edge_top_outer_color );
2653                         dc.DrawLine( tmp_pen, rectangle.X, rectangle.Y + 1, rectangle.X + 1, rectangle.Y );
2654                         dc.DrawLine( tmp_pen, rectangle.Right - 2, rectangle.Y, rectangle.Right - 1, rectangle.Y + 1 );
2655                         
2656                         tmp_pen = ResPool.GetPen( button_edge_bottom_outer_color );
2657                         dc.DrawLine( tmp_pen, rectangle.X, rectangle.Bottom - 2, rectangle.X + 1, rectangle.Bottom - 1 );
2658                         dc.DrawLine( tmp_pen, rectangle.Right - 1, rectangle.Bottom - 2, rectangle.Right - 2, rectangle.Bottom - 1 );
2659                 }
2660                 
2661                 public override void CPDrawBorder( Graphics dc, Rectangle bounds, Color leftColor, int leftWidth,
2662                                                   ButtonBorderStyle leftStyle, Color topColor, int topWidth, ButtonBorderStyle topStyle,
2663                                                   Color rightColor, int rightWidth, ButtonBorderStyle rightStyle, Color bottomColor,
2664                                                   int bottomWidth, ButtonBorderStyle bottomStyle ) {
2665                         dc.DrawRectangle( ResPool.GetPen( combobox_border_color ), bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1 );
2666                 }
2667                 
2668                 // TODO: inactive...
2669                 public override void CPDrawCheckBox( Graphics dc, Rectangle rectangle, ButtonState state ) {
2670                         
2671                         bool pushed = ( state & ButtonState.Pushed ) != 0;
2672                         
2673                         int lineWidth;
2674                         Rectangle rect;
2675                         int scale;
2676                         
2677                         // background
2678                         dc.FillRectangle( ResPool.GetSolidBrush( pushed ? checkbox_pressed_backcolor : Color.White ), rectangle );
2679                         
2680                         // border
2681                         dc.DrawRectangle( ResPool.GetPen( scrollbar_border_color ), rectangle );
2682                         
2683                         Color inner_border_color = pushed ? checkbox_pressed_inner_boder_color : checkbox_inner_boder_color;
2684                         
2685                         Pen tmp_pen = ResPool.GetPen( inner_border_color );
2686                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 1, rectangle.Right - 1, rectangle.Y + 1 );
2687                         dc.DrawLine( tmp_pen, rectangle.X + 1, rectangle.Y + 2, rectangle.X + 1, rectangle.Bottom - 1 );
2688                         
2689                         /* Make sure we've got at least a line width of 1 */
2690                         lineWidth = Math.Max( 3, rectangle.Width / 6 );
2691                         scale = Math.Max( 1, rectangle.Width / 12 );
2692                         
2693                         // define a rectangle inside the border area
2694                         rect = new Rectangle( rectangle.X + 2, rectangle.Y + 2, rectangle.Width - 4, rectangle.Height - 4 );
2695                         if ( ( state & ButtonState.Inactive ) != 0 ) {
2696                                 tmp_pen = SystemPens.ControlDark;
2697                         } else {
2698                                 tmp_pen = SystemPens.ControlText;
2699                         }
2700                         
2701                         if ( ( state & ButtonState.Checked ) != 0 ) { 
2702                                 /* Need to draw a check-mark */
2703                                 for ( int i=0; i < lineWidth; i++ ) {
2704                                         dc.DrawLine( tmp_pen, rect.Left + lineWidth / 2, rect.Top + lineWidth + i, rect.Left + lineWidth / 2 + 2 * scale, rect.Top + lineWidth + 2 * scale + i );
2705                                         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 );
2706                                 }
2707                         }
2708                 }
2709                 
2710                 public  override void CPDrawStringDisabled( Graphics graphics, string s, Font font, Color color, RectangleF layoutRectangle,
2711                                                            StringFormat format ) {                      
2712                         
2713                         layoutRectangle.Offset( 1.0f, 1.0f );
2714                         graphics.DrawString( s, font, ResPool.GetSolidBrush( Color.White ), layoutRectangle, format );                  
2715                         layoutRectangle.Offset( -1.0f, -1.0f );
2716                         graphics.DrawString( s, font, ResPool.GetSolidBrush( disabled_color_foreground ), layoutRectangle, format );
2717                         
2718                 }
2719         } //class
2720 }
2721