private int large_change;
private int small_change;
internal int scrollbutton_height;
- internal int scrollbutton_width;
+ internal int scrollbutton_width;
private ScrollBars type;
private Rectangle first_arrow_area = new Rectangle (); // up or left
private Rectangle second_arrow_area = new Rectangle (); // down or right
private float pixel_per_pos = 0;
private Timer timer = new Timer ();
private TimerType timer_type;
- private int thumb_pixel_click_move;
- private int thumb_pixel_click_move_prev;
private int thumb_size = 40;
private const int thumb_min_size = 8;
private const int thumb_notshown_size = 40;
internal bool vert;
- private int lastclick_pos; // Position of the last button-down event
- private int lastclick_pos_thumb; // Position of the last button-down event relative to the thumb
- private bool outside_thumbarea_right = false;
- private bool outside_thumbarea_left = false;
-
+ internal bool implicit_control;
+ private int lastclick_pos; // Position of the last button-down event
+ private int lastclick_pos_thumb; // Position of the last button-down event relative to the thumb
+ private int thumbclick_offset; // Position of the last button-down event relative to the thumb edge
private Rectangle dirty;
internal ThumbMoving thumb_moving = ThumbMoving.None;
HoldThumbArea,
RepeatThumbArea
}
-
+
internal enum ThumbMoving
{
None,
}
#region events
-
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackColorChanged;
-
+ public new event EventHandler BackColorChanged {
+ add { base.BackColorChanged += value; }
+ remove { base.BackColorChanged -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler BackgroundImageChanged;
-
+ public new event EventHandler BackgroundImageChanged {
+ add { base.BackgroundImageChanged += value; }
+ remove { base.BackgroundImageChanged -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler Click;
-
+ public new event EventHandler Click {
+ add { base.Click += value; }
+ remove { base.Click -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler DoubleClick;
-
+ public new event EventHandler DoubleClick {
+ add { base.DoubleClick += value; }
+ remove { base.DoubleClick -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler FontChanged;
-
+ public new event EventHandler FontChanged {
+ add { base.FontChanged += value; }
+ remove { base.FontChanged -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler ForeColorChanged;
-
+ public new event EventHandler ForeColorChanged {
+ add { base.ForeColorChanged += value; }
+ remove { base.ForeColorChanged -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler ImeModeChanged;
-
+ public new event EventHandler ImeModeChanged {
+ add { base.ImeModeChanged += value; }
+ remove { base.ImeModeChanged -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event MouseEventHandler MouseDown;
-
+ public new event MouseEventHandler MouseDown {
+ add { base.MouseDown += value; }
+ remove { base.MouseDown -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event MouseEventHandler MouseMove;
-
+ public new event MouseEventHandler MouseMove {
+ add { base.MouseMove += value; }
+ remove { base.MouseMove -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event MouseEventHandler MouseUp;
-
+ public new event MouseEventHandler MouseUp {
+ add { base.MouseUp += value; }
+ remove { base.MouseUp -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event PaintEventHandler Paint;
-
+ public new event PaintEventHandler Paint {
+ add { base.Paint += value; }
+ remove { base.Paint -= value; }
+ }
+
public event ScrollEventHandler Scroll;
-
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler TextChanged;
-
+ public new event EventHandler TextChanged {
+ add { base.TextChanged += value; }
+ remove { base.TextChanged -= value; }
+ }
+
public event EventHandler ValueChanged;
#endregion Events
base.MouseMove += new MouseEventHandler (OnMouseMoveSB);
base.Resize += new EventHandler (OnResizeSB);
base.TabStop = false;
+ base.cursor = Cursors.Default;
- if (ThemeEngine.Current.DoubleBufferingSupported == true) {
- double_buffering = true;
- } else {
- double_buffering = false;
- }
-
- SetStyle (ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
- SetStyle (ControlStyles.ResizeRedraw | ControlStyles.Opaque, true);
+ SetStyle (ControlStyles.UserPaint | ControlStyles.StandardClick, false);
}
#region Internal & Private Properties
set {
if (base.BackColor == value)
return;
-
- if (BackColorChanged != null)
- BackColorChanged (this, EventArgs.Empty);
-
base.BackColor = value;
Refresh ();
}
if (base.BackgroundImage == value)
return;
- if (BackgroundImageChanged != null)
- BackgroundImageChanged (this, EventArgs.Empty);
-
base.BackgroundImage = value;
}
}
{
get { return base.Font; }
set {
- if (base.Font == value)
+ if (base.Font.Equals (value))
return;
- if (FontChanged != null)
- FontChanged (this, EventArgs.Empty);
-
base.Font = value;
}
}
if (base.ForeColor == value)
return;
- if (ForeColorChanged != null)
- ForeColorChanged (this, EventArgs.Empty);
-
base.ForeColor = value;
Refresh ();
}
if (base.ImeMode == value)
return;
- if (ImeModeChanged != null)
- ImeModeChanged (this, EventArgs.Empty);
-
base.ImeMode = value;
}
}
[DefaultValue (10)]
[RefreshProperties(RefreshProperties.Repaint)]
+ [MWFDescription("Scroll amount when clicking in the scroll area"), MWFCategory("Behaviour")]
public int LargeChange {
get {
if (large_change > maximum)
// so we need to recalculate it.
CalcThumbArea ();
UpdatePos (Value, true);
- Refresh ();
+ InvalidateDirty ();
}
}
}
[DefaultValue (100)]
[RefreshProperties(RefreshProperties.Repaint)]
+ [MWFDescription("Highest value for scrollbar"), MWFCategory("Behaviour")]
public int Maximum {
get { return maximum; }
set {
if (maximum == value)
return;
-
+
maximum = value;
if (maximum < minimum)
// so we need to recalculate it.
CalcThumbArea ();
UpdatePos (Value, true);
- Refresh ();
+ InvalidateDirty ();
+ }
+ }
+
+ internal void SetValues (int maximum, int large_change)
+ {
+ SetValues (-1, maximum, -1, large_change);
+ }
+
+ internal void SetValues (int minimum, int maximum, int small_change, int large_change)
+ {
+ bool update = false;
+
+ if (-1 != minimum && this.minimum != minimum) {
+ this.minimum = minimum;
+
+ if (minimum > this.maximum)
+ this.maximum = minimum;
+ update = true;
+ }
+
+ if (-1 != maximum && this.maximum != maximum) {
+ this.maximum = maximum;
+
+ if (maximum < this.minimum)
+ this.minimum = maximum;
+ update = true;
+ }
+
+ if (-1 != small_change && this.small_change != small_change) {
+ this.small_change = small_change;
+ }
+
+ if (this.large_change != large_change) {
+ this.large_change = large_change;
+ update = true;
+ }
+
+ if (update) {
+ CalcThumbArea ();
+ UpdatePos (Value, true);
+ InvalidateDirty ();
}
}
[DefaultValue (0)]
[RefreshProperties(RefreshProperties.Repaint)]
+ [MWFDescription("Smallest value for scrollbar"), MWFCategory("Behaviour")]
public int Minimum {
get { return minimum; }
set {
if (minimum == value)
return;
-
+
minimum = value;
if (minimum > maximum)
// so we need to recalculate it.
CalcThumbArea ();
UpdatePos (Value, true);
- Refresh ();
+ InvalidateDirty ();
}
}
[DefaultValue (1)]
+ [MWFDescription("Scroll amount when clicking scroll arrows"), MWFCategory("Behaviour")]
public int SmallChange {
get { return small_change; }
set {
if (small_change != value) {
small_change = value;
UpdatePos (Value, true);
- Refresh ();
+ InvalidateDirty ();
}
}
}
[Bindable(true)]
[DefaultValue (0)]
+ [MWFDescription("Current value for scrollbar"), MWFCategory("Behaviour")]
public int Value {
get { return position; }
set {
OnValueChanged (EventArgs.Empty);
- ClearDirty ();
- UpdatePos (Value, true);
- InvalidateDirty ();
+ if (IsHandleCreated) {
+ Rectangle thumb_rect = thumb_pos;
+
+ UpdateThumbPos ((vert ? thumb_area.Y : thumb_area.X) + (int)(((float)(position - minimum)) * pixel_per_pos), false, false);
+
+ MoveThumb (thumb_rect, vert ? thumb_pos.Y : thumb_pos.X);
+ }
}
}
}
#endregion //Public Properties
#region Public Methods
-
+
protected override void OnEnabledChanged (EventArgs e)
{
base.OnEnabledChanged (e);
Refresh ();
}
-
+
protected override void OnHandleCreated (System.EventArgs e)
{
- base.OnHandleCreated (e);
+ base.OnHandleCreated (e);
CalcButtonSizes ();
CalcThumbArea ();
- UpdatePos (Value, true);
+ UpdateThumbPos (thumb_area.Y + (int)(((float)(position - minimum)) * pixel_per_pos), true, false);
}
protected virtual void OnScroll (ScrollEventArgs event_args)
if (Scroll == null)
return;
+ if (event_args.NewValue < Minimum) {
+ event_args.NewValue = Minimum;
+ }
+
+ if (event_args.NewValue > Maximum) {
+ event_args.NewValue = Maximum;
+ }
+
Scroll (this, event_args);
}
+ private void SendWMScroll(ScrollBarCommands cmd) {
+ if ((parent != null) && parent.IsHandleCreated) {
+ if (vert) {
+ XplatUI.SendMessage(parent.Handle, Msg.WM_VSCROLL, (IntPtr)cmd, implicit_control ? IntPtr.Zero : Handle);
+ } else {
+ XplatUI.SendMessage(parent.Handle, Msg.WM_HSCROLL, (IntPtr)cmd, implicit_control ? IntPtr.Zero : Handle);
+ }
+ }
+ }
+
protected virtual void OnValueChanged (EventArgs e)
{
- if (ValueChanged != null)
+ if (ValueChanged != null) {
ValueChanged (this, e);
+ }
}
public override string ToString()
protected override void WndProc (ref Message m)
{
- switch ((Msg) m.Msg)
- {
- case Msg.WM_PAINT:
- {
- PaintEventArgs paint_event;
-
- paint_event = XplatUI.PaintEventStart (Handle);
- OnPaintSB (paint_event);
- XplatUI.PaintEventEnd (Handle);
- return;
- }
-
-
- case Msg.WM_ERASEBKGND:
- m.Result = (IntPtr) 1; /// Disable background painting to avoid flickering
- return;
-
- default:
- break;
- }
-
base.WndProc (ref m);
}
#endregion //Public Methods
#region Private Methods
-
+
private void CalcButtonSizes ()
- {
+ {
if (vert) {
if (Height < ThemeEngine.Current.ScrollBarButtonSize * 2)
scrollbutton_height = Height /2;
else
scrollbutton_height = ThemeEngine.Current.ScrollBarButtonSize;
-
+
} else {
if (Width < ThemeEngine.Current.ScrollBarButtonSize * 2)
scrollbutton_width = Width /2;
scrollbutton_width = ThemeEngine.Current.ScrollBarButtonSize;
}
}
-
+
private void CalcThumbArea ()
{
// Thumb area
thumb_size = 0;
else {
double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
- thumb_size = 1 + (int) (thumb_area.Height * per);
-
+ thumb_size = 1 + (int) (thumb_area.Height * per);
+
if (thumb_size < thumb_min_size)
thumb_size = thumb_min_size;
- }
+ }
pixel_per_pos = ((float)(thumb_area.Height - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
thumb_area.Y = 0;
thumb_area.X = scrollbutton_width;
thumb_area.Height = Height;
- thumb_area.Width = Width - scrollbutton_width - scrollbutton_width;
-
+ thumb_area.Width = Width - scrollbutton_width - scrollbutton_width;
+
if (Width < thumb_notshown_size)
thumb_size = 0;
else {
double per = ((double) this.LargeChange / (double)((1 + maximum - minimum)));
thumb_size = 1 + (int) (thumb_area.Width * per);
-
+
if (thumb_size < thumb_min_size)
thumb_size = thumb_min_size;
}
-
+
pixel_per_pos = ((float)(thumb_area.Width - thumb_size) / (float) ((maximum - minimum - this.LargeChange) + 1));
}
}
-
- private void Draw (Rectangle clip)
- {
- ThemeEngine.Current.DrawScrollBar(DeviceContext, clip, this);
- }
private void LargeIncrement ()
- {
+ {
ScrollEventArgs event_args;
- int pos = position + large_change;
-
+ int pos = Math.Min (Maximum - large_change + 1, position + large_change);
+
event_args = new ScrollEventArgs (ScrollEventType.LargeIncrement, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
-
- event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
+ OnScroll (event_args);
+ Value = event_args.NewValue;
- UpdatePos (pos, true);
+ event_args = new ScrollEventArgs (ScrollEventType.EndScroll, Value);
+ OnScroll (event_args);
+ Value = event_args.NewValue;
}
private void LargeDecrement ()
- {
+ {
ScrollEventArgs event_args;
- int pos = position - large_change;
-
+ int pos = Math.Max (Minimum, position - large_change);
+
event_args = new ScrollEventArgs (ScrollEventType.LargeDecrement, pos);
OnScroll (event_args);
- pos = event_args.NewValue;
-
- event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
+ Value = event_args.NewValue;
+
+ event_args = new ScrollEventArgs (ScrollEventType.EndScroll, Value);
OnScroll (event_args);
- pos = event_args.NewValue;
-
+ Value = event_args.NewValue;
+ }
- UpdatePos (pos, true);
- }
-
private void OnResizeSB (Object o, EventArgs e)
- {
+ {
if (Width <= 0 || Height <= 0)
return;
-
+
CalcButtonSizes ();
CalcThumbArea ();
UpdatePos (position, true);
+
+ Refresh ();
}
- private void OnPaintSB (PaintEventArgs pevent)
+ internal override void OnPaintInternal (PaintEventArgs pevent)
{
- if (Paint != null) {
- Paint (this, pevent);
- }
-
- if (Width <= 0 || Height <= 0 || Visible == false)
- return;
-
- Draw (pevent.ClipRectangle);
- pevent.Graphics.DrawImage (ImageBuffer, pevent.ClipRectangle, pevent.ClipRectangle, GraphicsUnit.Pixel);
+ ThemeEngine.Current.DrawScrollBar (pevent.Graphics, pevent.ClipRectangle, this);
}
private void OnTimer (Object source, EventArgs e)
case TimerType.RepeatButton:
{
- if ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
+ if ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed && position != Minimum) {
SmallDecrement();
+ SendWMScroll(ScrollBarCommands.SB_LINEUP);
+ }
- if ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)
+ if ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed && position != Maximum) {
SmallIncrement();
+ SendWMScroll(ScrollBarCommands.SB_LINEDOWN);
+ }
break;
}
pnt_screen = PointToScreen (new Point (thumb_area.X, thumb_area.Y));
thumb_area_screen.X = pnt_screen.X;
thumb_area_screen.Y = pnt_screen.Y;
-
- if (thumb_area_screen.Contains (MousePosition) == false) {
+
+ if (thumb_area_screen.Contains (MousePosition) == false) {
timer.Enabled = false;
thumb_moving = ThumbMoving.None;
DirtyThumbArea ();
InvalidateDirty ();
- }
-
+ }
+
pnt = PointToClient (MousePosition);
-
+
if (vert)
lastclick_pos = pnt.Y;
else
if (thumb_moving == ThumbMoving.Forward) {
if ((vert && (thumb_pos.Y + thumb_size > lastclick_pos)) ||
- (!vert && (thumb_pos.X + thumb_size > lastclick_pos)) ||
- (thumb_area.Contains (pnt) == false)){
- timer.Enabled = false;
+ (!vert && (thumb_pos.X + thumb_size > lastclick_pos)) ||
+ (thumb_area.Contains (pnt) == false)) {
+ timer.Enabled = false;
thumb_moving = ThumbMoving.None;
- Refresh ();
+ Refresh ();
return;
} else {
LargeIncrement ();
- }
- }
- else
+ SendWMScroll(ScrollBarCommands.SB_PAGEDOWN);
+ }
+ } else {
if ((vert && (thumb_pos.Y < lastclick_pos)) ||
- (!vert && (thumb_pos.X < lastclick_pos))){
+ (!vert && (thumb_pos.X < lastclick_pos))){
timer.Enabled = false;
thumb_moving = ThumbMoving.None;
- Refresh ();
+ SendWMScroll(ScrollBarCommands.SB_PAGEUP);
+ Refresh ();
} else {
LargeDecrement ();
+ SendWMScroll(ScrollBarCommands.SB_PAGEUP);
}
+ }
break;
}
}
InvalidateDirty ();
- }
+ }
+
+ private void MoveThumb (Rectangle original_thumbpos, int value)
+ {
+ /* so, the reason this works can best be
+ * described by the following 1 dimensional
+ * pictures
+ *
+ * say you have a scrollbar thumb positioned
+ * thusly:
+ *
+ * <---------------------| |------------------------------>
+ *
+ * and you want it to end up looking like this:
+ *
+ * <-----------------------------| |---------------------->
+ *
+ * that can be done with the scrolling api by
+ * extending the rectangle to encompass both
+ * positions:
+ *
+ * start of range end of range
+ * \ /
+ * <---------------------| |-------|---------------------->
+ *
+ * so, we end up scrolling just this little region:
+ *
+ * | |-------|
+ *
+ * and end up with ********| |
+ *
+ * where ****** is space that is automatically
+ * redrawn.
+ *
+ * It's clear that in both cases (left to
+ * right, right to left) we need to extend the
+ * size of the scroll rectangle to encompass
+ * both. In the right to left case, we also
+ * need to decrement the X coordinate.
+ *
+ * We call Update after scrolling to make sure
+ * there's no garbage left in the window to be
+ * copied again if we're called before the
+ * paint events have been handled.
+ *
+ */
+ int delta;
+
+ if (vert) {
+ delta = value - original_thumbpos.Y;
+
+ if (delta < 0) {
+ original_thumbpos.Y += delta;
+ original_thumbpos.Height -= delta;
+ }
+ else {
+ original_thumbpos.Height += delta;
+ }
+
+ XplatUI.ScrollWindow (Handle, original_thumbpos, 0, delta, false);
+ }
+ else {
+ delta = value - original_thumbpos.X;
+
+ if (delta < 0) {
+ original_thumbpos.X += delta;
+ original_thumbpos.Width -= delta;
+ }
+ else {
+ original_thumbpos.Width += delta;
+ }
+
+ XplatUI.ScrollWindow (Handle, original_thumbpos, delta, 0, false);
+ }
+
+ Update ();
+ }
private void OnMouseMoveSB (object sender, MouseEventArgs e)
{
- if (MouseMove != null) {
- MouseMove (this, e);
- }
-
if (Enabled == false || thumb_size == 0)
return;
if (!first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
firstbutton_state = ButtonState.Normal;
Invalidate (first_arrow_area);
+ Update();
return;
} else if (first_arrow_area.Contains (e.X, e.Y) && ((firstbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
firstbutton_state = ButtonState.Pushed;
Invalidate (first_arrow_area);
+ Update();
return;
}
} else if (secondbutton_pressed) {
if (!second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Pushed) == ButtonState.Pushed)) {
secondbutton_state = ButtonState.Normal;
Invalidate (second_arrow_area);
+ Update();
return;
} else if (second_arrow_area.Contains (e.X, e.Y) && ((secondbutton_state & ButtonState.Normal) == ButtonState.Normal)) {
secondbutton_state = ButtonState.Pushed;
Invalidate (second_arrow_area);
+ Update();
return;
}
} else if (thumb_pressed == true) {
- int pixel_pos;
-
if (vert) {
+ int thumb_edge = e.Y - thumbclick_offset;
- int mouse_click = e.Y;
- int outside_curpos = thumb_area.Y + thumb_area.Height - thumb_size + lastclick_pos_thumb;
-
-
- if (mouse_click > thumb_area.Y + thumb_area.Height) {
- outside_thumbarea_right = true;
- mouse_click = thumb_area.Y + thumb_area.Height;
- }
+ if (thumb_edge < thumb_area.Y)
+ thumb_edge = thumb_area.Y;
+ else if (thumb_edge > thumb_area.Bottom - thumb_size)
+ thumb_edge = thumb_area.Bottom - thumb_size;
- if (mouse_click < thumb_area.Y) {
- outside_thumbarea_left = true;
- mouse_click = thumb_area.Y;
- }
+ if (thumb_edge != thumb_pos.Y) {
+ Rectangle thumb_rect = thumb_pos;
- if (outside_thumbarea_right && mouse_click < outside_curpos) {
- outside_thumbarea_right = false;
- thumb_pixel_click_move_prev =
- thumb_pixel_click_move = outside_curpos;
- }
+ UpdateThumbPos (thumb_edge, false, true);
- if (outside_thumbarea_left && mouse_click > thumb_area.Y + lastclick_pos_thumb) {
- outside_thumbarea_left = false;
- thumb_pixel_click_move_prev =
- thumb_pixel_click_move = thumb_area.Y + lastclick_pos_thumb;
- }
+ MoveThumb (thumb_rect, thumb_pos.Y);
- if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
- pixel_pos = thumb_pos.Y + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
- thumb_pixel_click_move_prev = thumb_pixel_click_move;
- thumb_pixel_click_move = mouse_click;
-
- UpdateThumbPos (pixel_pos, true);
OnScroll (new ScrollEventArgs (ScrollEventType.ThumbTrack, position));
}
+ SendWMScroll(ScrollBarCommands.SB_THUMBTRACK);
+ } else {
+ int thumb_edge = e.X - thumbclick_offset;
- }
- else {
- int mouse_click = e.X;
- int outside_curpos = thumb_area.X + thumb_area.Width - thumb_size + lastclick_pos_thumb;
-
- if (mouse_click > thumb_area.X + thumb_area.Width) {
- outside_thumbarea_right = true;
- mouse_click = thumb_area.X + thumb_area.Width;
- }
+ if (thumb_edge < thumb_area.X)
+ thumb_edge = thumb_area.X;
+ else if (thumb_edge > thumb_area.Right - thumb_size)
+ thumb_edge = thumb_area.Right - thumb_size;
- if (mouse_click < thumb_area.X) {
- outside_thumbarea_left = true;
- mouse_click = thumb_area.X;
- }
+ if (thumb_edge != thumb_pos.X) {
+ Rectangle thumb_rect = thumb_pos;
- if (outside_thumbarea_right && mouse_click < outside_curpos) {
- outside_thumbarea_right = false;
- thumb_pixel_click_move_prev =
- thumb_pixel_click_move = outside_curpos;
- }
+ UpdateThumbPos (thumb_edge, false, true);
- if (outside_thumbarea_left && mouse_click > thumb_area.X + lastclick_pos_thumb) {
- outside_thumbarea_left = false;
- thumb_pixel_click_move_prev =
- thumb_pixel_click_move = thumb_area.X + lastclick_pos_thumb;
- }
+ MoveThumb (thumb_rect, thumb_pos.X);
- if (outside_thumbarea_right == false && outside_thumbarea_left == false) {
- pixel_pos = thumb_pos.X + (thumb_pixel_click_move - thumb_pixel_click_move_prev);
- thumb_pixel_click_move_prev = thumb_pixel_click_move;
- thumb_pixel_click_move = mouse_click;
- UpdateThumbPos (pixel_pos, true);
OnScroll (new ScrollEventArgs (ScrollEventType.ThumbTrack, position));
}
-
+ SendWMScroll(ScrollBarCommands.SB_THUMBTRACK);
}
- Refresh ();
}
}
private void OnMouseDownSB (object sender, MouseEventArgs e)
{
ClearDirty ();
-
- if (e.Button == MouseButtons.Right) {
- if (MouseDown != null) {
- MouseDown (this, e);
- }
- }
-
+
if (Enabled == false)
return;
if (firstbutton_state != ButtonState.Inactive && first_arrow_area.Contains (e.X, e.Y)) {
- this.Capture = true;
+ SendWMScroll(ScrollBarCommands.SB_LINEUP);
firstbutton_state = ButtonState.Pushed;
firstbutton_pressed = true;
Invalidate (first_arrow_area);
+ Update();
if (!timer.Enabled) {
SetHoldButtonClickTimer ();
timer.Enabled = true;
}
if (secondbutton_state != ButtonState.Inactive && second_arrow_area.Contains (e.X, e.Y)) {
- this.Capture = true;
+ SendWMScroll(ScrollBarCommands.SB_LINEDOWN);
secondbutton_state = ButtonState.Pushed;
secondbutton_pressed = true;
Invalidate (second_arrow_area);
+ Update();
if (!timer.Enabled) {
SetHoldButtonClickTimer ();
timer.Enabled = true;
if (thumb_size > 0 && thumb_pos.Contains (e.X, e.Y)) {
thumb_pressed = true;
- this.Capture = true;
+ SendWMScroll(ScrollBarCommands.SB_THUMBTRACK);
if (vert) {
- lastclick_pos_thumb = e.Y - thumb_pos.Y;
- lastclick_pos = e.Y;
- thumb_pixel_click_move_prev = thumb_pixel_click_move = e.Y;
+ thumbclick_offset = e.Y - thumb_pos.Y;
+ lastclick_pos = e.Y;
}
else {
- lastclick_pos_thumb = e.X - thumb_pos.X;
+ thumbclick_offset = e.X - thumb_pos.X;
lastclick_pos = e.X;
- thumb_pixel_click_move_prev = thumb_pixel_click_move = e.X;
}
} else {
if (thumb_size > 0 && thumb_area.Contains (e.X, e.Y)) {
lastclick_pos = e.Y;
if (e.Y > thumb_pos.Y + thumb_pos.Height) {
- LargeIncrement ();
- thumb_moving = ThumbMoving.Forward;
+ SendWMScroll(ScrollBarCommands.SB_PAGEDOWN);
+ LargeIncrement ();
+ thumb_moving = ThumbMoving.Forward;
Dirty (new Rectangle (0, thumb_pos.Y + thumb_pos.Height,
ClientRectangle.Width,
ClientRectangle.Height - (thumb_pos.Y + thumb_pos.Height) -
scrollbutton_height));
} else {
- LargeDecrement ();
+ SendWMScroll(ScrollBarCommands.SB_PAGEUP);
+ LargeDecrement ();
thumb_moving = ThumbMoving.Backwards;
Dirty (new Rectangle (0, scrollbutton_height,
ClientRectangle.Width,
lastclick_pos = e.X;
if (e.X > thumb_pos.X + thumb_pos.Width) {
+ SendWMScroll(ScrollBarCommands.SB_PAGEDOWN);
thumb_moving = ThumbMoving.Forward;
- LargeIncrement ();
+ LargeIncrement ();
Dirty (new Rectangle (thumb_pos.X + thumb_pos.Width, 0,
ClientRectangle.Width - (thumb_pos.X + thumb_pos.Width) -
scrollbutton_width,
ClientRectangle.Height));
} else {
+ SendWMScroll(ScrollBarCommands.SB_PAGEUP);
thumb_moving = ThumbMoving.Backwards;
- LargeDecrement ();
+ LargeDecrement ();
Dirty (new Rectangle (scrollbutton_width, 0,
thumb_pos.X - scrollbutton_width,
ClientRectangle.Height));
}
}
}
-
+
private void OnMouseUpSB (object sender, MouseEventArgs e)
{
ClearDirty ();
- if (e.Button == MouseButtons.Right) {
- if (MouseUp != null) {
- MouseUp (this, e);
- }
- }
-
if (Enabled == false)
return;
if (thumb_moving != ThumbMoving.None) {
DirtyThumbArea ();
thumb_moving = ThumbMoving.None;
- }
- this.Capture = false;
+ }
if (firstbutton_pressed) {
firstbutton_state = ButtonState.Normal;
if (first_arrow_area.Contains (e.X, e.Y)) {
SmallDecrement ();
}
+ SendWMScroll(ScrollBarCommands.SB_LINEUP);
firstbutton_pressed = false;
Dirty (first_arrow_area);
} else if (secondbutton_pressed) {
if (second_arrow_area.Contains (e.X, e.Y)) {
SmallIncrement ();
}
+ SendWMScroll(ScrollBarCommands.SB_LINEDOWN);
Dirty (second_arrow_area);
secondbutton_pressed = false;
} else if (thumb_pressed == true) {
OnScroll (new ScrollEventArgs (ScrollEventType.ThumbPosition, position));
OnScroll (new ScrollEventArgs (ScrollEventType.EndScroll, position));
+ SendWMScroll(ScrollBarCommands.SB_THUMBPOSITION);
thumb_pressed = false;
- Refresh ();
return;
}
break;
}
case Keys.Home:
- {
- SetHomePosition ();
+ {
+ SetHomePosition ();
break;
- }
+ }
case Keys.End:
- {
+ {
SetEndPosition ();
break;
}
}
InvalidateDirty ();
- }
-
- private void SetEndPosition ()
- {
+ }
+
+ private void SetEndPosition ()
+ {
ScrollEventArgs event_args;
- int pos = Maximum;
-
+ int pos = Maximum - large_change + 1;
+
event_args = new ScrollEventArgs (ScrollEventType.Last, pos);
OnScroll (event_args);
- pos = event_args.NewValue;
-
+ pos = event_args.NewValue;
+
event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
+ OnScroll (event_args);
+ pos = event_args.NewValue;
SetValue (pos);
}
-
+
private void SetHomePosition ()
{
ScrollEventArgs event_args;
int pos = Minimum;
-
+
event_args = new ScrollEventArgs (ScrollEventType.First, pos);
OnScroll (event_args);
pos = event_args.NewValue;
-
+
event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
-
+ OnScroll (event_args);
+ pos = event_args.NewValue;
+
SetValue (pos);
- }
+ }
private void SmallIncrement ()
{
ScrollEventArgs event_args;
- int pos = position + small_change;
-
+ int pos = Math.Min (Maximum - large_change + 1, position + small_change);
+
event_args = new ScrollEventArgs (ScrollEventType.SmallIncrement, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
-
- event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
+ OnScroll (event_args);
+ Value = event_args.NewValue;
- UpdatePos (pos, true);
+ event_args = new ScrollEventArgs (ScrollEventType.EndScroll, Value);
+ OnScroll (event_args);
+ Value = event_args.NewValue;
}
private void SmallDecrement ()
- {
+ {
ScrollEventArgs event_args;
- int pos = position - small_change;
-
+ int pos = Math.Max (Minimum, position - small_change);
+
event_args = new ScrollEventArgs (ScrollEventType.SmallDecrement, pos);
OnScroll (event_args);
- pos = event_args.NewValue;
-
- event_args = new ScrollEventArgs (ScrollEventType.EndScroll, pos);
- OnScroll (event_args);
- pos = event_args.NewValue;
+ Value = event_args.NewValue;
- UpdatePos (pos, true);
+ event_args = new ScrollEventArgs (ScrollEventType.EndScroll, Value);
+ OnScroll (event_args);
+ Value = event_args.NewValue;
}
-
+
private void SetHoldButtonClickTimer ()
{
timer.Enabled = false;
timer.Interval = 50;
timer_type = TimerType.RepeatThumbArea;
timer.Enabled = true;
- }
-
+ }
+
private void UpdatePos (int newPos, bool update_thumbpos)
{
- int old = position;
int pos;
if (newPos < minimum)
else
if (newPos > maximum + 1 - large_change)
pos = maximum + 1 - large_change;
- else
- pos = newPos;
+ else
+ pos = newPos;
// pos can't be less than minimum
if (pos < minimum)
if (update_thumbpos) {
if (vert)
- UpdateThumbPos (thumb_area.Y + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
+ UpdateThumbPos (thumb_area.Y + (int)(((float)(pos - minimum)) * pixel_per_pos), true, false);
else
- UpdateThumbPos (thumb_area.X + (int)(((float)(pos - minimum)) * pixel_per_pos), false);
+ UpdateThumbPos (thumb_area.X + (int)(((float)(pos - minimum)) * pixel_per_pos), true, false);
SetValue (pos);
}
else {
position = pos; // Updates directly the value to avoid thumb pos update
-
+
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
- }
+ }
}
- private void UpdateThumbPos (int pixel, bool update_value)
+ private void UpdateThumbPos (int pixel, bool dirty, bool update_value)
{
float new_pos = 0;
if (vert) {
- Dirty (thumb_pos);
+ if (dirty)
+ Dirty (thumb_pos);
if (pixel < thumb_area.Y)
thumb_pos.Y = thumb_area.Y;
+ else if (pixel > thumb_area.Bottom - thumb_size)
+ thumb_pos.Y = thumb_area.Bottom - thumb_size;
else
- if (pixel > thumb_area.Y + thumb_area.Height - thumb_size)
- thumb_pos.Y = thumb_area.Y + thumb_area.Height - thumb_size;
- else
- thumb_pos.Y = pixel;
+ thumb_pos.Y = pixel;
thumb_pos.X = 0;
thumb_pos.Width = ThemeEngine.Current.ScrollBarButtonSize;
thumb_pos.Height = thumb_size;
new_pos = (float) (thumb_pos.Y - thumb_area.Y);
new_pos = new_pos / pixel_per_pos;
-
- Dirty (thumb_pos);
+ if (dirty)
+ Dirty (thumb_pos);
} else {
- Dirty (thumb_pos);
+ if (dirty)
+ Dirty (thumb_pos);
if (pixel < thumb_area.X)
thumb_pos.X = thumb_area.X;
+ else if (pixel > thumb_area.Right - thumb_size)
+ thumb_pos.X = thumb_area.Right - thumb_size;
else
- if (pixel > thumb_area.X + thumb_area.Width - thumb_size)
- thumb_pos.X = thumb_area.X + thumb_area.Width - thumb_size;
- else
- thumb_pos.X = pixel;
+ thumb_pos.X = pixel;
thumb_pos.Y = 0;
thumb_pos.Width = thumb_size;
new_pos = (float) (thumb_pos.X - thumb_area.X);
new_pos = new_pos / pixel_per_pos;
- Dirty (thumb_pos);
+ if (dirty)
+ Dirty (thumb_pos);
}
if (update_value)
private void InvalidateDirty ()
{
Invalidate (dirty);
+ Update();
dirty = Rectangle.Empty;
}