2008-04-25 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                         ButtonRenderer.GetPushButtonRenderer (GetPushButtonState (button)).DrawBackground (g, new Rectangle (Point.Empty, button.Size));
78                 }
79                 #endregion
80 #endif
81                 #region CheckBox
82                 protected override void CheckBox_DrawCheckBox (Graphics dc, CheckBox checkbox, ButtonState state, Rectangle checkbox_rectangle)
83                 {
84                         if (checkbox.Appearance == Appearance.Normal && checkbox.FlatStyle == FlatStyle.System) {
85                                 CheckBoxRenderer.DrawCheckBox (
86                                         dc,
87                                         new Point (checkbox_rectangle.Left, checkbox_rectangle.Top),
88                                         GetCheckBoxState (checkbox)
89                                 );
90                                 return;
91                         }
92                         base.CheckBox_DrawCheckBox(dc, checkbox, state, checkbox_rectangle);
93                 }
94                 static CheckBoxState GetCheckBoxState (CheckBox checkBox)
95                 {
96                         switch (checkBox.CheckState) {
97                         case CheckState.Checked:
98                                 if (!checkBox.Enabled)
99                                         return CheckBoxState.CheckedDisabled;
100                                 else if (checkBox.Pressed)
101                                         return CheckBoxState.CheckedPressed;
102                                 else if (checkBox.Entered)
103                                         return CheckBoxState.CheckedHot;
104                                 return CheckBoxState.CheckedNormal;
105                         case CheckState.Indeterminate:
106                                 if (!checkBox.Enabled)
107                                         return CheckBoxState.MixedDisabled;
108                                 else if (checkBox.Pressed)
109                                         return CheckBoxState.MixedPressed;
110                                 else if (checkBox.Entered)
111                                         return CheckBoxState.MixedHot;
112                                 return CheckBoxState.MixedNormal;
113                         default:
114                                 if (!checkBox.Enabled)
115                                         return CheckBoxState.UncheckedDisabled;
116                                 else if (checkBox.Pressed)
117                                         return CheckBoxState.UncheckedPressed;
118                                 else if (checkBox.Entered)
119                                         return CheckBoxState.UncheckedHot;
120                                 return CheckBoxState.UncheckedNormal;
121                         }
122                 }
123                 #endregion
124                 #region ControlPaint
125                 public override void CPDrawCheckBox (Graphics dc, Rectangle rectangle, ButtonState state)
126                 {
127                         if ((state & ButtonState.Flat) == ButtonState.Flat) {
128                                 base.CPDrawCheckBox (dc, rectangle, state);
129                                 return;
130                         }
131                         VisualStyleElement element;
132                         if ((state & ButtonState.Checked) == ButtonState.Checked)
133                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
134                                         element = VisualStyleElement.Button.CheckBox.CheckedDisabled;
135                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
136                                         element = VisualStyleElement.Button.CheckBox.CheckedPressed;
137                                 else
138                                         element = VisualStyleElement.Button.CheckBox.CheckedNormal;
139                         else
140                                 if ((state & ButtonState.Inactive) == ButtonState.Inactive)
141                                         element = VisualStyleElement.Button.CheckBox.UncheckedDisabled;
142                                 else if ((state & ButtonState.Pushed) == ButtonState.Pushed)
143                                         element = VisualStyleElement.Button.CheckBox.UncheckedPressed;
144                                 else
145                                         element = VisualStyleElement.Button.CheckBox.UncheckedNormal;
146                         if (!VisualStyleRenderer.IsElementDefined (element)) {
147                                 base.CPDrawCheckBox (dc, rectangle, state);
148                                 return;
149                         }
150                         new VisualStyleRenderer (element).DrawBackground (dc, rectangle);
151                 }
152                 #endregion
153                 #region ProgressBar
154                 public override void DrawProgressBar (Graphics dc, Rectangle clip_rect, ProgressBar ctrl)
155                 {
156                         if (!VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Bar.Normal) ||
157                                 !VisualStyleRenderer.IsElementDefined (VisualStyleElement.ProgressBar.Chunk.Normal)) {
158                                 base.DrawProgressBar (dc, clip_rect, ctrl);
159                                 return;
160                         }
161                         VisualStyleRenderer renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Bar.Normal);
162                         renderer.DrawBackground (dc, ctrl.ClientRectangle, clip_rect);
163                         Rectangle client_area = renderer.GetBackgroundContentRectangle (dc, new Rectangle (Point.Empty, ctrl.Size));
164                         renderer = new VisualStyleRenderer (VisualStyleElement.ProgressBar.Chunk.Normal);
165                         /* Draw Blocks */
166                         int draw_mode = 0;
167                         int max_blocks = int.MaxValue;
168                         int start_pixel = client_area.X;
169 #if NET_2_0
170                         draw_mode = (int)ctrl.Style;
171 #endif
172                         switch (draw_mode) {
173 #if NET_2_0
174                         case 1: // Continuous
175                                 client_area.Width = (int)(client_area.Width * ((double)(ctrl.Value - ctrl.Minimum) / (double)(Math.Max (ctrl.Maximum - ctrl.Minimum, 1))));
176                                 renderer.DrawBackground (dc, client_area, clip_rect);
177                                 break;
178                         case 2: // Marquee
179                                 int ms_diff = (int)(DateTime.Now - ctrl.start).TotalMilliseconds;
180                                 double percent_done = (double)ms_diff % (double)ctrl.MarqueeAnimationSpeed / (double)ctrl.MarqueeAnimationSpeed;
181                                 max_blocks = 5;
182                                 start_pixel = client_area.X + (int)(client_area.Width * percent_done);
183                                 goto default;
184 #endif
185                         default: // Blocks
186                                 int block_width = renderer.GetInteger (IntegerProperty.ProgressChunkSize);
187                                 int first_pixel_outside_filled_area = ((ctrl.Value - ctrl.Minimum) * client_area.Width) / (Math.Max (ctrl.Maximum - ctrl.Minimum, 1)) + client_area.X;
188                                 int block_count = 0;
189                                 int increment = block_width + renderer.GetInteger (IntegerProperty.ProgressSpaceSize);
190                                 Rectangle block_rect = new Rectangle (start_pixel, client_area.Y, block_width, client_area.Height);
191                                 while (true) {
192                                         if (max_blocks != int.MaxValue) {
193                                                 if (block_count == max_blocks)
194                                                         break;
195                                                 if (block_rect.Right >= client_area.Width)
196                                                         block_rect.X -= client_area.Width;
197                                         } else {
198                                                 if (block_rect.X >= first_pixel_outside_filled_area)
199                                                         break;
200                                                 if (block_rect.Right >= first_pixel_outside_filled_area)
201                                                         if (first_pixel_outside_filled_area == client_area.Right)
202                                                                 block_rect.Width = first_pixel_outside_filled_area - block_rect.X;
203                                                         else
204                                                                 break;
205                                         }
206                                         if (clip_rect.IntersectsWith (block_rect))
207                                                 renderer.DrawBackground (dc, block_rect, clip_rect);
208                                         block_rect.X += increment;
209                                         block_count++;
210                                 }
211                                 break;
212                         }
213                 }
214                 #endregion
215                 #region RadioButton
216                 protected override void RadioButton_DrawButton (RadioButton radio_button, Graphics dc, ButtonState state, Rectangle radiobutton_rectangle) {
217                         if (radio_button.Appearance == Appearance.Normal && radio_button.FlatStyle == FlatStyle.System) {
218                                 RadioButtonRenderer.DrawRadioButton (
219                                         dc,
220                                         new Point (radiobutton_rectangle.Left, radiobutton_rectangle.Top),
221                                         GetRadioButtonState (radio_button)
222                                 );
223                                 return;
224                         }
225                         base.RadioButton_DrawButton(radio_button, dc, state, radiobutton_rectangle);
226                 }
227                 static RadioButtonState GetRadioButtonState (RadioButton checkBox)
228                 {
229                         if (checkBox.Checked) {
230                                 if (!checkBox.Enabled)
231                                         return RadioButtonState.CheckedDisabled;
232                                 else if (checkBox.Pressed)
233                                         return RadioButtonState.CheckedPressed;
234                                 else if (checkBox.Entered)
235                                         return RadioButtonState.CheckedHot;
236                                 return RadioButtonState.CheckedNormal;
237                         } else {
238                                 if (!checkBox.Enabled)
239                                         return RadioButtonState.UncheckedDisabled;
240                                 else if (checkBox.Pressed)
241                                         return RadioButtonState.UncheckedPressed;
242                                 else if (checkBox.Entered)
243                                         return RadioButtonState.UncheckedHot;
244                                 return RadioButtonState.UncheckedNormal;
245                         }
246                 }
247                 #endregion
248         }
249 }