importing messaging-2008 branch to trunk.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ProgressBar.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-2006 Novell, Inc.
21 //
22 // Authors:
23 //              Jordi Mas i Hernandez   jordi@ximian.com
24 //              Peter Dennis Bartok     pbartok@novell.com
25 //
26 //
27
28 using System.Drawing;
29 using System.ComponentModel;
30 using System.Drawing.Imaging;
31 using System.Drawing.Drawing2D;
32 using System.Runtime.InteropServices;
33
34 namespace System.Windows.Forms
35 {
36         [DefaultProperty ("Value")]
37 #if NET_2_0
38         [DefaultBindingProperty ("Value")]
39         [ClassInterface (ClassInterfaceType.AutoDispatch)]
40         [ComVisible (true)]
41 #endif
42         public
43 #if !NET_2_0
44         sealed
45 #endif
46         class ProgressBar : Control
47         {
48                 #region Local Variables
49                 private int maximum;
50                 private int minimum;
51                 internal int step;
52                 internal int val;
53                 internal DateTime start = DateTime.Now;
54                 internal Rectangle client_area = new Rectangle ();
55 #if NET_2_0
56                 internal ProgressBarStyle style;
57                 Timer marquee_timer;
58                 bool right_to_left_layout;
59 #endif
60
61 #if NET_2_0
62                 private static readonly Color defaultForeColor = SystemColors.Highlight;
63 #endif
64                 #endregion      // Local Variables
65
66                 #region events
67
68 #if NET_2_0
69                 static object RightToLeftLayoutChangedEvent = new object ();
70 #endif
71                         
72 #if ONLY_1_1
73                 [Browsable (false)]
74                 [EditorBrowsable (EditorBrowsableState.Never)]
75                 public new event EventHandler BackColorChanged {
76                         add { base.BackColorChanged += value; }
77                         remove { base.BackColorChanged -= value; }
78                 }
79 #endif
80                 
81                 [Browsable (false)]
82                 [EditorBrowsable (EditorBrowsableState.Never)]
83                 public new event EventHandler BackgroundImageChanged {
84                         add { base.BackgroundImageChanged += value; }
85                         remove { base.BackgroundImageChanged -= value; }
86                 }
87                 
88 #if NET_2_0
89                 [Browsable(false)]
90                 [EditorBrowsable(EditorBrowsableState.Never)]
91                 public new event EventHandler BackgroundImageLayoutChanged {
92                         add     { base.BackgroundImageLayoutChanged += value; }
93                         remove { base.BackgroundImageLayoutChanged -= value; }
94                 }
95 #endif
96                         
97                 [Browsable (false)]
98                 [EditorBrowsable (EditorBrowsableState.Never)]
99                 public new event EventHandler CausesValidationChanged {
100                         add { base.CausesValidationChanged += value; }
101                         remove { base.CausesValidationChanged -= value; }
102                 }
103                 
104                 [Browsable (false)]
105                 [EditorBrowsable (EditorBrowsableState.Never)]
106                 public new event EventHandler DoubleClick {
107                         add { base.DoubleClick += value; }
108                         remove { base.DoubleClick -= value; }
109                 }
110                 
111                 [Browsable (false)]
112                 [EditorBrowsable (EditorBrowsableState.Never)]
113                 public new event EventHandler Enter {
114                         add { base.Enter += value; }
115                         remove { base.Enter -= value; }
116                 }
117                 
118                 [Browsable (false)]
119                 [EditorBrowsable (EditorBrowsableState.Never)]
120                 public new event EventHandler FontChanged {
121                         add { base.FontChanged += value; }
122                         remove { base.FontChanged -= value; }
123                 }
124                 
125 #if ONLY_1_1
126                 [Browsable (false)]
127                 [EditorBrowsable (EditorBrowsableState.Never)]
128                 public new event EventHandler ForeColorChanged {
129                         add { base.ForeColorChanged += value; }
130                         remove { base.ForeColorChanged -= value; }
131                 }
132 #endif
133                 
134                 [Browsable (false)]
135                 [EditorBrowsable (EditorBrowsableState.Never)]
136                 public new event EventHandler ImeModeChanged {
137                         add { base.ImeModeChanged += value; }
138                         remove { base.ImeModeChanged -= value; }
139                 }
140                 
141                 [Browsable (false)]
142                 [EditorBrowsable (EditorBrowsableState.Never)]
143                 public new event KeyEventHandler KeyDown {
144                         add { base.KeyDown += value; }
145                         remove { base.KeyDown -= value; }
146                 }
147                 
148                 [Browsable (false)]
149                 [EditorBrowsable (EditorBrowsableState.Never)]
150                 public new event KeyPressEventHandler KeyPress {
151                         add { base.KeyPress += value; }
152                         remove { base.KeyPress -= value; }
153                 }
154                 
155                 [Browsable (false)]
156                 [EditorBrowsable (EditorBrowsableState.Never)]
157                 public new event KeyEventHandler KeyUp {
158                         add { base.KeyUp += value; }
159                         remove { base.KeyUp -= value; }
160                 }
161                 
162                 [Browsable (false)]
163                 [EditorBrowsable (EditorBrowsableState.Never)]
164                 public new event EventHandler Leave {
165                         add { base.Leave += value; }
166                         remove { base.Leave -= value; }
167                 }
168
169 #if NET_2_0
170                 [EditorBrowsable(EditorBrowsableState.Never)]
171                 [Browsable(false)]
172                 public new event MouseEventHandler MouseDoubleClick {
173                         add { base.MouseDoubleClick += value; }
174                         remove { base.MouseDoubleClick -= value; }
175                 }
176                         
177                 [Browsable(false)]
178                 [EditorBrowsable(EditorBrowsableState.Never)]
179                 public new event EventHandler PaddingChanged {
180                         add { base.PaddingChanged += value; }
181                         remove { base.PaddingChanged -= value; }
182                 }
183 #endif
184                         
185                 [Browsable (false)]
186                 [EditorBrowsable (EditorBrowsableState.Never)]
187                 public new event PaintEventHandler Paint {
188                         add { base.Paint += value; }
189                         remove { base.Paint -= value; }
190                 }
191                 
192 #if ONLY_1_1
193                 [Browsable (false)]
194                 [EditorBrowsable (EditorBrowsableState.Never)]
195                 public new event EventHandler RightToLeftChanged {
196                         add { base.RightToLeftChanged += value; }
197                         remove { base.RightToLeftChanged -= value; }
198                 }
199 #endif
200 #if NET_2_0
201                 public event EventHandler RightToLeftLayoutChanged {
202                         add { Events.AddHandler (RightToLeftLayoutChangedEvent, value); }
203                         remove { Events.RemoveHandler (RightToLeftLayoutChangedEvent, value); }
204                 }
205 #endif
206                 
207                 [Browsable (false)]
208                 [EditorBrowsable (EditorBrowsableState.Never)]
209                 public new event EventHandler TabStopChanged {
210                         add { base.TabStopChanged += value; }
211                         remove { base.TabStopChanged -= value; }
212                 }
213                 
214                 [Browsable (false)]
215                 [EditorBrowsable (EditorBrowsableState.Never)]
216                 public new event EventHandler TextChanged {
217                         add { base.TextChanged += value; }
218                         remove { base.TextChanged -= value; }
219                 }
220                 #endregion Events
221
222                 #region Public Constructors
223                 public ProgressBar()
224                 {
225                         maximum = 100;
226                         minimum = 0;
227                         step = 10;
228                         val = 0;
229
230                         base.Resize += new EventHandler (OnResizeTB);
231
232                         SetStyle (ControlStyles.UserPaint | 
233                                 ControlStyles.Selectable | 
234                                 ControlStyles.ResizeRedraw | 
235                                 ControlStyles.Opaque
236 #if NET_2_0
237                                 | ControlStyles.UseTextForAccessibility
238 #endif
239                                 , false);
240
241                         force_double_buffer = true;
242                         
243 #if NET_2_0
244                         ForeColor = defaultForeColor;
245 #endif
246                 }
247                 #endregion      // Public Constructors
248
249                 #region Public Instance Properties
250
251                 [Browsable (false)]
252                 [EditorBrowsable (EditorBrowsableState.Never)]
253                 public override bool AllowDrop
254                 {
255                         get { return base.AllowDrop; }
256                         set {
257                                 base.AllowDrop = value;
258                         }
259                 }
260
261 #if ONLY_1_1
262                 // Setting this property in MS .Net 1.1 does not have any visual effect and it
263                 // does not fire a BackColorChanged event
264                 [Browsable (false)]
265                 [EditorBrowsable (EditorBrowsableState.Never)]
266                 public override Color BackColor
267                 {
268                         get { return base.BackColor; }
269                         set { base.BackColor = value; }
270                 }
271 #endif
272
273                 // Setting this property in MS .Net 1.1 does not have any visual effect and it
274                 // does not fire a BackgroundImageChanged event
275                 [Browsable (false)]
276                 [EditorBrowsable (EditorBrowsableState.Never)]
277                 public override Image BackgroundImage
278                 {
279                         get { return base.BackgroundImage; }
280                         set { base.BackgroundImage = value; }
281                 }
282
283 #if NET_2_0
284                 [Browsable(false)]
285                 [EditorBrowsable(EditorBrowsableState.Never)]
286                 public override ImageLayout BackgroundImageLayout {
287                                 get     { return base.BackgroundImageLayout; }
288                                 set { base.BackgroundImageLayout = value; }
289                 }
290 #endif
291                 [Browsable (false)]
292                 [EditorBrowsable (EditorBrowsableState.Never)]
293                 public new bool CausesValidation
294                 {
295                         get { return base.CausesValidation; }
296                         set { base.CausesValidation = value; }
297                 }
298
299                 protected override CreateParams CreateParams
300                 {
301                         get { return base.CreateParams; }
302                 }
303
304                 protected override ImeMode DefaultImeMode
305                 {
306                         get { return base.DefaultImeMode; }
307                 }
308
309                 protected override Size DefaultSize
310                 {
311                         get { return ThemeEngine.Current.ProgressBarDefaultSize; }
312                 }
313
314 #if NET_2_0
315                 [EditorBrowsable(EditorBrowsableState.Never)]
316                 protected override bool DoubleBuffered {
317                                 get { return base.DoubleBuffered; }
318                                 set { base.DoubleBuffered = value; }
319                 }
320 #endif
321                 // Setting this property in MS .Net 1.1 does not have any visual effect and it
322                 // does not fire a FontChanged event
323                 [Browsable (false)]
324                 [EditorBrowsable (EditorBrowsableState.Never)]
325                 public override Font Font
326                 {
327                         get { return base.Font; }
328                         set { base.Font = value; }
329                 }
330
331 #if ONLY_1_1
332                 // Setting this property in MS .Net 1.1 does not have any visual effect and it
333                 // does not fire a FontChanged event
334                 [Browsable (false)]
335                 [EditorBrowsable (EditorBrowsableState.Never)]
336                 public override Color ForeColor
337                 {
338                         get { return base.ForeColor; }
339                         set { base.ForeColor = value; }
340                 }
341 #endif
342
343                 [Browsable (false)]
344                 [EditorBrowsable (EditorBrowsableState.Never)]
345                 public new ImeMode ImeMode
346                 {
347                         get { return base.ImeMode; }
348                         set { base.ImeMode = value; }
349                 }
350
351                 [RefreshProperties(RefreshProperties.Repaint)]
352                 [DefaultValue (100)]
353                 public int Maximum
354                 {
355                         get {
356                                 return maximum;
357                         }
358                         set {
359                                 if (value < 0)
360 #if NET_2_0
361                                         throw new ArgumentOutOfRangeException ("Maximum", 
362 #else
363                                         throw new ArgumentException(
364 #endif
365                                                 string.Format("Value '{0}' must be greater than or equal to 0.", value ));
366
367                                 maximum = value;
368                                 minimum = Math.Min (minimum, maximum);
369                                 val = Math.Min (val, maximum);
370                                 Refresh ();
371                         }
372                 }
373
374                 [RefreshProperties(RefreshProperties.Repaint)]
375                 [DefaultValue (0)]
376                 public int Minimum {
377                         get {
378                                 return minimum;
379                         }
380                         set {
381                                 if (value < 0)
382 #if NET_2_0
383                                         throw new ArgumentOutOfRangeException ("Minimum", 
384 #else
385                                         throw new ArgumentException(
386 #endif
387                                                 string.Format("Value '{0}' must be greater than or equal to 0.", value ));
388
389                                 minimum = value;
390                                 maximum = Math.Max (maximum, minimum);
391                                 val = Math.Max (val, minimum);
392                                 Refresh ();
393                         }
394                 }
395
396 #if NET_2_0
397                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
398                 [Browsable(false)]
399                 [EditorBrowsable(EditorBrowsableState.Never)]
400                 public new Padding Padding {
401                         get { return base.Padding; }
402                         set { base.Padding = value; }
403                 }
404                         
405                 [Localizable(true)]
406                 [DefaultValue(false)]
407                 [MonoTODO ("Layout is currently always from left to right")]
408                 public virtual bool RightToLeftLayout {
409                                 get { return right_to_left_layout;}
410                                 set     { 
411                                         if (right_to_left_layout != value) {
412                                                 right_to_left_layout = value;
413                                                 OnRightToLeftLayoutChanged (EventArgs.Empty);
414                                         }
415                                 }               
416                 }
417 #endif
418                         
419 #if ONLY_1_1
420                 [Browsable (false)]
421                 [EditorBrowsable (EditorBrowsableState.Never)]
422                 public override RightToLeft RightToLeft
423                 {
424                         get { return base.RightToLeft; }
425                         set { base.RightToLeft = value; }
426                 }
427 #endif
428
429                 [DefaultValue (10)]
430                 public int Step
431                 {
432                         get { return step; }
433                         set {
434                                 step = value;
435                                 Refresh ();
436                         }
437                 }
438
439 #if NET_2_0
440                 [Browsable (true)]
441                 [DefaultValue (ProgressBarStyle.Blocks)]
442                 [EditorBrowsable (EditorBrowsableState.Always)]
443                 public ProgressBarStyle Style {
444                         get {
445                                 return style;
446                         }
447
448                         set {
449                                 if (value != ProgressBarStyle.Blocks && value != ProgressBarStyle.Continuous
450                                                 && value != ProgressBarStyle.Marquee)
451                                         throw new InvalidEnumArgumentException ("value", unchecked((int)value), typeof (ProgressBarStyle));
452                                 if (style != value) {
453                                         style = value;
454
455                                         if (style == ProgressBarStyle.Marquee) {
456                                                 if (marquee_timer == null) {
457                                                         marquee_timer = new Timer ();
458                                                         marquee_timer.Interval = 10;
459                                                         marquee_timer.Tick += new EventHandler (marquee_timer_Tick);
460                                                 }
461                                                 marquee_timer.Start ();
462                                         } else {
463                                                 if (marquee_timer != null) {
464                                                         marquee_timer.Stop ();
465                                                 }
466                                                 Refresh ();
467                                         }
468                                 }
469                         }
470                 }
471
472                 void marquee_timer_Tick (object sender, EventArgs e)
473                 {
474                         Invalidate ();
475                 }
476                 
477                 int marquee_animation_speed = 100;
478                 [DefaultValue (100)]
479                 public int MarqueeAnimationSpeed {
480                         get {
481                                 return marquee_animation_speed;
482                         }
483
484                         set {
485                                 marquee_animation_speed = value;
486                         }
487                 }
488 #endif
489
490                 [Browsable (false)]
491                 [EditorBrowsable (EditorBrowsableState.Never)]
492                 public new bool TabStop
493                 {
494                         get { return base.TabStop; }
495                         set { base.TabStop = value; }
496                 }
497
498                 [Browsable (false)]
499                 [EditorBrowsable (EditorBrowsableState.Never)]
500                 [Bindable(false)]
501                 public override string Text
502                 {
503                         get { return base.Text; }
504                         set { base.Text = value; }
505                 }
506
507                 [Bindable(true)]
508                 [DefaultValue (0)]
509                 public int Value
510                 {
511                         get {
512                                 return val;
513                         }
514                         set {
515                                 if (value < Minimum || value > Maximum)
516 #if NET_2_0
517                                         throw new ArgumentOutOfRangeException ("Value", string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
518 #else
519                                         throw new ArgumentException(string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
520 #endif
521                                 val = value;
522                                 Refresh ();
523                         }
524                 }
525
526
527                 #endregion      // Protected Instance Properties
528
529                 #region Public Instance Methods
530                 
531                 protected override void CreateHandle ()
532                 {
533                         base.CreateHandle ();
534                 }
535
536                 public void Increment (int value)
537                 {
538 #if NET_2_0
539                         if (Style == ProgressBarStyle.Marquee)
540                                 throw new InvalidOperationException ("Increment should not be called if the style is Marquee.");
541 #endif
542                         int newValue = Value + value;
543
544                         if (newValue < Minimum)
545                                 newValue = Minimum;
546
547                         if (newValue > Maximum)
548                                 newValue = Maximum;
549
550                         Value = newValue;
551                         Refresh ();
552                 }
553
554                 protected override void OnHandleCreated (EventArgs e)
555                 {
556                         base.OnHandleCreated (e);
557
558                         UpdateAreas ();
559                 }
560
561 #if NET_2_0
562                 protected override void OnBackColorChanged (EventArgs e)
563                 {
564                         base.OnBackColorChanged (e);
565                 }
566                         
567                 protected override void OnForeColorChanged (EventArgs e)
568                 {
569                         base.OnForeColorChanged (e);
570                 }
571                         
572                 protected override void OnHandleDestroyed (EventArgs e)
573                 {
574                         base.OnHandleDestroyed (e);
575                 }
576                         
577                 [EditorBrowsable(EditorBrowsableState.Advanced)]
578                 protected virtual void OnRightToLeftLayoutChanged(EventArgs e)
579                 {
580                                 EventHandler eh = (EventHandler) Events [RightToLeftLayoutChangedEvent];
581                                 if (eh != null)
582                                         eh (this, e);
583                 }
584 #endif
585                         
586                 public void PerformStep ()
587                 {
588 #if NET_2_0
589                         if (Style == ProgressBarStyle.Marquee)
590                                 throw new InvalidOperationException ("PerformStep should not be called if the style is Marquee.");
591 #endif
592                         Increment (Step);
593                 }
594
595 #if NET_2_0
596                 [EditorBrowsable (EditorBrowsableState.Never)]
597                 public override void ResetForeColor ()
598                 {
599                         ForeColor = defaultForeColor;
600                 }
601 #endif
602
603                 public override string ToString()
604                 {
605                         return string.Format ("{0}, Minimum: {1}, Maximum: {2}, Value: {3}",
606                                 GetType().FullName,
607                                 Minimum.ToString (),
608                                 Maximum.ToString (),
609                                 Value.ToString () );
610                 }
611
612                 #endregion      // Public Instance Methods
613
614                 #region Private Instance Methods
615
616                 private void UpdateAreas ()
617                 {
618                         client_area.X = client_area.Y = 2;
619                         client_area.Width = Width - 4;
620                         client_area.Height = Height - 4;
621                 }
622
623                 private void OnResizeTB (Object o, EventArgs e)
624                 {
625                         if (Width <= 0 || Height <= 0)
626                                 return;
627
628                         UpdateAreas ();
629                         Invalidate();   // Invalidate the full surface, blocks will not match
630                 }
631
632                 internal override void OnPaintInternal (PaintEventArgs pevent)
633                 {
634                         ThemeEngine.Current.DrawProgressBar (pevent.Graphics, pevent.ClipRectangle, this);
635                 }
636
637                 #endregion
638         }
639 }