[jit] Enable partial generic sharing when not using AOT as an experiment.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / TrackBar.cs
1 //
2 // System.Windows.Forms.TrackBar.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 //
24 // Copyright (c) 2004-2006 Novell, Inc.
25 //
26 // Authors:
27 //      Jordi Mas i Hernandez, jordi@ximian.com
28 //      Rolf Bjarne Kvinge, RKvinge@novell.com
29 // 
30 // TODO:
31 //              - The AutoSize functionality seems quite broken for vertical controls in .Net 1.1. Not
32 //              sure if we are implementing it the right way.
33 //
34
35 // NOT COMPLETE
36
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
39 using System.Drawing;
40 using System.Drawing.Imaging;
41 using System.Drawing.Drawing2D;
42 using System.Timers;
43 using System.Runtime.InteropServices;
44
45 namespace System.Windows.Forms
46 {
47         [DefaultBindingProperty ("Value")]
48         [ComVisible (true)]
49         [ClassInterface (ClassInterfaceType.AutoDispatch)]
50         [Designer("System.Windows.Forms.Design.TrackBarDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
51         [DefaultEvent ("Scroll")]
52         [DefaultProperty("Value")]
53         public class TrackBar : Control, ISupportInitialize
54         {
55                 private int minimum;
56                 private int maximum;
57                 internal int tickFrequency;
58                 private bool autosize;
59                 private int position;
60                 private int smallChange;
61                 private int largeChange;
62                 private Orientation orientation;
63                 private TickStyle tickStyle;            
64                 private Rectangle thumb_pos = new Rectangle ();  /* Current position and size of the thumb */
65                 private Rectangle thumb_area = new Rectangle (); /* Area where the thumb can scroll */
66                 internal bool thumb_pressed = false;             
67                 private System.Timers.Timer holdclick_timer = new System.Timers.Timer ();
68                 internal int thumb_mouseclick;          
69                 private bool mouse_clickmove;
70                 private bool is_moving_right; // which way the thumb should move when mouse is down (right=up, left=down) 
71                 internal int mouse_down_x_offset; // how far from left side of thumb was the mouse clicked.
72                 internal bool mouse_moved; // has the mouse moved since it was clicked?
73                 private const int size_of_autosize = 45;
74                 private bool right_to_left_layout;
75                 bool thumb_entered;
76         
77                 #region events
78                 [EditorBrowsable (EditorBrowsableState.Always)]
79                 [Browsable (true)]
80                 public new event EventHandler AutoSizeChanged {
81                         add {base.AutoSizeChanged += value;}
82                         remove {base.AutoSizeChanged -= value;}
83                 }
84
85                 [Browsable (false)]
86                 [EditorBrowsable (EditorBrowsableState.Never)]
87                 public new event EventHandler BackgroundImageChanged {
88                         add { base.BackgroundImageChanged += value; }
89                         remove { base.BackgroundImageChanged -= value; }
90                 }
91                 
92                 [EditorBrowsable (EditorBrowsableState.Never)]
93                 [Browsable (false)]
94                 public new event EventHandler BackgroundImageLayoutChanged
95                 {
96                         add { base.BackgroundImageLayoutChanged += value; }
97                         remove { base.BackgroundImageLayoutChanged -= value; }
98                 }
99
100                 [Browsable (false)]
101                 [EditorBrowsable (EditorBrowsableState.Never)]
102                 public new event EventHandler Click {
103                         add { base.Click += value; }
104                         remove { base.Click -= value; }
105                 }
106                 
107                 [Browsable (false)]
108                 [EditorBrowsable (EditorBrowsableState.Never)]
109                 public new event EventHandler DoubleClick {
110                         add { base.DoubleClick += value; }
111                         remove { base.DoubleClick -= value; }
112                 }
113                 
114                 [Browsable (false)]
115                 [EditorBrowsable (EditorBrowsableState.Never)]
116                 public new event EventHandler FontChanged {
117                         add { base.FontChanged += value; }
118                         remove { base.FontChanged -= value; }
119                 }
120                 
121                 [Browsable (false)]
122                 [EditorBrowsable (EditorBrowsableState.Never)]
123                 public new event EventHandler ForeColorChanged {
124                         add { base.ForeColorChanged += value; }
125                         remove { base.ForeColorChanged -= value; }
126                 }
127                 
128                 [Browsable (false)]
129                 [EditorBrowsable (EditorBrowsableState.Never)]
130                 public new event EventHandler ImeModeChanged {
131                         add { base.ImeModeChanged += value; }
132                         remove { base.ImeModeChanged -= value; }
133                 }
134                 
135                 [Browsable (false)]
136                 [EditorBrowsable (EditorBrowsableState.Never)]
137                 public new event MouseEventHandler MouseClick {
138                         add {base.MouseClick += value;}
139                         remove {base.MouseClick -= value;}
140                 }
141                 
142                 [Browsable (false)]
143                 [EditorBrowsable (EditorBrowsableState.Never)]
144                 public new event MouseEventHandler MouseDoubleClick
145                 {
146                         add { base.MouseDoubleClick += value; }
147                         remove { base.MouseDoubleClick -= value; }
148                 }
149                 
150                 [Browsable (false)]
151                 [EditorBrowsable (EditorBrowsableState.Never)]
152                 public new event EventHandler PaddingChanged
153                 {
154                         add { base.PaddingChanged += value; }
155                         remove { base.PaddingChanged -= value; }
156                 }
157                 
158                 [Browsable (false)]
159                 [EditorBrowsable (EditorBrowsableState.Never)]
160                 public new event PaintEventHandler Paint {
161                         add { base.Paint += value; }
162                         remove { base.Paint -= value; }
163                 }
164
165                 public event EventHandler RightToLeftLayoutChanged {
166                         add {Events.AddHandler (RightToLeftLayoutChangedEvent, value);}
167                         remove {Events.RemoveHandler (RightToLeftLayoutChangedEvent, value);}
168                 }
169
170                 [Browsable (false)]
171                 [EditorBrowsable (EditorBrowsableState.Never)]
172                 public new event EventHandler TextChanged {
173                         add { base.TextChanged += value; }
174                         remove { base.TextChanged -= value; }
175                 }
176
177                 static object RightToLeftLayoutChangedEvent = new object ();
178                 static object ScrollEvent = new object ();
179                 static object ValueChangedEvent = new object ();
180
181                 public event EventHandler Scroll {
182                         add { Events.AddHandler (ScrollEvent, value); }
183                         remove { Events.RemoveHandler (ScrollEvent, value); }
184                 }
185
186                 public event EventHandler ValueChanged {
187                         add { Events.AddHandler (ValueChangedEvent, value); }
188                         remove { Events.RemoveHandler (ValueChangedEvent, value); }
189                 }
190                 
191                 #endregion // Events
192
193                 #region UIA FrameWork Events
194                 static object UIAValueParamChangedEvent = new object ();
195
196                 internal event EventHandler UIAValueParamChanged {
197                         add { Events.AddHandler (UIAValueParamChangedEvent, value); }
198                         remove { Events.RemoveHandler (UIAValueParamChangedEvent, value); }
199                 }
200
201                 internal void OnUIAValueParamChanged ()
202                 {
203                         EventHandler eh = (EventHandler) Events [UIAValueParamChangedEvent];
204                         if (eh != null)
205                                 eh (this, EventArgs.Empty);
206                 }
207                 #endregion
208
209                 public TrackBar ()
210                 {
211                         orientation = Orientation.Horizontal;
212                         minimum = 0;
213                         maximum = 10;
214                         tickFrequency = 1;
215                         autosize = true;
216                         position = 0;
217                         tickStyle = TickStyle.BottomRight;
218                         smallChange = 1;
219                         largeChange = 5;                        
220                         mouse_clickmove = false;                        
221                         MouseDown += new MouseEventHandler (OnMouseDownTB); 
222                         MouseUp += new MouseEventHandler (OnMouseUpTB); 
223                         MouseMove += new MouseEventHandler (OnMouseMoveTB);
224                         MouseLeave += new EventHandler (OnMouseLeave);
225                         KeyDown += new KeyEventHandler (OnKeyDownTB);
226                         LostFocus += new EventHandler (OnLostFocusTB);
227                         GotFocus += new EventHandler (OnGotFocusTB);
228                         holdclick_timer.Elapsed += new ElapsedEventHandler (OnFirstClickTimer);
229
230                         SetStyle (ControlStyles.UserPaint | ControlStyles.Opaque | ControlStyles.UseTextForAccessibility, false);
231                 }
232
233                 #region Private & Internal Properties
234                 internal Rectangle ThumbPos {
235                         get {
236                                 return thumb_pos;
237                         }
238
239                         set {
240                                 thumb_pos = value;
241                         }
242                 }
243
244                 internal Rectangle ThumbArea {
245                         get {
246                                 return thumb_area;
247                         }
248
249                         set {
250                                 thumb_area = value;
251                         }
252                 }
253
254                 internal bool ThumbEntered {
255                         get { return thumb_entered; }
256                         set {
257                                 if (thumb_entered == value)
258                                         return;
259                                 thumb_entered = value;
260                                 if (ThemeEngine.Current.TrackBarHasHotThumbStyle)
261                                         Invalidate (GetRealThumbRectangle ());
262                         }
263                 }
264                 #endregion      // Private & Internal Properties
265
266                 #region Public Properties
267
268                 [Browsable (true)]
269                 [EditorBrowsable (EditorBrowsableState.Always)]
270                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
271                 [DefaultValue (true)]
272                 public override bool AutoSize {
273                         get { return autosize; }
274                         set { autosize = value;}
275                 }
276
277                 [EditorBrowsable (EditorBrowsableState.Never)]
278                 [Browsable (false)]
279                 public override Image BackgroundImage {
280                         get { return base.BackgroundImage; }
281                         set { base.BackgroundImage = value; }
282                 }
283
284                 [EditorBrowsable (EditorBrowsableState.Never)]
285                 [Browsable (false)]
286                 public override ImageLayout BackgroundImageLayout {
287                         get {
288                                 return base.BackgroundImageLayout;
289                         }
290                         set {
291                                 base.BackgroundImageLayout = value;
292                         }
293                 }
294
295                 protected override CreateParams CreateParams {
296                         get {
297                                 return base.CreateParams;
298                         }
299                 }
300
301                 protected override ImeMode DefaultImeMode {
302                         get {return ImeMode.Disable; }
303                 }
304
305                 protected override Size DefaultSize {
306                         get { return ThemeEngine.Current.TrackBarDefaultSize; }
307                 }       
308                 
309                 [EditorBrowsable (EditorBrowsableState.Never)]
310                 protected override bool DoubleBuffered {
311                         get {
312                                 return base.DoubleBuffered;
313                         }
314                         set {
315                                 base.DoubleBuffered = value;
316                         }
317                 }
318
319                 [Browsable(false)]
320                 [EditorBrowsable (EditorBrowsableState.Never)]
321                 public override Font Font {
322                         get { return base.Font; }
323                         set { base.Font = value; }
324                 }
325
326                 [EditorBrowsable (EditorBrowsableState.Never)]  
327                 [Browsable (false)]
328                 public override Color ForeColor {
329                         get { return base.ForeColor; }
330                         set { base.ForeColor = value; }
331                 }               
332
333                 [EditorBrowsable (EditorBrowsableState.Never)]  
334                 [Browsable (false)]
335                 public new ImeMode ImeMode {
336                         get { return base.ImeMode; }
337                         set { base.ImeMode = value; }
338                 }
339                 
340                 [DefaultValue (5)]
341                 public int LargeChange 
342                 {
343                         get { return largeChange; }
344                         set {
345                                 if (value < 0)
346                                         throw new ArgumentOutOfRangeException (string.Format ("Value '{0}' must be greater than or equal to 0.", value));
347                                 
348                                 largeChange = value;                            
349
350                                 OnUIAValueParamChanged ();
351                         }
352                 }
353
354                 [DefaultValue (10)]
355                 [RefreshProperties (RefreshProperties.All)]             
356                 public int Maximum {
357                         get { return maximum; }
358                         set {
359                                 if (maximum != value)  {
360                                         maximum = value;
361
362                                         if (maximum < minimum)
363                                                 minimum = maximum;
364
365                                         Refresh ();
366
367                                         OnUIAValueParamChanged ();
368                                 }
369                         }
370                 }
371
372                 [DefaultValue (0)]
373                 [RefreshProperties (RefreshProperties.All)]             
374                 public int Minimum {
375                         get { return minimum; }
376                         set {
377
378                                 if (Minimum != value) {
379                                         minimum = value;
380
381                                         if (minimum > maximum)
382                                                 maximum = minimum;
383
384                                         Refresh ();
385
386                                         OnUIAValueParamChanged ();
387                                 }
388                         }
389                 }
390
391                 [DefaultValue (Orientation.Horizontal)]
392                 [Localizable (true)]
393                 public Orientation Orientation {
394                         get { return orientation; }
395                         set {
396                                 if (!Enum.IsDefined (typeof (Orientation), value))
397                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for Orientation", value));
398
399                                 /* Orientation can be changed once the control has been created */
400                                 if (orientation != value) {
401                                         orientation = value;
402                                         
403                                         if (this.IsHandleCreated) {
404                                                 Size = new Size (Height, Width);
405                                                 Refresh (); 
406                                         }
407                                 }
408                         }
409                 }
410
411                 [Browsable (false)]
412                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
413                 [EditorBrowsable (EditorBrowsableState.Never)]
414                 public new Padding Padding {
415                         get {
416                                 return base.Padding;
417                         }
418                         set {
419                                 base.Padding = value;
420                         }
421                 }
422                 
423                 [Localizable (true)]
424                 [DefaultValue (false)]
425                 public virtual bool RightToLeftLayout {
426                         get {
427                                 return right_to_left_layout;
428                         }
429                         set {
430                                 if (value != right_to_left_layout) {
431                                         right_to_left_layout = value;
432                                         OnRightToLeftLayoutChanged (EventArgs.Empty);
433                                 }
434                         }
435                 }
436
437                 [DefaultValue (1)]
438                 public int SmallChange {
439                         get { return smallChange;}
440                         set {
441                                 if (value < 0)
442                                         throw new ArgumentOutOfRangeException (string.Format ("Value '{0}' must be greater than or equal to 0.", value));
443
444                                 if (smallChange != value) {
445                                         smallChange = value;                                    
446
447                                         OnUIAValueParamChanged ();
448                                 }
449                         }
450                 }
451
452                 [EditorBrowsable (EditorBrowsableState.Never)]
453                 [Bindable (false)]
454                 [Browsable (false)]
455                 public override string Text {
456                         get {   return base.Text; }                     
457                         set { base.Text = value; }
458                 }
459
460                 [DefaultValue (1)]
461                 public int TickFrequency {
462                         get { return tickFrequency; }
463                         set {
464                                 if ( value > 0 ) {
465                                         tickFrequency = value;
466                                         Refresh ();
467                                 }
468                         }
469                 }
470
471                 [DefaultValue (TickStyle.BottomRight)]
472                 public TickStyle TickStyle {
473                         get { return tickStyle; }
474                         set {                           
475                                 if (!Enum.IsDefined (typeof (TickStyle), value))
476                                         throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for TickStyle", value));
477                                 
478                                 if (tickStyle != value) {
479                                         tickStyle = value;
480                                         Refresh ();
481                                 }
482                         }
483                 }
484                 
485                 [DefaultValue (0)]
486                 [Bindable (true)]
487                 public int Value {
488                         get { return position; }
489                         set {
490                                 SetValue (value, false);
491                         }
492                 }
493
494                 void SetValue (int value, bool fire_onscroll)
495                 {
496                         if (value < Minimum || value > Maximum)
497                                 throw new ArgumentException(
498                                                 String.Format ("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
499
500                         if (position == value)
501                                 return;
502
503                         position = value;
504
505                         // OnScroll goes before OnValueChanged
506                         if (fire_onscroll)
507                                 OnScroll (EventArgs.Empty);
508
509                         // XXX any reason we don't call OnValueChanged here?
510                         EventHandler eh = (EventHandler)(Events [ValueChangedEvent]);
511                         if (eh != null)
512                                 eh (this, EventArgs.Empty);
513
514                         Invalidate (thumb_area);
515                 }
516
517                 #endregion //Public Properties
518
519                 #region Public Methods
520
521                 public void BeginInit ()                
522                 {
523
524                 }
525
526                 protected override void CreateHandle ()
527                 {
528                         base.CreateHandle ();
529                 }
530
531                 protected override void SetBoundsCore (int x, int y,int width, int height, BoundsSpecified specified)
532                 {
533                         if (AutoSize) {
534                                 if (orientation == Orientation.Vertical) {
535                                         width = size_of_autosize;
536                                 } else {
537                                         height = size_of_autosize;
538                                 }
539                         }
540                         base.SetBoundsCore (x, y, width, height, specified);
541                 }
542
543                 public void EndInit ()          
544                 {
545
546                 }
547
548                 protected override bool IsInputKey (Keys keyData)
549                 {
550                         if ((keyData & Keys.Alt) == 0) {
551                                 switch (keyData & Keys.KeyCode) {
552                                 case Keys.Down:
553                                 case Keys.Right:
554                                 case Keys.Up:
555                                 case Keys.Left:
556                                 case Keys.PageUp:
557                                 case Keys.PageDown:
558                                 case Keys.Home:
559                                 case Keys.End:
560                                         return true;
561                                 }
562                         }
563                         return base.IsInputKey (keyData);
564                 }
565
566                 protected override void OnBackColorChanged (EventArgs e)
567                 {
568                         base.OnBackColorChanged (e);
569                 }
570
571                 protected override void OnHandleCreated (EventArgs e)
572                 {       
573                         base.OnHandleCreated (e);
574                                         
575                         if (AutoSize)
576                                 if (Orientation == Orientation.Horizontal)
577                                         Size = new Size (Width, 40);
578                                 else
579                                         Size = new Size (50, Height);
580                         
581                         UpdatePos (Value, true);                        
582                 }
583         
584                 [EditorBrowsable (EditorBrowsableState.Advanced)]
585                 protected override void OnMouseWheel (MouseEventArgs e)
586                 {
587                         base.OnMouseWheel (e);
588                         
589                         if (!Enabled) return;
590                         
591                         if (e.Delta > 0)
592                                 SmallDecrement ();
593                         else
594                                 SmallIncrement ();                                      
595                 }
596
597                 [EditorBrowsable (EditorBrowsableState.Advanced)]
598                 protected virtual void OnRightToLeftLayoutChanged (EventArgs e)
599                 {
600                         EventHandler eh = (EventHandler)Events [RightToLeftLayoutChangedEvent];
601                         if (eh != null)
602                                 eh (this, e);
603                 }
604
605                 protected virtual void OnScroll (EventArgs e) 
606                 {
607                         EventHandler eh = (EventHandler)(Events [ScrollEvent]);
608                         if (eh != null)
609                                 eh (this, e);
610                 }
611
612                 protected override void OnSystemColorsChanged (EventArgs e)
613                 {
614                         base.OnSystemColorsChanged (e);
615                         Invalidate ();
616                 }
617
618                 protected virtual void OnValueChanged (EventArgs e) 
619                 {
620                         EventHandler eh = (EventHandler)(Events [ValueChangedEvent]);
621                         if (eh != null)
622                                 eh (this, e);
623                 }
624
625                 public void SetRange (int minValue, int maxValue)
626                 {
627                         Minimum = minValue;
628                         Maximum = maxValue;                     
629                 }
630
631                 public override string ToString()
632                 {
633                         return string.Format("System.Windows.Forms.TrackBar, Minimum: {0}, Maximum: {1}, Value: {2}",
634                                                 Minimum, Maximum, Value);
635                 }
636                                                         
637
638                 protected override void WndProc (ref Message m)
639                 {
640                         base.WndProc (ref m);
641
642                         // Basically we want ControlStyles.ResizeRedraw but
643                         // tests say we can't set that flag
644                         if ((Msg)m.Msg == Msg.WM_WINDOWPOSCHANGED && Visible)
645                                 Invalidate ();
646                 }
647                 
648                 #endregion Public Methods
649
650                 #region Private Methods
651                 
652                 private void UpdatePos (int newPos, bool update_trumbpos)
653                 {
654                         if (newPos < minimum){
655                                 SetValue (minimum, true);
656                         }
657                         else {
658                                 if (newPos > maximum) {
659                                         SetValue (maximum, true);
660                                 }
661                                 else {
662                                         SetValue (newPos, true);
663                                 }
664                         }
665                 }
666                 
667                         // Used by UIA implementation, so making internal
668                 internal void LargeIncrement ()
669                 {                       
670                         UpdatePos (position + LargeChange, true);
671                         Invalidate (thumb_area);
672                 }
673
674                         // Used by UIA implementation, so making internal
675                 internal void LargeDecrement ()
676                 {
677                         UpdatePos (position - LargeChange, true);
678                         Invalidate (thumb_area);
679                 }
680
681                 private void SmallIncrement ()
682                 {                       
683                         UpdatePos (position + SmallChange, true);
684                         Invalidate (thumb_area);
685                 }
686
687                 private void SmallDecrement ()
688                 {
689                         UpdatePos (position - SmallChange, true);
690                         Invalidate (thumb_area);
691                 }
692                 
693                 private void OnMouseUpTB (object sender, MouseEventArgs e)
694                 {       
695                         if (!Enabled) return;                   
696
697                         if (thumb_pressed == true || mouse_clickmove == true) { 
698                                 thumb_pressed = false;
699                                 holdclick_timer.Enabled = false;
700                                 this.Capture = false;
701                                 Invalidate (thumb_area);
702                         }
703                 }
704
705                 private void OnMouseDownTB (object sender, MouseEventArgs e)
706                 {
707                         if (!Enabled) return;                                           
708
709                         mouse_moved = false;
710
711                         bool fire_timer = false;
712                         
713                         Point point = new Point (e.X, e.Y);
714
715                         if (orientation == Orientation.Horizontal) {
716                                 
717                                 if (thumb_pos.Contains (point)) {
718                                         this.Capture = true;
719                                         thumb_pressed = true;
720                                         thumb_mouseclick = e.X;
721                                         mouse_down_x_offset = e.X - thumb_pos.X;
722                                         Invalidate (thumb_area);
723                                 }
724                                 else {
725                                         if (thumb_area.Contains (point)) {
726                                                 is_moving_right = e.X > thumb_pos.X + thumb_pos.Width; 
727                                                 if (is_moving_right)
728                                                         LargeIncrement ();
729                                                 else
730                                                         LargeDecrement ();
731
732                                                 Invalidate (thumb_area);
733                                                 fire_timer = true;
734                                                 mouse_clickmove = true;
735                                         }
736                                 }
737                         }
738                         else {
739                                 Rectangle vertical_thumb_pos = thumb_pos;
740                                 vertical_thumb_pos.Width = thumb_pos.Height;
741                                 vertical_thumb_pos.Height = thumb_pos.Width;
742                                 if (vertical_thumb_pos.Contains (point)) {
743                                         this.Capture = true;
744                                         thumb_pressed = true;
745                                         thumb_mouseclick = e.Y;
746                                         mouse_down_x_offset = e.Y - thumb_pos.Y;
747                                         Invalidate (thumb_area);
748                                 }
749                                 else {
750                                         if (thumb_area.Contains (point)) {
751                                                 is_moving_right = e.Y > thumb_pos.Y + thumb_pos.Width;
752                                                 if (is_moving_right)
753                                                         LargeDecrement ();
754                                                 else
755                                                         LargeIncrement ();
756
757                                                 Invalidate (thumb_area);
758                                                 fire_timer = true;
759                                                 mouse_clickmove = true;
760                                         }
761                                 }
762                         }
763
764                         if (fire_timer) {                               
765                                 holdclick_timer.Interval = 300;
766                                 holdclick_timer.Enabled = true;                         
767                         }                       
768                 }
769
770                 private void OnMouseMoveTB (object sender, MouseEventArgs e)
771                 {                       
772                         if (!Enabled) return;
773                 
774                         mouse_moved = true;
775
776                         /* Moving the thumb */
777                         if (thumb_pressed)
778                                 SetValue (ThemeEngine.Current.TrackBarValueFromMousePosition (e.X, e.Y, this), true);
779
780                         ThumbEntered = GetRealThumbRectangle ().Contains (e.Location);
781                 }
782
783                 Rectangle GetRealThumbRectangle ()
784                 {
785                         Rectangle result = thumb_pos;
786                         if (Orientation == Orientation.Vertical) {
787                                 result.Width = thumb_pos.Height;
788                                 result.Height = thumb_pos.Width;
789                         }
790                         return result;
791                 }
792
793                 internal override void OnPaintInternal (PaintEventArgs pevent)
794                 {               
795                         ThemeEngine.Current.DrawTrackBar (pevent.Graphics, pevent.ClipRectangle, this);
796                 }
797
798                 private void OnLostFocusTB (object sender, EventArgs e)
799                 {
800                         Invalidate();
801                 }
802
803                 private void OnGotFocusTB (object sender, EventArgs e)
804                 {
805                         Invalidate();
806                 }
807                 private void OnKeyDownTB (object sender, KeyEventArgs e) 
808                 {
809                         bool horiz = Orientation == Orientation.Horizontal;
810                         switch (e.KeyCode) {
811                         
812                         case Keys.Down:
813                         case Keys.Right:
814                                 if(horiz)
815                                         SmallIncrement();
816                                 else
817                                         SmallDecrement ();
818                                 break;
819
820                         case Keys.Up:
821                         case Keys.Left:
822                                 if (horiz)
823                                         SmallDecrement();
824                                 else
825                                         SmallIncrement();
826                                 break;
827
828                         case Keys.PageUp:
829                                 if (horiz)
830                                         LargeDecrement();
831                                 else
832                                         LargeIncrement();
833                                 break;
834
835                         case Keys.PageDown:
836                                 if (horiz)
837                                         LargeIncrement();
838                                 else
839                                         LargeDecrement();
840                                 break;
841
842                         case Keys.Home:
843                                 if (horiz)
844                                         SetValue (Minimum, true);
845                                 else
846                                         SetValue (Maximum, true);
847                                 break;
848
849                         case Keys.End:
850                                 if (horiz)
851                                         SetValue (Maximum, true);
852                                 else
853                                         SetValue (Minimum, true);
854                                 break;
855
856                         default:
857                                 break;
858                         }
859                 }
860
861                 private void OnFirstClickTimer (Object source, ElapsedEventArgs e)
862                 {                                               
863                         Point pnt;
864                         pnt = PointToClient (MousePosition);                    
865                         /*
866                                 On Win32 the thumb only moves in one direction after a click, 
867                                 if the thumb passes the clicked point it will never go in the 
868                                 other way unless the mouse is released and clicked again. This
869                                 is also true if the mouse moves while beeing hold down.
870                         */
871                 
872                         if (thumb_area.Contains (pnt))  {
873                                 bool invalidate = false;
874                                 if (orientation == Orientation.Horizontal) {
875                                         if (pnt.X > thumb_pos.X + thumb_pos.Width && is_moving_right) {
876                                                 LargeIncrement ();
877                                                 invalidate = true;
878                                         } else if (pnt.X < thumb_pos.X && !is_moving_right) {
879                                                 LargeDecrement ();                      
880                                                 invalidate = true;
881                                         }                                       
882                                 } else {
883                                         if (pnt.Y > thumb_pos.Y + thumb_pos.Width && is_moving_right) {
884                                                 LargeDecrement ();              
885                                                 invalidate = true;
886                                         } else if (pnt.Y < thumb_pos.Y && !is_moving_right) {
887                                                 LargeIncrement ();              
888                                                 invalidate = true;
889                                         }
890                                 }
891                                 if (invalidate)
892                                         // A Refresh is necessary because the mouse is down and if we just invalidate
893                                         // we'll only get paint events once in a while.
894                                         Refresh();
895                         }                       
896                 }                                       
897
898                 void OnMouseLeave (object sender, EventArgs e)
899                 {
900                         ThumbEntered = false;
901                 }
902                 #endregion // Private Methods
903         }
904 }
905