2 // System.Windows.Forms.ScrollBar.cs
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:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
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.
23 // Copyright (C) 2004, Novell, Inc.
26 // Jordi Mas i Hernandez jordi@ximian.com
31 // $Log: ScrollBar.cs,v $
32 // Revision 1.26 2004/11/08 14:15:00 jordi
33 // fixes vertical scrollbar and removes dead code
35 // Revision 1.25 2004/11/04 12:03:49 ravindra
36 // - We need to recalculate the Thumb area when LargeChange/maximum/minimum values are changed.
37 // - We set the 'pos' in UpdatePos() method to minimum, if it's less than minimum. This is required to handle the case if large_change is more than max, and use LargeChange property instead of large_change variable.
38 // - We return max+1 when large_change is more than max, like MS does.
40 // Revision 1.24 2004/10/17 22:11:49 jordi
41 // disabled scrollbar should not honor any keyboard or mouse event
43 // Revision 1.23 2004/10/05 04:56:11 jackson
44 // Let the base Control handle the buffers, derived classes should not have to CreateBuffers themselves.
46 // Revision 1.22 2004/09/28 18:44:25 pbartok
47 // - Streamlined Theme interfaces:
48 // * Each DrawXXX method for a control now is passed the object for the
49 // control to be drawn in order to allow accessing any state the theme
52 // * ControlPaint methods for the theme now have a CP prefix to avoid
53 // name clashes with the Draw methods for controls
55 // * Every control now retrieves it's DefaultSize from the current theme
57 // Revision 1.21 2004/09/17 16:43:27 pbartok
58 // - Fixed behaviour of arrow buttons. Now properly behaves like Buttons (and
59 // like Microsoft's scrollbar arrow buttons)
61 // Revision 1.20 2004/09/17 16:14:36 pbartok
62 // - Added missing release of keyboard/mouse capture
64 // Revision 1.19 2004/09/05 08:03:51 jordi
65 // fixes bugs, adds flashing on certain situations
67 // Revision 1.18 2004/08/31 10:35:04 jordi
68 // adds autorepeat timer, uses a single timer, fixes scrolling bugs, adds new methods
70 // Revision 1.17 2004/08/25 21:35:18 jordi
71 // more fixes to scrollbar
73 // Revision 1.16 2004/08/25 19:20:13 jordi
74 // small bug fix regarding bar position
76 // Revision 1.15 2004/08/24 18:37:02 jordi
77 // fixes formmating, methods signature, and adds missing events
79 // Revision 1.14 2004/08/23 22:53:15 jordi
82 // Revision 1.13 2004/08/23 22:43:46 jordi
83 // *** empty log message ***
85 // Revision 1.11 2004/08/22 19:34:22 jackson
86 // Update the position through the Value property so the OnValueChanged event is raised.
88 // Revision 1.10 2004/08/21 20:22:21 pbartok
89 // - Replaced direct XplatUI calls with their Control counterpart
91 // Revision 1.9 2004/08/20 19:35:33 jackson
92 // Use the SWF timer so callbacks are run in the correct thread
94 // Revision 1.8 2004/08/20 19:34:26 jackson
95 // Use the SWF timer so callbacks are run in the correct thread
97 // Revision 1.7 2004/08/19 22:25:31 jordi
100 // Revision 1.6 2004/08/18 15:56:12 jordi
101 // fixes to scrollbar: steps and multiple timers
103 // Revision 1.5 2004/08/10 19:21:27 jordi
104 // scrollbar enhancements and standarize on win colors defaults
106 // Revision 1.4 2004/08/10 15:41:50 jackson
107 // Allow control to handle buffering
109 // Revision 1.3 2004/07/27 15:29:40 jordi
110 // fixes scrollbar events
112 // Revision 1.2 2004/07/26 17:42:03 jordi
118 using System
.Drawing
;
119 using System
.Drawing
.Imaging
;
120 using System
.Drawing
.Drawing2D
;
121 using System
.ComponentModel
;
122 using System
.Runtime
.InteropServices
;
124 namespace System
.Windows
.Forms
126 [DefaultEvent ("Scroll")]
127 [DefaultProperty ("Value")]
128 public class ScrollBar
: Control
130 #region Local Variables
131 private int position
;
134 private int large_change
;
135 private int small_change
;
136 internal int scrollbutton_height
;
137 internal int scrollbutton_width
;
138 private ScrollBars type
;
139 private Rectangle first_arrow_area
= new Rectangle (); // up or left
140 private Rectangle second_arrow_area
= new Rectangle (); // down or right
141 private Rectangle thumb_pos
= new Rectangle ();
142 private Rectangle thumb_area
= new Rectangle ();
143 internal ButtonState firstbutton_state
= ButtonState
.Normal
;
144 internal ButtonState secondbutton_state
= ButtonState
.Normal
;
145 private bool firstbutton_pressed
= false;
146 private bool secondbutton_pressed
= false;
147 private bool thumb_pressed
= false;
148 private float pixel_per_pos
= 0;
149 private Timer timer
= new Timer ();
150 private TimerType timer_type
;
151 private int thumb_pixel_click_move
;
152 private int thumb_pixel_click_move_prev
;
153 private int thumb_size
= 0;
154 private const int thumb_min_size
= 8;
156 private int lastclick_pos
; // Position of the last button-down event
157 private int lastclick_pos_thumb
; // Position of the last button-down event relative to the thumb
158 private bool outside_thumbarea_right
= false;
159 private bool outside_thumbarea_left
= false;
160 internal ThumbMoving thumb_moving
= ThumbMoving
.None
;
161 #endregion // Local Variables
163 private enum TimerType
171 internal enum ThumbMoving
179 public new event EventHandler BackColorChanged
;
180 public new event EventHandler BackgroundImageChanged
;
181 public new event EventHandler Click
;
182 public new event EventHandler DoubleClick
;
183 public new event EventHandler FontChanged
;
184 public new event EventHandler ForeColorChanged
;
185 public new event EventHandler ImeModeChanged
;
186 public new event MouseEventHandler MouseDown
;
187 public new event MouseEventHandler MouseMove
;
188 public new event MouseEventHandler MouseUp
;
189 public new event PaintEventHandler Paint
;
190 public event ScrollEventHandler Scroll
;
191 public new event EventHandler TextChanged
;
192 public event EventHandler ValueChanged
;
203 timer
.Tick
+= new EventHandler (OnTimer
);
204 base.KeyDown
+= new KeyEventHandler (OnKeyDownSB
);
205 base.MouseDown
+= new MouseEventHandler (OnMouseDownSB
);
206 base.MouseUp
+= new MouseEventHandler (OnMouseUpSB
);
207 base.MouseMove
+= new MouseEventHandler (OnMouseMoveSB
);
208 base.Resize
+= new EventHandler (OnResizeSB
);
209 base.TabStop
= false;
211 if (ThemeEngine
.Current
.DoubleBufferingSupported
== true) {
212 double_buffering
= true;
214 double_buffering
= false;
217 SetStyle (ControlStyles
.UserPaint
| ControlStyles
.AllPaintingInWmPaint
, true);
218 SetStyle (ControlStyles
.ResizeRedraw
| ControlStyles
.Opaque
, true);
221 #region Internal & Private Properties
222 internal Rectangle FirstArrowArea
{
224 return this.first_arrow_area
;
228 this.first_arrow_area
= value;
232 internal Rectangle SecondArrowArea
{
234 return this.second_arrow_area
;
238 this.second_arrow_area
= value;
242 internal Rectangle ThumbPos
{
251 #endregion // Internal & Private Properties
253 #region Public Properties
255 [EditorBrowsable (EditorBrowsableState
.Never
)]
256 public override Color BackColor
258 get { return base.BackColor; }
260 if (base.BackColor
== value)
263 if (BackColorChanged
!= null)
264 BackColorChanged (this, EventArgs
.Empty
);
266 base.BackColor
= value;
271 [EditorBrowsable (EditorBrowsableState
.Never
)]
272 public override Image BackgroundImage
274 get { return base.BackgroundImage; }
276 if (base.BackgroundImage
== value)
279 if (BackgroundImageChanged
!= null)
280 BackgroundImageChanged (this, EventArgs
.Empty
);
282 base.BackgroundImage
= value;
286 protected override CreateParams CreateParams
288 get { return base.CreateParams; }
291 protected override ImeMode DefaultImeMode
293 get { return ImeMode.Disable; }
296 public override Font Font
298 get { return base.Font; }
300 if (base.Font
== value)
303 if (FontChanged
!= null)
304 FontChanged (this, EventArgs
.Empty
);
310 [EditorBrowsable (EditorBrowsableState
.Never
)]
311 public override Color ForeColor
313 get { return base.ForeColor; }
315 if (base.ForeColor
== value)
318 if (ForeColorChanged
!= null)
319 ForeColorChanged (this, EventArgs
.Empty
);
321 base.ForeColor
= value;
326 [EditorBrowsable (EditorBrowsableState
.Never
)]
327 public new ImeMode ImeMode
329 get { return base.ImeMode; }
331 if (base.ImeMode
== value)
334 if (ImeModeChanged
!= null)
335 ImeModeChanged (this, EventArgs
.Empty
);
337 base.ImeMode
= value;
341 public int LargeChange
{
343 if (large_change
> maximum
)
344 return (maximum
+ 1);
350 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
352 if (large_change
!= value) {
353 large_change
= value;
355 // thumb area depends on large change value,
356 // so we need to recalculate it.
364 get { return maximum; }
368 if (maximum
< minimum
)
371 // thumb area depends on maximum value,
372 // so we need to recalculate it.
379 get { return minimum; }
383 if (minimum
> maximum
)
386 // thumb area depends on minimum value,
387 // so we need to recalculate it.
393 public int SmallChange
{
394 get { return small_change; }
397 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
399 if (small_change
!= value) {
400 small_change
= value;
406 public new bool TabStop
{
407 get { return base.TabStop; }
408 set { base.TabStop = value; }
411 [EditorBrowsable (EditorBrowsableState
.Never
)]
412 public override string Text
{
413 get { return base.Text; }
414 set { base.Text = value; }
418 get { return position; }
420 if ( value < minimum
|| value > maximum
)
421 throw new ArgumentException(
422 string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
424 if (position
!= value){
427 if (ValueChanged
!= null)
428 ValueChanged (this, EventArgs
.Empty
);
430 UpdatePos (Value
, true);
436 #endregion //Public Properties
438 #region Public Methods
440 protected override void OnEnabledChanged (EventArgs e
)
442 base.OnEnabledChanged (e
);
445 firstbutton_state
= secondbutton_state
= ButtonState
.Normal
;
447 firstbutton_state
= secondbutton_state
= ButtonState
.Inactive
;
452 protected override void OnHandleCreated (System
.EventArgs e
)
454 base.OnHandleCreated (e
);
456 scrollbutton_height
= ThemeEngine
.Current
.ScrollBarButtonSize
;
457 scrollbutton_width
= ThemeEngine
.Current
.ScrollBarButtonSize
;
460 UpdatePos (Value
, true);
463 protected virtual void OnScroll (ScrollEventArgs event_args
)
468 Scroll (this, event_args
);
471 protected virtual void OnValueChanged (EventArgs e
)
473 if (ValueChanged
!= null)
474 ValueChanged (this, e
);
477 public override string ToString()
479 return string.Format("{0}, Minimum: {1}, Maximum: {2}, Value: {3}",
480 GetType( ).FullName
.ToString( ), minimum
, maximum
, position
);
483 protected void UpdateScrollInfo ()
488 protected override void WndProc (ref Message m
)
494 PaintEventArgs paint_event
;
496 paint_event
= XplatUI
.PaintEventStart (Handle
);
497 OnPaintSB (paint_event
);
498 XplatUI
.PaintEventEnd (Handle
);
503 case Msg
.WM_ERASEBKGND
:
504 m
.Result
= (IntPtr
) 1; /// Disable background painting to avoid flickering
511 base.WndProc (ref m
);
514 #endregion //Public Methods
516 #region Private Methods
518 private void CalcThumbArea ()
523 thumb_area
.Height
= Height
- scrollbutton_height
- scrollbutton_height
;
525 thumb_area
.Y
= scrollbutton_height
;
526 thumb_area
.Width
= Width
;
528 if (Height
< scrollbutton_height
* 2)
531 double per
= ((double) this.LargeChange
/ (double)((1 + maximum
- minimum
)));
532 thumb_size
= 1 + (int) (thumb_area
.Height
* per
);
534 if (thumb_size
< thumb_min_size
)
535 thumb_size
= thumb_min_size
;
539 pixel_per_pos
= ((float)(thumb_area
.Height
- thumb_size
) / (float) ((maximum
- minimum
- this.LargeChange
) + 1));
544 thumb_area
.X
= scrollbutton_width
;
545 thumb_area
.Height
= Height
;
546 thumb_area
.Width
= Width
- scrollbutton_width
- scrollbutton_width
;
548 if (Width
< scrollbutton_width
* 2)
551 double per
= ((double) this.LargeChange
/ (double)((1 + maximum
- minimum
)));
552 thumb_size
= 1 + (int) (thumb_area
.Width
* per
);
554 if (thumb_size
< thumb_min_size
)
555 thumb_size
= thumb_min_size
;
557 pixel_per_pos
= ((float)(thumb_area
.Width
- thumb_size
) / (float) ((maximum
- minimum
- this.LargeChange
) + 1));
563 ThemeEngine
.Current
.DrawScrollBar(DeviceContext
, this.ClientRectangle
, this);
566 private void LargeIncrement ()
568 UpdatePos (position
+ large_change
, true);
571 OnScroll (new ScrollEventArgs (ScrollEventType
.LargeIncrement
, position
));
572 OnScroll (new ScrollEventArgs (ScrollEventType
.EndScroll
, position
));
575 private void LargeDecrement ()
577 UpdatePos (position
- large_change
, true);
580 OnScroll (new ScrollEventArgs (ScrollEventType
.LargeDecrement
, position
));
581 OnScroll (new ScrollEventArgs (ScrollEventType
.EndScroll
, position
));
584 private void OnResizeSB (Object o
, EventArgs e
)
586 if (Width
<= 0 || Height
<= 0)
590 UpdatePos (position
, true);
593 private void OnPaintSB (PaintEventArgs pevent
)
595 if (Width
<= 0 || Height
<= 0 || Visible
== false)
598 /* Copies memory drawing buffer to screen*/
601 if (double_buffering
)
602 pevent
.Graphics
.DrawImage (ImageBuffer
, 0, 0);
606 private void OnTimer (Object source
, EventArgs e
)
608 switch (timer_type
) {
610 case TimerType
.HoldButton
:
611 SetRepeatButtonTimer ();
614 case TimerType
.RepeatButton
:
616 if ((firstbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)
619 if ((secondbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)
625 case TimerType
.HoldThumbArea
:
626 SetRepeatThumbAreaTimer ();
629 case TimerType
.RepeatThumbArea
:
632 pnt
= PointToClient (MousePosition
);
635 lastclick_pos
= pnt
.Y
;
637 lastclick_pos
= pnt
.X
;
639 if (thumb_moving
== ThumbMoving
.Forward
) {
640 if ((vert
&& (thumb_pos
.Y
+ thumb_size
> lastclick_pos
)) ||
641 (!vert
&& (thumb_pos
.X
+ thumb_size
> lastclick_pos
)) ||
642 (thumb_area
.Contains (pnt
) == false)){
643 timer
.Enabled
= false;
644 thumb_moving
= ThumbMoving
.None
;
650 if ((vert
&& (thumb_pos
.Y
< lastclick_pos
)) ||
651 (!vert
&& (thumb_pos
.X
< lastclick_pos
))){
652 timer
.Enabled
= false;
653 thumb_moving
= ThumbMoving
.None
;
666 private void OnMouseMoveSB (object sender
, MouseEventArgs e
)
668 if (Enabled
== false)
671 if (firstbutton_pressed
) {
672 if (!first_arrow_area
.Contains (e
.X
, e
.Y
) && ((firstbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)) {
673 firstbutton_state
= ButtonState
.Normal
;
676 } else if (first_arrow_area
.Contains (e
.X
, e
.Y
) && ((firstbutton_state
& ButtonState
.Normal
) == ButtonState
.Normal
)) {
677 firstbutton_state
= ButtonState
.Pushed
;
681 } else if (secondbutton_pressed
) {
682 if (!second_arrow_area
.Contains (e
.X
, e
.Y
) && ((secondbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)) {
683 secondbutton_state
= ButtonState
.Normal
;
686 } else if (second_arrow_area
.Contains (e
.X
, e
.Y
) && ((secondbutton_state
& ButtonState
.Normal
) == ButtonState
.Normal
)) {
687 secondbutton_state
= ButtonState
.Pushed
;
691 } else if (thumb_pressed
== true) {
696 int mouse_click
= e
.Y
;
697 int outside_curpos
= thumb_area
.Y
+ thumb_area
.Height
- thumb_size
+ lastclick_pos_thumb
;
700 if (mouse_click
> thumb_area
.Y
+ thumb_area
.Height
) {
701 outside_thumbarea_right
= true;
702 mouse_click
= thumb_area
.Y
+ thumb_area
.Height
;
705 if (mouse_click
< thumb_area
.Y
) {
706 outside_thumbarea_left
= true;
707 mouse_click
= thumb_area
.Y
;
710 if (outside_thumbarea_right
&& mouse_click
< outside_curpos
) {
711 outside_thumbarea_right
= false;
712 thumb_pixel_click_move_prev
=
713 thumb_pixel_click_move
= outside_curpos
;
716 if (outside_thumbarea_left
&& mouse_click
> thumb_area
.Y
+ lastclick_pos_thumb
) {
717 outside_thumbarea_left
= false;
718 thumb_pixel_click_move_prev
=
719 thumb_pixel_click_move
= thumb_area
.Y
+ lastclick_pos_thumb
;
722 if (outside_thumbarea_right
== false && outside_thumbarea_left
== false) {
723 pixel_pos
= thumb_pos
.Y
+ (thumb_pixel_click_move
- thumb_pixel_click_move_prev
);
724 thumb_pixel_click_move_prev
= thumb_pixel_click_move
;
725 thumb_pixel_click_move
= mouse_click
;
726 UpdateThumbPos (pixel_pos
, true);
731 int mouse_click
= e
.X
;
732 int outside_curpos
= thumb_area
.X
+ thumb_area
.Width
- thumb_size
+ lastclick_pos_thumb
;
734 if (mouse_click
> thumb_area
.X
+ thumb_area
.Width
) {
735 outside_thumbarea_right
= true;
736 mouse_click
= thumb_area
.X
+ thumb_area
.Width
;
739 if (mouse_click
< thumb_area
.X
) {
740 outside_thumbarea_left
= true;
741 mouse_click
= thumb_area
.X
;
744 if (outside_thumbarea_right
&& mouse_click
< outside_curpos
) {
745 outside_thumbarea_right
= false;
746 thumb_pixel_click_move_prev
=
747 thumb_pixel_click_move
= outside_curpos
;
750 if (outside_thumbarea_left
&& mouse_click
> thumb_area
.X
+ lastclick_pos_thumb
) {
751 outside_thumbarea_left
= false;
752 thumb_pixel_click_move_prev
=
753 thumb_pixel_click_move
= thumb_area
.X
+ lastclick_pos_thumb
;
756 if (outside_thumbarea_right
== false && outside_thumbarea_left
== false) {
757 pixel_pos
= thumb_pos
.X
+ (thumb_pixel_click_move
- thumb_pixel_click_move_prev
);
758 thumb_pixel_click_move_prev
= thumb_pixel_click_move
;
759 thumb_pixel_click_move
= mouse_click
;
760 UpdateThumbPos (pixel_pos
, true);
770 private void OnMouseDownSB (object sender
, MouseEventArgs e
)
772 if (Enabled
== false)
775 if (firstbutton_state
!= ButtonState
.Inactive
&& first_arrow_area
.Contains (e
.X
, e
.Y
)) {
777 firstbutton_state
= ButtonState
.Pushed
;
778 firstbutton_pressed
= true;
782 if (secondbutton_state
!= ButtonState
.Inactive
&& second_arrow_area
.Contains (e
.X
, e
.Y
)) {
784 secondbutton_state
= ButtonState
.Pushed
;
785 secondbutton_pressed
= true;
789 if (thumb_pos
.Contains (e
.X
, e
.Y
)) {
790 thumb_pressed
= true;
794 lastclick_pos_thumb
= e
.Y
- thumb_pos
.Y
;
796 thumb_pixel_click_move_prev
= thumb_pixel_click_move
= e
.Y
;
799 lastclick_pos_thumb
= e
.X
- thumb_pos
.X
;
801 thumb_pixel_click_move_prev
= thumb_pixel_click_move
= e
.X
;
805 if (thumb_area
.Contains (e
.X
, e
.Y
)) {
808 lastclick_pos_thumb
= e
.Y
- thumb_pos
.Y
;
811 if (e
.Y
> thumb_pos
.Y
+ thumb_pos
.Height
) {
813 thumb_moving
= ThumbMoving
.Forward
;
817 thumb_moving
= ThumbMoving
.Backwards
;
822 lastclick_pos_thumb
= e
.X
- thumb_pos
.X
;
825 if (e
.X
> thumb_pos
.X
+ thumb_pos
.Width
) {
826 thumb_moving
= ThumbMoving
.Forward
;
830 thumb_moving
= ThumbMoving
.Backwards
;
835 SetHoldThumbAreaTimer ();
836 timer
.Enabled
= true;
843 /* If arrows are pressed, fire timer for auto-repeat */
844 if ((((firstbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)
845 || ((secondbutton_state
& ButtonState
.Pushed
) == ButtonState
.Pushed
)) &&
846 timer
.Enabled
== false) {
847 SetHoldButtonClickTimer ();
848 timer
.Enabled
= true;
852 private void OnMouseUpSB (object sender
, MouseEventArgs e
)
854 if (Enabled
== false)
857 timer
.Enabled
= false;
859 if (thumb_moving
!= ThumbMoving
.None
) {
860 thumb_moving
= ThumbMoving
.None
;
864 this.Capture
= false;
866 if (firstbutton_pressed
) {
867 firstbutton_state
= ButtonState
.Normal
;
868 if (first_arrow_area
.Contains (e
.X
, e
.Y
)) {
871 firstbutton_pressed
= false;
873 } else if (secondbutton_pressed
) {
874 secondbutton_state
= ButtonState
.Normal
;
875 if (second_arrow_area
.Contains (e
.X
, e
.Y
)) {
878 secondbutton_pressed
= false;
880 } else if (thumb_pressed
== true) {
881 OnScroll (new ScrollEventArgs (ScrollEventType
.ThumbPosition
, position
));
882 OnScroll (new ScrollEventArgs (ScrollEventType
.EndScroll
, position
));
883 thumb_pressed
= false;
888 private void OnKeyDownSB (Object o
, KeyEventArgs key
)
890 if (Enabled
== false)
893 switch (key
.KeyCode
){
920 private void SmallIncrement ()
922 UpdatePos (position
+ small_change
, true);
925 OnScroll (new ScrollEventArgs (ScrollEventType
.SmallIncrement
, position
));
926 OnScroll (new ScrollEventArgs (ScrollEventType
.EndScroll
, position
));
929 private void SmallDecrement ()
931 UpdatePos (position
- small_change
, true);
934 OnScroll (new ScrollEventArgs (ScrollEventType
.SmallDecrement
, position
));
935 OnScroll (new ScrollEventArgs (ScrollEventType
.EndScroll
, position
));
938 private void SetHoldButtonClickTimer ()
940 timer
.Enabled
= false;
941 timer
.Interval
= 200;
942 timer_type
= TimerType
.HoldButton
;
943 timer
.Enabled
= true;
946 private void SetRepeatButtonTimer ()
948 timer
.Enabled
= false;
950 timer_type
= TimerType
.RepeatButton
;
951 timer
.Enabled
= true;
954 private void SetHoldThumbAreaTimer ()
956 timer
.Enabled
= false;
957 timer
.Interval
= 200;
958 timer_type
= TimerType
.HoldThumbArea
;
959 timer
.Enabled
= true;
962 private void SetRepeatThumbAreaTimer ()
964 timer
.Enabled
= false;
966 timer_type
= TimerType
.RepeatThumbArea
;
967 timer
.Enabled
= true;
970 private void UpdatePos (int newPos
, bool update_thumbpos
)
975 if (newPos
< minimum
)
978 if (newPos
> maximum
+ 1 - large_change
)
979 pos
= maximum
+ 1 - large_change
;
983 // pos can't be less than minimum
987 if (update_thumbpos
) {
989 UpdateThumbPos (thumb_area
.Y
+ (int)(((float)(pos
- minimum
)) * pixel_per_pos
), false);
991 UpdateThumbPos (thumb_area
.X
+ (int)(((float)(pos
- minimum
)) * pixel_per_pos
), false);
996 position
= pos
; // Updates directly the value to avoid thumb pos update
998 if (ValueChanged
!= null)
999 ValueChanged (this, EventArgs
.Empty
);
1002 if (pos
!= old
) // Fire event
1003 OnScroll (new ScrollEventArgs (ScrollEventType
.ThumbTrack
, pos
));
1007 private void UpdateThumbPos (int pixel
, bool update_value
)
1012 if (pixel
< thumb_area
.Y
)
1013 thumb_pos
.Y
= thumb_area
.Y
;
1015 if (pixel
> thumb_area
.Y
+ thumb_area
.Height
- thumb_size
)
1016 thumb_pos
.Y
= thumb_area
.Y
+ thumb_area
.Height
- thumb_size
;
1018 thumb_pos
.Y
= pixel
;
1021 thumb_pos
.Width
= ThemeEngine
.Current
.ScrollBarButtonSize
;
1022 thumb_pos
.Height
= thumb_size
;
1023 new_pos
= (float) (thumb_pos
.Y
- thumb_area
.Y
);
1024 new_pos
= new_pos
/ pixel_per_pos
;
1028 if (pixel
< thumb_area
.X
)
1029 thumb_pos
.X
= thumb_area
.X
;
1031 if (pixel
> thumb_area
.X
+ thumb_area
.Width
- thumb_size
)
1032 thumb_pos
.X
= thumb_area
.X
+ thumb_area
.Width
- thumb_size
;
1034 thumb_pos
.X
= pixel
;
1037 thumb_pos
.Width
= thumb_size
;
1038 thumb_pos
.Height
= ThemeEngine
.Current
.ScrollBarButtonSize
;
1039 new_pos
= (float) (thumb_pos
.X
- thumb_area
.X
);
1040 new_pos
= new_pos
/ pixel_per_pos
;
1044 UpdatePos ((int) new_pos
+ minimum
, false);
1048 #endregion //Private Methods