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-2005, Novell, Inc.
26 // Jordi Mas i Hernandez jordi@ximian.com
33 using System.Drawing.Imaging;
34 using System.Drawing.Drawing2D;
35 using System.ComponentModel;
36 using System.Runtime.InteropServices;
38 namespace System.Windows.Forms
40 [DefaultEvent ("Scroll")]
41 [DefaultProperty ("Value")]
42 public abstract class ScrollBar : Control
44 #region Local Variables
48 private int large_change;
49 private int small_change;
50 internal int scrollbutton_height;
51 internal int scrollbutton_width;
52 private ScrollBars type;
53 private Rectangle first_arrow_area = new Rectangle (); // up or left
54 private Rectangle second_arrow_area = new Rectangle (); // down or right
55 private Rectangle thumb_pos = new Rectangle ();
56 private Rectangle thumb_area = new Rectangle ();
57 internal ButtonState firstbutton_state = ButtonState.Normal;
58 internal ButtonState secondbutton_state = ButtonState.Normal;
59 private bool firstbutton_pressed = false;
60 private bool secondbutton_pressed = false;
61 private bool thumb_pressed = false;
62 private float pixel_per_pos = 0;
63 private Timer timer = new Timer ();
64 private TimerType timer_type;
65 private int thumb_pixel_click_move;
66 private int thumb_pixel_click_move_prev;
67 private int thumb_size = 40;
68 private const int thumb_min_size = 8;
69 private const int thumb_notshown_size = 40;
71 private int lastclick_pos; // Position of the last button-down event
72 private int lastclick_pos_thumb; // Position of the last button-down event relative to the thumb
73 private bool outside_thumbarea_right = false;
74 private bool outside_thumbarea_left = false;
76 private Rectangle dirty;
78 internal ThumbMoving thumb_moving = ThumbMoving.None;
79 #endregion // Local Variables
81 private enum TimerType
89 internal enum ThumbMoving
99 [EditorBrowsable (EditorBrowsableState.Never)]
100 public new event EventHandler BackColorChanged;
103 [EditorBrowsable (EditorBrowsableState.Never)]
104 public new event EventHandler BackgroundImageChanged;
107 [EditorBrowsable (EditorBrowsableState.Never)]
108 public new event EventHandler Click;
111 [EditorBrowsable (EditorBrowsableState.Never)]
112 public new event EventHandler DoubleClick;
115 [EditorBrowsable (EditorBrowsableState.Never)]
116 public new event EventHandler FontChanged;
119 [EditorBrowsable (EditorBrowsableState.Never)]
120 public new event EventHandler ForeColorChanged;
123 [EditorBrowsable (EditorBrowsableState.Never)]
124 public new event EventHandler ImeModeChanged;
127 [EditorBrowsable (EditorBrowsableState.Never)]
128 public new event MouseEventHandler MouseDown;
131 [EditorBrowsable (EditorBrowsableState.Never)]
132 public new event MouseEventHandler MouseMove;
135 [EditorBrowsable (EditorBrowsableState.Never)]
136 public new event MouseEventHandler MouseUp;
139 [EditorBrowsable (EditorBrowsableState.Never)]
140 public new event PaintEventHandler Paint;
142 public event ScrollEventHandler Scroll;
145 [EditorBrowsable (EditorBrowsableState.Never)]
146 public new event EventHandler TextChanged;
148 public event EventHandler ValueChanged;
159 timer.Tick += new EventHandler (OnTimer);
160 base.KeyDown += new KeyEventHandler (OnKeyDownSB);
161 base.MouseDown += new MouseEventHandler (OnMouseDownSB);
162 base.MouseUp += new MouseEventHandler (OnMouseUpSB);
163 base.MouseMove += new MouseEventHandler (OnMouseMoveSB);
164 base.Resize += new EventHandler (OnResizeSB);
165 base.TabStop = false;
167 if (ThemeEngine.Current.DoubleBufferingSupported == true) {
168 double_buffering = true;
170 double_buffering = false;
173 SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
174 SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
177 #region Internal & Private Properties
178 internal Rectangle FirstArrowArea {
180 return this.first_arrow_area;
184 this.first_arrow_area = value;
188 internal Rectangle SecondArrowArea {
190 return this.second_arrow_area;
194 this.second_arrow_area = value;
198 internal Rectangle ThumbPos {
207 #endregion // Internal & Private Properties
209 #region Public Properties
211 [EditorBrowsable (EditorBrowsableState.Never)]
213 public override Color BackColor
215 get { return base.BackColor; }
217 if (base.BackColor == value)
220 if (BackColorChanged != null)
221 BackColorChanged (this, EventArgs.Empty);
223 base.BackColor = value;
228 [EditorBrowsable (EditorBrowsableState.Never)]
230 public override Image BackgroundImage
232 get { return base.BackgroundImage; }
234 if (base.BackgroundImage == value)
237 if (BackgroundImageChanged != null)
238 BackgroundImageChanged (this, EventArgs.Empty);
240 base.BackgroundImage = value;
244 protected override CreateParams CreateParams
246 get { return base.CreateParams; }
249 protected override ImeMode DefaultImeMode
251 get { return ImeMode.Disable; }
254 [EditorBrowsable (EditorBrowsableState.Never)]
256 public override Font Font
258 get { return base.Font; }
260 if (base.Font.Equals (value))
263 if (FontChanged != null)
264 FontChanged (this, EventArgs.Empty);
270 [EditorBrowsable (EditorBrowsableState.Never)]
272 public override Color ForeColor
274 get { return base.ForeColor; }
276 if (base.ForeColor == value)
279 if (ForeColorChanged != null)
280 ForeColorChanged (this, EventArgs.Empty);
282 base.ForeColor = value;
287 [EditorBrowsable (EditorBrowsableState.Never)]
289 public new ImeMode ImeMode
291 get { return base.ImeMode; }
293 if (base.ImeMode == value)
296 if (ImeModeChanged != null)
297 ImeModeChanged (this, EventArgs.Empty);
299 base.ImeMode = value;
304 [RefreshProperties(RefreshProperties.Repaint)]
305 public int LargeChange {
307 if (large_change > maximum)
308 return (maximum + 1);
314 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
316 if (large_change != value) {
317 large_change = value;
319 // thumb area depends on large change value,
320 // so we need to recalculate it.
322 UpdatePos (Value, true);
329 [RefreshProperties(RefreshProperties.Repaint)]
331 get { return maximum; }
333 if (maximum == value)
338 if (maximum < minimum)
341 // thumb area depends on maximum value,
342 // so we need to recalculate it.
344 UpdatePos (Value, true);
350 [RefreshProperties(RefreshProperties.Repaint)]
352 get { return minimum; }
354 if (minimum == value)
359 if (minimum > maximum)
362 // thumb area depends on minimum value,
363 // so we need to recalculate it.
365 UpdatePos (Value, true);
371 public int SmallChange {
372 get { return small_change; }
375 throw new Exception( string.Format("Value '{0}' must be greater than or equal to 0.", value));
377 if (small_change != value) {
378 small_change = value;
379 UpdatePos (Value, true);
385 [DefaultValue (false)]
386 public new bool TabStop {
387 get { return base.TabStop; }
388 set { base.TabStop = value; }
391 [EditorBrowsable (EditorBrowsableState.Never)]
394 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
395 public override string Text {
396 get { return base.Text; }
397 set { base.Text = value; }
403 get { return position; }
405 if ( value < minimum || value > maximum )
406 throw new ArgumentException(
407 string.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
409 if (position != value){
412 OnValueChanged (EventArgs.Empty);
415 UpdatePos (Value, true);
421 #endregion //Public Properties
423 #region Public Methods
425 protected override void OnEnabledChanged (EventArgs e)
427 base.OnEnabledChanged (e);
430 firstbutton_state = secondbutton_state = ButtonState.Normal;
432 firstbutton_state = secondbutton_state = ButtonState.Inactive;
437 protected override void OnHandleCreated (System.EventArgs e)
439 base.OnHandleCreated (e);
443 UpdatePos (Value, true);
446 protected virtual void OnScroll (ScrollEventArgs event_args)
451 Scroll (this, event_args);
454 protected virtual void OnValueChanged (EventArgs e)
456 if (ValueChanged != null)
457 ValueChanged (this, e);
460 public override string ToString()
462 return string.Format("{0}, Minimum: {1}, Maximum: {2}, Value: {3}",
463 GetType( ).FullName.ToString( ), minimum, maximum, position);
466 protected void UpdateScrollInfo ()
471 protected override void WndProc (ref Message m)
477 PaintEventArgs paint_event;
479 paint_event = XplatUI.PaintEventStart (Handle);
480 OnPaintSB (paint_event);
481 XplatUI.PaintEventEnd (Handle);
486 case Msg.WM_ERASEBKGND:
487 m.Result = (IntPtr) 1; /// Disable background painting to avoid flickering
494 base.WndProc (ref m);
497 #endregion //Public Methods
499 #region Private Methods
501 private void CalcButtonSizes ()
504 if (Height < ThemeEngine.Current.ScrollBarButtonSize * 2)
505 scrollbutton_height = Height /2;
507 scrollbutton_height = ThemeEngine.Current.ScrollBarButtonSize;
510 if (Width < ThemeEngine.Current.ScrollBarButtonSize * 2)
511 scrollbutton_width = Width /2;
513 scrollbutton_width = ThemeEngine.Current.ScrollBarButtonSize;
517 private void CalcThumbArea ()
522 thumb_area.Height = Height - scrollbutton_height - scrollbutton_height;
524 thumb_area.Y = scrollbutton_height;
525 thumb_area.Width = Width;
527 if (Height < thumb_notshown_size)
530 double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
531 thumb_size = 1 + (int) (thumb_area.Height * per);
533 if (thumb_size < thumb_min_size)
534 thumb_size = thumb_min_size;
537 pixel_per_pos = ((float)(thumb_area.Height - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
542 thumb_area.X = scrollbutton_width;
543 thumb_area.Height = Height;
544 thumb_area.Width = Width - scrollbutton_width - scrollbutton_width;
546 if (Width < thumb_notshown_size)
549 double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
550 thumb_size = 1 + (int) (thumb_area.Width * per);
552 if (thumb_size < thumb_min_size)
553 thumb_size = thumb_min_size;
556 pixel_per_pos = ((float)(thumb_area.Width - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
560 private void Draw (Rectangle clip)
562 ThemeEngine.Current.DrawScrollBar(DeviceContext, clip, this);
565 private void LargeIncrement ()
567 ScrollEventArgs event_args;
568 int pos = position + large_change;
570 event_args = new ScrollEventArgs (ScrollEventType.LargeIncrement, pos);
571 OnScroll (event_args);
572 pos = event_args.NewValue;
574 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
575 OnScroll (event_args);
576 pos = event_args.NewValue;
578 UpdatePos (pos, true);
581 private void LargeDecrement ()
583 ScrollEventArgs event_args;
584 int pos = position - large_change;
586 event_args = new ScrollEventArgs (ScrollEventType.LargeDecrement, pos);
587 OnScroll (event_args);
588 pos = event_args.NewValue;
590 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
591 OnScroll (event_args);
592 pos = event_args.NewValue;
595 UpdatePos (pos, true);
598 private void OnResizeSB (Object o, EventArgs e)
600 if (Width <= 0 || Height <= 0)
605 UpdatePos (position, true);
608 private void OnPaintSB (PaintEventArgs pevent)
611 Paint (this, pevent);
614 if (Width <= 0 || Height <= 0 || Visible == false)
617 Draw (pevent.ClipRectangle);
618 pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
621 private void OnTimer (Object source, EventArgs e)
625 switch (timer_type) {
627 case TimerType.HoldButton:
628 SetRepeatButtonTimer ();
631 case TimerType.RepeatButton:
633 if ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
636 if ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
642 case TimerType.HoldThumbArea:
643 SetRepeatThumbAreaTimer ();
646 case TimerType.RepeatThumbArea:
648 Point pnt, pnt_screen;
649 Rectangle thumb_area_screen = thumb_area;
651 pnt_screen = PointToScreen (new Point (thumb_area.X, thumb_area.Y));
652 thumb_area_screen.X = pnt_screen.X;
653 thumb_area_screen.Y = pnt_screen.Y;
655 if (thumb_area_screen.Contains (MousePosition) == false) {
656 timer.Enabled = false;
657 thumb_moving = ThumbMoving.None;
662 pnt = PointToClient (MousePosition);
665 lastclick_pos = pnt.Y;
667 lastclick_pos = pnt.X;
669 if (thumb_moving == ThumbMoving.Forward) {
670 if ((vert && (thumb_pos.Y + thumb_size > lastclick_pos)) ||
671 (!vert && (thumb_pos.X + thumb_size > lastclick_pos)) ||
672 (thumb_area.Contains (pnt) == false)){
673 timer.Enabled = false;
674 thumb_moving = ThumbMoving.None;
682 if ((vert && (thumb_pos.Y < lastclick_pos)) ||
683 (!vert && (thumb_pos.X < lastclick_pos))){
684 timer.Enabled = false;
685 thumb_moving = ThumbMoving.None;
700 private void OnMouseMoveSB (object sender, MouseEventArgs e)
702 if (MouseMove != null) {
706 if (Enabled == false || thumb_size == 0)
709 if (firstbutton_pressed) {
710 if (!first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
711 firstbutton_state = ButtonState.Normal;
712 Invalidate (first_arrow_area);
714 } else if (first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
715 firstbutton_state = ButtonState.Pushed;
716 Invalidate (first_arrow_area);
719 } else if (secondbutton_pressed) {
720 if (!second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
721 secondbutton_state = ButtonState.Normal;
722 Invalidate (second_arrow_area);
724 } else if (second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
725 secondbutton_state = ButtonState.Pushed;
726 Invalidate (second_arrow_area);
729 } else if (thumb_pressed == true) {
734 int mouse_click = e.Y;
735 int outside_curpos = thumb_area.Y + thumb_area.Height - thumb_size + lastclick_pos_thumb;
738 if (mouse_click > thumb_area.Y + thumb_area.Height) {
739 outside_thumbarea_right = true;
740 mouse_click = thumb_area.Y + thumb_area.Height;
743 if (mouse_click < thumb_area.Y) {
744 outside_thumbarea_left = true;
745 mouse_click = thumb_area.Y;
748 if (outside_thumbarea_right && mouse_click < outside_curpos) {
749 outside_thumbarea_right = false;
750 thumb_pixel_click_move_prev =
751 thumb_pixel_click_move = outside_curpos;
754 if (outside_thumbarea_left && mouse_click > thumb_area.Y + lastclick_pos_thumb) {
755 outside_thumbarea_left = false;
756 thumb_pixel_click_move_prev =
757 thumb_pixel_click_move = thumb_area.Y + lastclick_pos_thumb;
760 if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
761 pixel_pos = thumb_pos.Y + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
762 thumb_pixel_click_move_prev = thumb_pixel_click_move;
763 thumb_pixel_click_move = mouse_click;
765 UpdateThumbPos (pixel_pos, true);
766 OnScroll (new ScrollEventArgs (ScrollEventType.ThumbTrack, position));
771 int mouse_click = e.X;
772 int outside_curpos = thumb_area.X + thumb_area.Width - thumb_size + lastclick_pos_thumb;
774 if (mouse_click > thumb_area.X + thumb_area.Width) {
775 outside_thumbarea_right = true;
776 mouse_click = thumb_area.X + thumb_area.Width;
779 if (mouse_click < thumb_area.X) {
780 outside_thumbarea_left = true;
781 mouse_click = thumb_area.X;
784 if (outside_thumbarea_right && mouse_click < outside_curpos) {
785 outside_thumbarea_right = false;
786 thumb_pixel_click_move_prev =
787 thumb_pixel_click_move = outside_curpos;
790 if (outside_thumbarea_left && mouse_click > thumb_area.X + lastclick_pos_thumb) {
791 outside_thumbarea_left = false;
792 thumb_pixel_click_move_prev =
793 thumb_pixel_click_move = thumb_area.X + lastclick_pos_thumb;
796 if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
797 pixel_pos = thumb_pos.X + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
798 thumb_pixel_click_move_prev = thumb_pixel_click_move;
799 thumb_pixel_click_move = mouse_click;
800 UpdateThumbPos (pixel_pos, true);
801 OnScroll (new ScrollEventArgs (ScrollEventType.ThumbTrack, position));
811 private void OnMouseDownSB (object sender, MouseEventArgs e)
815 if (e.Button == MouseButtons.Right) {
816 if (MouseDown != null) {
821 if (Enabled == false)
824 if (firstbutton_state != ButtonState.Inactive && first_arrow_area.Contains (e.X, e.Y)) {
826 firstbutton_state = ButtonState.Pushed;
827 firstbutton_pressed = true;
828 Invalidate (first_arrow_area);
829 if (!timer.Enabled) {
830 SetHoldButtonClickTimer ();
831 timer.Enabled = true;
835 if (secondbutton_state != ButtonState.Inactive && second_arrow_area.Contains (e.X, e.Y)) {
837 secondbutton_state = ButtonState.Pushed;
838 secondbutton_pressed = true;
839 Invalidate (second_arrow_area);
840 if (!timer.Enabled) {
841 SetHoldButtonClickTimer ();
842 timer.Enabled = true;
846 if (thumb_size > 0 && thumb_pos.Contains (e.X, e.Y)) {
847 thumb_pressed = true;
850 lastclick_pos_thumb = e.Y - thumb_pos.Y;
852 thumb_pixel_click_move_prev = thumb_pixel_click_move = e.Y;
855 lastclick_pos_thumb = e.X - thumb_pos.X;
857 thumb_pixel_click_move_prev = thumb_pixel_click_move = e.X;
860 if (thumb_size > 0 && thumb_area.Contains (e.X, e.Y)) {
863 lastclick_pos_thumb = e.Y - thumb_pos.Y;
866 if (e.Y > thumb_pos.Y + thumb_pos.Height) {
868 thumb_moving = ThumbMoving.Forward;
869 Dirty (new Rectangle (0, thumb_pos.Y + thumb_pos.Height,
870 ClientRectangle.Width,
871 ClientRectangle.Height - (thumb_pos.Y + thumb_pos.Height) -
872 scrollbutton_height));
875 thumb_moving = ThumbMoving.Backwards;
876 Dirty (new Rectangle (0, scrollbutton_height,
877 ClientRectangle.Width,
878 thumb_pos.Y - scrollbutton_height));
882 lastclick_pos_thumb = e.X - thumb_pos.X;
885 if (e.X > thumb_pos.X + thumb_pos.Width) {
886 thumb_moving = ThumbMoving.Forward;
888 Dirty (new Rectangle (thumb_pos.X + thumb_pos.Width, 0,
889 ClientRectangle.Width - (thumb_pos.X + thumb_pos.Width) -
891 ClientRectangle.Height));
893 thumb_moving = ThumbMoving.Backwards;
895 Dirty (new Rectangle (scrollbutton_width, 0,
896 thumb_pos.X - scrollbutton_width,
897 ClientRectangle.Height));
901 SetHoldThumbAreaTimer ();
902 timer.Enabled = true;
908 private void OnMouseUpSB (object sender, MouseEventArgs e)
912 if (e.Button == MouseButtons.Right) {
913 if (MouseUp != null) {
918 if (Enabled == false)
921 timer.Enabled = false;
922 if (thumb_moving != ThumbMoving.None) {
924 thumb_moving = ThumbMoving.None;
926 this.Capture = false;
928 if (firstbutton_pressed) {
929 firstbutton_state = ButtonState.Normal;
930 if (first_arrow_area.Contains (e.X, e.Y)) {
933 firstbutton_pressed = false;
934 Dirty (first_arrow_area);
935 } else if (secondbutton_pressed) {
936 secondbutton_state = ButtonState.Normal;
937 if (second_arrow_area.Contains (e.X, e.Y)) {
940 Dirty (second_arrow_area);
941 secondbutton_pressed = false;
942 } else if (thumb_pressed == true) {
943 OnScroll (new ScrollEventArgs (ScrollEventType.ThumbPosition, position));
944 OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
945 thumb_pressed = false;
953 private void OnKeyDownSB (Object o, KeyEventArgs key)
955 if (Enabled == false)
960 switch (key.KeyCode){
998 private void SetEndPosition ()
1000 ScrollEventArgs event_args;
1003 event_args = new ScrollEventArgs (ScrollEventType.Last, pos);
1004 OnScroll (event_args);
1005 pos = event_args.NewValue;
1007 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
1008 OnScroll (event_args);
1009 pos = event_args.NewValue;
1014 private void SetHomePosition ()
1016 ScrollEventArgs event_args;
1019 event_args = new ScrollEventArgs (ScrollEventType.First, pos);
1020 OnScroll (event_args);
1021 pos = event_args.NewValue;
1023 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
1024 OnScroll (event_args);
1025 pos = event_args.NewValue;
1030 private void SmallIncrement ()
1032 ScrollEventArgs event_args;
1033 int pos = position + small_change;
1035 event_args = new ScrollEventArgs (ScrollEventType.SmallIncrement, pos);
1036 OnScroll (event_args);
1037 pos = event_args.NewValue;
1039 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
1040 OnScroll (event_args);
1041 pos = event_args.NewValue;
1043 UpdatePos (pos, true);
1046 private void SmallDecrement ()
1048 ScrollEventArgs event_args;
1049 int pos = position - small_change;
1051 event_args = new ScrollEventArgs (ScrollEventType.SmallDecrement, pos);
1052 OnScroll (event_args);
1053 pos = event_args.NewValue;
1055 event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
1056 OnScroll (event_args);
1057 pos = event_args.NewValue;
1059 UpdatePos (pos, true);
1062 private void SetHoldButtonClickTimer ()
1064 timer.Enabled = false;
1065 timer.Interval = 200;
1066 timer_type = TimerType.HoldButton;
1067 timer.Enabled = true;
1070 private void SetRepeatButtonTimer ()
1072 timer.Enabled = false;
1073 timer.Interval = 50;
1074 timer_type = TimerType.RepeatButton;
1075 timer.Enabled = true;
1078 private void SetHoldThumbAreaTimer ()
1080 timer.Enabled = false;
1081 timer.Interval = 200;
1082 timer_type = TimerType.HoldThumbArea;
1083 timer.Enabled = true;
1086 private void SetRepeatThumbAreaTimer ()
1088 timer.Enabled = false;
1089 timer.Interval = 50;
1090 timer_type = TimerType.RepeatThumbArea;
1091 timer.Enabled = true;
1094 private void UpdatePos (int newPos, bool update_thumbpos)
1099 if (newPos < minimum)
1102 if (newPos > maximum + 1 - large_change)
1103 pos = maximum + 1 - large_change;
1107 // pos can't be less than minimum
1111 if (update_thumbpos) {
1113 UpdateThumbPos (thumb_area.Y + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
1115 UpdateThumbPos (thumb_area.X + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
1119 position = pos; // Updates directly the value to avoid thumb pos update
1121 if (ValueChanged != null)
1122 ValueChanged (this, EventArgs.Empty);
1126 private void UpdateThumbPos (int pixel, bool update_value)
1132 if (pixel < thumb_area.Y)
1133 thumb_pos.Y = thumb_area.Y;
1135 if (pixel > thumb_area.Y + thumb_area.Height - thumb_size)
1136 thumb_pos.Y = thumb_area.Y + thumb_area.Height - thumb_size;
1138 thumb_pos.Y = pixel;
1141 thumb_pos.Width = ThemeEngine.Current.ScrollBarButtonSize;
1142 thumb_pos.Height = thumb_size;
1143 new_pos = (float) (thumb_pos.Y - thumb_area.Y);
1144 new_pos = new_pos / pixel_per_pos;
1149 if (pixel < thumb_area.X)
1150 thumb_pos.X = thumb_area.X;
1152 if (pixel > thumb_area.X + thumb_area.Width - thumb_size)
1153 thumb_pos.X = thumb_area.X + thumb_area.Width - thumb_size;
1155 thumb_pos.X = pixel;
1158 thumb_pos.Width = thumb_size;
1159 thumb_pos.Height = ThemeEngine.Current.ScrollBarButtonSize;
1160 new_pos = (float) (thumb_pos.X - thumb_area.X);
1161 new_pos = new_pos / pixel_per_pos;
1167 UpdatePos ((int) new_pos + minimum, false);
1170 private void SetValue (int value)
1172 if ( value < minimum || value > maximum )
1173 throw new ArgumentException(
1174 String.Format("'{0}' is not a valid value for 'Value'. 'Value' should be between 'Minimum' and 'Maximum'", value));
1176 if (position != value){
1179 OnValueChanged (EventArgs.Empty);
1180 UpdatePos (value, true);
1184 private void ClearDirty ()
1186 dirty = Rectangle.Empty;
1189 private void Dirty (Rectangle r)
1191 if (dirty == Rectangle.Empty) {
1195 dirty = Rectangle.Union (dirty, r);
1198 private void DirtyThumbArea ()
1200 if (thumb_moving == ThumbMoving.Forward) {
1202 Dirty (new Rectangle (0, thumb_pos.Y + thumb_pos.Height,
1203 ClientRectangle.Width,
1204 ClientRectangle.Height - (thumb_pos.Y + thumb_pos.Height) -
1205 scrollbutton_height));
1207 Dirty (new Rectangle (thumb_pos.X + thumb_pos.Width, 0,
1208 ClientRectangle.Width - (thumb_pos.X + thumb_pos.Width) -
1210 ClientRectangle.Height));
1212 } else if (thumb_moving == ThumbMoving.Backwards) {
1214 Dirty(new Rectangle (0, scrollbutton_height,
1215 ClientRectangle.Width,
1216 thumb_pos.Y - scrollbutton_height));
1218 Dirty (new Rectangle (scrollbutton_width, 0,
1219 thumb_pos.X - scrollbutton_width,
1220 ClientRectangle.Height));
1225 private void InvalidateDirty ()
1228 dirty = Rectangle.Empty;
1231 #endregion //Private Methods