2008-04-28 George Giolfan <georgegiolfan@yahoo.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ThemeVisualStyles.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) 2008 George Giolfan
21 // Copyright (c) 2004-2006 Novell, Inc.
22 //
23 // Authors:
24 //      George Giolfan, georgegiolfan@yahoo.com
25 //      Ernesto Carrea, equistango@gmail.com
26
27 using System.Drawing;
28 using System.Windows.Forms.VisualStyles;
29
30 namespace System.Windows.Forms
31 {
32         /// <summary>
33         /// VisualStyles theme.
34         /// </summary>
35         /// <remarks>
36         /// This theme uses only the managed VisualStyles API.
37         /// To select it, set MONO_THEME to VisualStyles and call <see cref="Application.EnableVisualStyles"/>.
38         /// </remarks>
39         class ThemeVisualStyles : ThemeWin32Classic
40         {
41                 #region ButtonBase
42                 public override void DrawButtonBase (Graphics dc, Rectangle clip_area, ButtonBase button)
43                 {
44                         if (button.FlatStyle == FlatStyle.System) {
45                                 ButtonRenderer.DrawButton (
46                                         dc,
47                                         new Rectangle (Point.Empty, button.Size),
48                                         button.Text,
49                                         button.Font,
50                                         button.TextFormatFlags,
51                                         null,
52                                         Rectangle.Empty,
53                                         ShouldPaintFocusRectagle (button),
54                                         GetPushButtonState (button)
55                                 );
56                                 return;
57                         }
58                         base.DrawButtonBase (dc, clip_area, button);
59                 }
60                 static PushButtonState GetPushButtonState (ButtonBase button)
61                 {
62                         if (!button.Enabled)
63                                 return PushButtonState.Disabled;
64                         if (button.Pressed)
65                                 return PushButtonState.Pressed;
66                         if (button.Entered)
67                                 return PushButtonState.Hot;
68                         if (button.IsDefault || button.Focused || button.paint_as_acceptbutton)
69                                 return PushButtonState.Default;
70                         return PushButtonState.Normal;
71                 }
72                 #endregion
73 #if NET_2_0
74                 #region Button 2.0
75                 public override void DrawButtonBackground (Graphics g, Button button, Rectangle clipArea)
76                 {
77                         if (!button.UseVisualStyleBackColor) {
78                                 base.DrawButtonBackground (g, button, clipArea);
79                                 return;
80                         }
81                         ButtonRenderer.GetPushButtonRenderer (GetPushButtonState (button)).DrawBackground (g, new Rectangle (Point.Empty, button.Size));
82                 }
83                 #endregion
84 #endif
85                 #region CheckBox
86                 protected override void CheckBox_DrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle)
87                 {
88                         if (checkbox.Appearance == Appearance.Normal && checkbox.FlatStyle == FlatStyle.System) {
89                                 CheckBoxRenderer.DrawCheckBox (
90                                         dc,
91                                         new Point (checkbox_rectangle.Left, checkbox_rectangle.Top),
92                                         GetCheckBoxState (checkbox)
93                                 );
94                                 return;
95                         }
96                         base.CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
97                 }
98                 static CheckBoxState GetCheckBoxState (CheckBox checkBox)
99                 {
100                         switch (checkBox.CheckState) {
101                         case CheckState.Checked:
102                                 if (!checkBox.Enabled)
103                                         return CheckBoxState.CheckedDisabled;
104                                 else if (checkBox.Pressed)
105                                         return CheckBoxState.CheckedPressed;
106                                 else if (checkBox.Entered)
107                                         return CheckBoxState.CheckedHot;
108                                 return CheckBoxState.CheckedNormal;
109                         case CheckState.Indeterminate:
110                                 if (!checkBox.Enabled)
111                                         return CheckBoxState.MixedDisabled;
112                                 else if (checkBox.Pressed)
113                                         return CheckBoxState.MixedPressed;
114                                 else if (checkBox.Entered)
115                                         return CheckBoxState.MixedHot;
116                                 return CheckBoxState.MixedNormal;
117                         default:
118                                 if (!checkBox.Enabled)
119                                         return CheckBoxState.UncheckedDisabled;
120                                 else if (checkBox.Pressed)
121                                         return CheckBoxState.UncheckedPressed;
122                                 else if (checkBox.Entered)
123                                         return CheckBoxState.UncheckedHot;
124                                 return CheckBoxState.UncheckedNormal;
125                         }
126                 }
127                 #endregion
128                 #region ControlPaint
129                 #region DrawCaptionButton
130                 public override void CPDrawCaptionButton (Graphics graphics, Rectangle rectangle, CaptionButton button, ButtonState state)
131                 {
132                         if ((state & ButtonState.Flat) == ButtonState.Flat ||
133                                 (state & ButtonState.Checked) == ButtonState.Checked) {
134                                 base.CPDrawCaptionButton (graphics, rectangle, button, state);
135                                 return;
136                         }
137                         VisualStyleElement element = GetCaptionButtonVisualStyleElement (button, state);
138                         if (!VisualStyleRenderer.IsElementDefined (element)) {
139                                 base.CPDrawCaptionButton (graphics, rectangle, button, state);
140                                 return;
141                         }
142                         new VisualStyleRenderer (element).DrawBackground (graphics, rectangle);
143                 }
144                 static VisualStyleElement GetCaptionButtonVisualStyleElement (CaptionButton button, ButtonState state)
145                 {
146                         switch (button) {
147                         case CaptionButton.Minimize:
148                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
149                                         return VisualStyleElement.Window.MinButton.Disabled;
150                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
151                                         return VisualStyleElement.Window.MinButton.Pressed;
152                                 else
153                                         return VisualStyleElement.Window.MinButton.Normal;
154                         case CaptionButton.Maximize:
155                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
156                                         return VisualStyleElement.Window.MaxButton.Disabled;
157                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
158                                         return VisualStyleElement.Window.MaxButton.Pressed;
159                                 else
160                                         return VisualStyleElement.Window.MaxButton.Normal;
161                         case CaptionButton.Close:
162                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
163                                         return VisualStyleElement.Window.CloseButton.Disabled;
164                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
165                                         return VisualStyleElement.Window.CloseButton.Pressed;
166                                 else
167                                         return VisualStyleElement.Window.CloseButton.Normal;
168                         case CaptionButton.Restore:
169                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
170                                         return VisualStyleElement.Window.RestoreButton.Disabled;
171                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
172                                         return VisualStyleElement.Window.RestoreButton.Pressed;
173                                 else
174                                         return VisualStyleElement.Window.RestoreButton.Normal;
175                         default:
176                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
177                                         return VisualStyleElement.Window.HelpButton.Disabled;
178                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
179                                         return VisualStyleElement.Window.HelpButton.Pressed;
180                                 else
181                                         return VisualStyleElement.Window.HelpButton.Normal;
182                         }
183                 }
184                 #endregion
185                 #region DrawCheckBox
186                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
187                 {
188                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
189                                 base.CPDrawCheckBox (dc, rectangle, state);
190                                 return;
191                         }
192                         VisualStyleElement element;
193                         if ((state & ButtonState.Checked) == ButtonState.Checked)
194                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
195                                         element = VisualStyleElement.Button.CheckBox.CheckedDisabled;
196                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
197                                         element = VisualStyleElement.Button.CheckBox.CheckedPressed;
198                                 else
199                                         element = VisualStyleElement.Button.CheckBox.CheckedNormal;
200                         else
201                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
202                                         element = VisualStyleElement.Button.CheckBox.UncheckedDisabled;
203                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
204                                         element = VisualStyleElement.Button.CheckBox.UncheckedPressed;
205                                 else
206                                         element = VisualStyleElement.Button.CheckBox.UncheckedNormal;
207                         if (!VisualStyleRenderer.IsElementDefined (element)) {
208                                 base.CPDrawCheckBox (dc, rectangle, state);
209                                 return;
210                         }
211                         new VisualStyleRenderer (element).DrawBackground (dc, rectangle);
212                 }
213                 #endregion
214                 #region DrawRadioButton
215                 public override void CPDrawRadioButton (Graphics dc, Rectangle rectangle, ButtonState state)
216                 {
217                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
218                                 base.CPDrawRadioButton (dc, rectangle, state);
219                                 return;
220                         }
221                         VisualStyleElement element;
222                         if ((state & ButtonState.Checked) == ButtonState.Checked)
223                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
224                                         element = VisualStyleElement.Button.RadioButton.CheckedDisabled;
225                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
226                                         element = VisualStyleElement.Button.RadioButton.CheckedPressed;
227                                 else
228                                         element = VisualStyleElement.Button.RadioButton.CheckedNormal;
229                         else
230                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
231                                         element = VisualStyleElement.Button.RadioButton.UncheckedDisabled;
232                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
233                                         element = VisualStyleElement.Button.RadioButton.UncheckedPressed;
234                                 else
235                                         element = VisualStyleElement.Button.RadioButton.UncheckedNormal;
236                         if (!VisualStyleRenderer.IsElementDefined (element)) {
237                                 base.CPDrawRadioButton (dc, rectangle, state);
238                                 return;
239                         }
240                         new VisualStyleRenderer (element).DrawBackground (dc, rectangle);
241                 }
242                 #endregion
243                 #region DrawScrollButton
244                 public override void CPDrawScrollButton (Graphics dc, Rectangle area, ScrollButton type, ButtonState state)
245                 {
246                         if ((state & ButtonState.Flat) == ButtonState.Flat ||
247                                 (state & ButtonState.Checked) == ButtonState.Checked) {
248                                 base.CPDrawScrollButton (dc, area, type, state);
249                                 return;
250                         }
251                         VisualStyleElement element = GetScrollButtonVisualStyleElement (type, state);
252                         if (!VisualStyleRenderer.IsElementDefined (element)) {
253                                 base.CPDrawScrollButton (dc, area, type, state);
254                                 return;
255                         }
256                         new VisualStyleRenderer (element).DrawBackground (dc, area);
257                 }
258                 static VisualStyleElement GetScrollButtonVisualStyleElement (ScrollButton type, ButtonState state)
259                 {
260                         switch (type) {
261                         case ScrollButton.Left:
262                                 if (IsDisabled (state))
263                                         return VisualStyleElement.ScrollBar.ArrowButton.LeftDisabled;
264                                 else if (IsPressed (state))
265                                         return VisualStyleElement.ScrollBar.ArrowButton.LeftPressed;
266                                 else
267                                         return VisualStyleElement.ScrollBar.ArrowButton.LeftNormal;
268                         case ScrollButton.Right:
269                                 if (IsDisabled (state))
270                                         return VisualStyleElement.ScrollBar.ArrowButton.RightDisabled;
271                                 else if (IsPressed (state))
272                                         return VisualStyleElement.ScrollBar.ArrowButton.RightPressed;
273                                 else
274                                         return VisualStyleElement.ScrollBar.ArrowButton.RightNormal;
275                         case ScrollButton.Up:
276                                 if (IsDisabled (state))
277                                         return VisualStyleElement.ScrollBar.ArrowButton.UpDisabled;
278                                 else if (IsPressed (state))
279                                         return VisualStyleElement.ScrollBar.ArrowButton.UpPressed;
280                                 else
281                                         return VisualStyleElement.ScrollBar.ArrowButton.UpNormal;
282                         default:
283                                 if (IsDisabled (state))
284                                         return VisualStyleElement.ScrollBar.ArrowButton.DownDisabled;
285                                 else if (IsPressed (state))
286                                         return VisualStyleElement.ScrollBar.ArrowButton.DownPressed;
287                                 else
288                                         return VisualStyleElement.ScrollBar.ArrowButton.DownNormal;
289                         }
290                 }
291                 static bool IsDisabled (ButtonState state)
292                 {
293                         return (state & ButtonState.Inactive) == ButtonState.Inactive;
294                 }
295                 static bool IsPressed (ButtonState state)
296                 {
297                         return (state & ButtonState.Pushed) == ButtonState.Pushed;
298                 }
299                 #endregion
300                 #endregion
301                 #region Managed windows
302                 [MonoTODO("When other VisualStyles implementations are supported, check if the visual style elements are defined.")]
303                 [MonoTODO("When the rest of the MDI code is fixed, make sure minimized windows are painted correctly,restrict the caption text drawing area to exclude the title buttons and handle the title bar height correctly.")]
304                 public override void DrawManagedWindowDecorations (Graphics dc, Rectangle clip, InternalWindowManager wm)
305                 {
306                         if (!wm.HasBorders || (wm.Form.IsMdiChild && wm.IsMaximized))
307                                 return;
308                         VisualStyleElement element;
309                         #region Title bar background
310                         #region Select caption visual style element
311                         if (wm.IsToolWindow)
312                                 #region Small window
313                                 switch (wm.form.window_state) {
314                                 case FormWindowState.Minimized:
315                                         if (!wm.Form.Enabled)
316                                                 element = VisualStyleElement.Window.SmallMinCaption.Disabled;
317                                         else if (wm.IsActive)
318                                                 element = VisualStyleElement.Window.SmallMinCaption.Active;
319                                         else
320                                                 element = VisualStyleElement.Window.SmallMinCaption.Inactive;
321                                         break;
322                                 case FormWindowState.Maximized:
323                                         if (!wm.Form.Enabled)
324                                                 element = VisualStyleElement.Window.SmallMaxCaption.Disabled;
325                                         else if (wm.IsActive)
326                                                 element = VisualStyleElement.Window.SmallMaxCaption.Active;
327                                         else
328                                                 element = VisualStyleElement.Window.SmallMaxCaption.Inactive;
329                                         break;
330                                 default:
331                                         if (!wm.Form.Enabled)
332                                                 element = VisualStyleElement.Window.SmallCaption.Disabled;
333                                         else if (wm.IsActive)
334                                                 element = VisualStyleElement.Window.SmallCaption.Active;
335                                         else
336                                                 element = VisualStyleElement.Window.SmallCaption.Inactive;
337                                         break;
338                                 }
339                                 #endregion
340                         else
341                                 #region Normal window
342                                 switch (wm.form.window_state) {
343                                 case FormWindowState.Minimized:
344                                         if (!wm.Form.Enabled)
345                                                 element = VisualStyleElement.Window.MinCaption.Disabled;
346                                         else if (wm.IsActive)
347                                                 element = VisualStyleElement.Window.MinCaption.Active;
348                                         else
349                                                 element = VisualStyleElement.Window.MinCaption.Inactive;
350                                         break;
351                                 case FormWindowState.Maximized:
352                                         if (!wm.Form.Enabled)
353                                                 element = VisualStyleElement.Window.MaxCaption.Disabled;
354                                         else if (wm.IsActive)
355                                                 element = VisualStyleElement.Window.MaxCaption.Active;
356                                         else
357                                                 element = VisualStyleElement.Window.MaxCaption.Inactive;
358                                         break;
359                                 default:
360                                         if (!wm.Form.Enabled)
361                                                 element = VisualStyleElement.Window.Caption.Disabled;
362                                         else if (wm.IsActive)
363                                                 element = VisualStyleElement.Window.Caption.Active;
364                                         else
365                                                 element = VisualStyleElement.Window.Caption.Inactive;
366                                         break;
367                                 }
368                                 #endregion
369                         #endregion
370                         VisualStyleRenderer renderer = new VisualStyleRenderer (element);
371                         Rectangle title_bar_rectangle = new Rectangle (
372                                 0,
373                                 0,
374                                 wm.Form.Width,
375                                 renderer.GetPartSize (dc, ThemeSizeType.True).Height
376                         );
377                         Rectangle caption_text_area = title_bar_rectangle;
378                         renderer.DrawBackground (dc, title_bar_rectangle, clip);
379                         #endregion
380                         int border_width = ManagedWindowBorderWidth (wm);
381                         #region Icon
382                         if (!wm.IsToolWindow && wm.Form.FormBorderStyle != FormBorderStyle.FixedDialog
383 #if NET_2_0
384                         && wm.Form.ShowIcon
385 #endif
386                         ) {
387                                 Rectangle icon_rectangle = new Rectangle (
388                                         border_width + 3,
389                                         border_width + 2,
390                                         wm.IconWidth,
391                                         wm.IconWidth);
392                                 caption_text_area.X += icon_rectangle.Width;
393                                 if (icon_rectangle.IntersectsWith (clip))
394                                         dc.DrawIcon (wm.Form.Icon, icon_rectangle);
395                         }
396                         #endregion
397                         #region Title bar buttons
398                         foreach (TitleButton button in wm.TitleButtons.AllButtons) {
399                                 if (!button.Visible || !button.Rectangle.IntersectsWith (clip))
400                                         continue;
401                                 new VisualStyleRenderer (GetCaptionButtonVisualStyleElement (button.Caption, button.State)).DrawBackground (dc, button.Rectangle, clip);
402                         }
403                         #endregion
404                         #region Borders
405                         if (wm.GetWindowState () == FormWindowState.Normal) {
406                                 #region Left
407                                 if (wm.IsToolWindow)
408                                         if (wm.IsActive)
409                                                 element = VisualStyleElement.Window.SmallFrameLeft.Active;
410                                         else
411                                                 element = VisualStyleElement.Window.SmallFrameLeft.Inactive;
412                                 else
413                                         if (wm.IsActive)
414                                                 element = VisualStyleElement.Window.FrameLeft.Active;
415                                         else
416                                                 element = VisualStyleElement.Window.FrameLeft.Inactive;
417                                 renderer = new VisualStyleRenderer (element);
418                                 renderer.DrawBackground (dc, new Rectangle (
419                                         0,
420                                         title_bar_rectangle.Bottom,
421                                         border_width,
422                                         wm.form.Height - title_bar_rectangle.Bottom
423                                         ), clip);
424                                 #endregion
425                                 #region Right
426                                 if (wm.IsToolWindow)
427                                         if (wm.IsActive)
428                                                 element = VisualStyleElement.Window.SmallFrameRight.Active;
429                                         else
430                                                 element = VisualStyleElement.Window.SmallFrameRight.Inactive;
431                                 else
432                                         if (wm.IsActive)
433                                                 element = VisualStyleElement.Window.FrameRight.Active;
434                                         else
435                                                 element = VisualStyleElement.Window.FrameRight.Inactive;
436
437                                 renderer = new VisualStyleRenderer (element);
438                                 renderer.DrawBackground (dc, new Rectangle (
439                                         wm.form.Width - border_width,
440                                         title_bar_rectangle.Bottom,
441                                         border_width,
442                                         wm.form.Height - title_bar_rectangle.Bottom
443                                         ), clip);
444                                 #endregion
445                                 #region Bottom
446                                 if (wm.IsToolWindow)
447                                         if (wm.IsActive)
448                                                 element = VisualStyleElement.Window.SmallFrameBottom.Active;
449                                         else
450                                                 element = VisualStyleElement.Window.SmallFrameBottom.Inactive;
451                                 else
452                                         if (wm.IsActive)
453                                                 element = VisualStyleElement.Window.FrameBottom.Active;
454                                         else
455                                                 element = VisualStyleElement.Window.FrameBottom.Inactive;
456
457                                 renderer = new VisualStyleRenderer (element);
458                                 renderer.DrawBackground (dc, new Rectangle (
459                                         0,
460                                         wm.form.Height - border_width,
461                                         wm.form.Width,
462                                         border_width
463                                         ), clip);
464                                 #endregion
465                                 caption_text_area.X += border_width;
466                         }
467                         #endregion
468                         #region Caption text
469                         string window_caption = wm.Form.Text;
470                         if (window_caption != null && window_caption.Length != 0 && caption_text_area.IntersectsWith (clip)) {
471                                 StringFormat format = new StringFormat ();
472                                 format.FormatFlags = StringFormatFlags.NoWrap;
473                                 format.Trimming = StringTrimming.EllipsisCharacter;
474                                 format.LineAlignment = StringAlignment.Center;
475                                 dc.DrawString (
476                                         window_caption,
477                                         WindowBorderFont,
478                                         ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
479                                         caption_text_area,
480                                         format
481                                 );
482                         }
483                         #endregion
484                 }
485                 #endregion
486                 #region ProgressBar
487                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
488                 {
489                         if (!VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Bar.Normal) ||
490                                 !VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Chunk.Normal)) {
491                                 base.DrawProgressBar (dc, clip_rect, ctrl);
492                                 return;
493                         }
494                         VisualStyleRenderer renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Bar.Normal);
495                         renderer.DrawBackground (dc, ctrl.ClientRectangle, clip_rect);
496                         Rectangle client_area = renderer.GetBackgroundContentRectangle (dc, new Rectangle (Point.Empty, ctrl.Size));
497                         renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Chunk.Normal);
498                         /* Draw Blocks */
499                         int draw_mode = 0;
500                         int max_blocks = int.MaxValue;
501                         int start_pixel = client_area.X;
502 #if NET_2_0
503                         draw_mode = (int)ctrl.Style;
504 #endif
505                         switch (draw_mode) {
506 #if NET_2_0
507                         case 1: // Continuous
508                                 client_area.Width = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max (ctrl.Maximum - ctrl.Minimum, 1))));
509                                 renderer.DrawBackground (dc, client_area, clip_rect);
510                                 break;
511                         case 2: // Marquee
512                                 int ms_diff = (int)(DateTime.Now - ctrl.start).TotalMilliseconds;
513                                 double percent_done = (double)ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
514                                 max_blocks = 5;
515                                 start_pixel = client_area.X + (int)(client_area.Width * percent_done);
516                                 goto default;
517 #endif
518                         default: // Blocks
519                                 int block_width = renderer.GetInteger (IntegerProperty.ProgressChunkSize);
520                                 int first_pixel_outside_filled_area = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)) + client_area.X;
521                                 int block_count = 0;
522                                 int increment = block_width + renderer.GetInteger (IntegerProperty.ProgressSpaceSize);
523                                 Rectangle block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
524                                 while (true) {
525                                         if (max_blocks != int.MaxValue) {
526                                                 if (block_count == max_blocks)
527                                                         break;
528                                                 if (block_rect.Right >= client_area.Width)
529                                                         block_rect.X -= client_area.Width;
530                                         } else {
531                                                 if (block_rect.X >= first_pixel_outside_filled_area)
532                                                         break;
533                                                 if (block_rect.Right >= first_pixel_outside_filled_area)
534                                                         if (first_pixel_outside_filled_area == client_area.Right)
535                                                                 block_rect.Width = first_pixel_outside_filled_area - block_rect.X;
536                                                         else
537                                                                 break;
538                                         }
539                                         if (clip_rect.IntersectsWith (block_rect))
540                                                 renderer.DrawBackground (dc, block_rect, clip_rect);
541                                         block_rect.X += increment;
542                                         block_count++;
543                                 }
544                                 break;
545                         }
546                 }
547                 #endregion
548                 #region RadioButton
549                 protected override void RadioButton_DrawButton (RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) {
550                         if (radio_button.Appearance == Appearance.Normal && radio_button.FlatStyle == FlatStyle.System) {
551                                 RadioButtonRenderer.DrawRadioButton (
552                                         dc,
553                                         new Point (radiobutton_rectangle.Left, radiobutton_rectangle.Top),
554                                         GetRadioButtonState (radio_button)
555                                 );
556                                 return;
557                         }
558                         base.RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
559                 }
560                 static RadioButtonState GetRadioButtonState (RadioButton checkBox)
561                 {
562                         if (checkBox.Checked) {
563                                 if (!checkBox.Enabled)
564                                         return RadioButtonState.CheckedDisabled;
565                                 else if (checkBox.Pressed)
566                                         return RadioButtonState.CheckedPressed;
567                                 else if (checkBox.Entered)
568                                         return RadioButtonState.CheckedHot;
569                                 return RadioButtonState.CheckedNormal;
570                         } else {
571                                 if (!checkBox.Enabled)
572                                         return RadioButtonState.UncheckedDisabled;
573                                 else if (checkBox.Pressed)
574                                         return RadioButtonState.UncheckedPressed;
575                                 else if (checkBox.Entered)
576                                         return RadioButtonState.UncheckedHot;
577                                 return RadioButtonState.UncheckedNormal;
578                         }
579                 }
580                 #endregion
581         }
582 }