Prevents continuous mouse button pressed from processing mouse event without slider completed the layout.

This commit is contained in:
BDisp
2024-08-21 22:15:17 +01:00
parent 81888222ea
commit 92e067e014
2 changed files with 37 additions and 6 deletions

View File

@@ -22,12 +22,12 @@ public class Scroll : View
Height = Dim.Auto (DimAutoStyle.Content, 1);
}
internal bool _wasSliderLayoutComplete = true;
private readonly ScrollSlider _slider;
private Orientation _orientation;
private int _position;
private int _size;
/// <inheritdoc/>
@@ -118,6 +118,12 @@ public class Scroll : View
/// <inheritdoc/>
protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
{
if (!_wasSliderLayoutComplete)
{
// Do not process if slider layout wasn't yet completed
return base.OnMouseEvent (mouseEvent);
}
int location = Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X;
int barSize = Orientation == Orientation.Vertical ? GetContentSize ().Height : GetContentSize ().Width;
@@ -125,11 +131,11 @@ public class Scroll : View
? new (_slider.Frame.Y, _slider.Frame.Bottom - 1)
: new (_slider.Frame.X, _slider.Frame.Right - 1);
if (mouseEvent.Flags == MouseFlags.Button1Pressed && location < sliderPos.topLeft)
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && location < sliderPos.topLeft)
{
Position = Math.Max (Position - barSize, 0);
}
else if (mouseEvent.Flags == MouseFlags.Button1Pressed && location > sliderPos.bottomRight)
else if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && location > sliderPos.bottomRight)
{
Position = Math.Min (Position + barSize, Size - barSize);
}
@@ -150,10 +156,21 @@ public class Scroll : View
return _slider.OnMouseEvent (mouseEvent);
}
}
// Flag as false until slider layout is completed
_wasSliderLayoutComplete = false;
return base.OnMouseEvent (mouseEvent);
}
/// <inheritdoc/>
protected internal override bool OnMouseLeave (MouseEvent mouseEvent)
{
// If scroll isn't handling mouse then reset the flag
_wasSliderLayoutComplete = true;
return base.OnMouseLeave (mouseEvent);
}
// TODO: Move this into "ScrollSlider" and override it there. Scroll can then subscribe to _slider.LayoutComplete and call AdjustSlider.
// QUESTION: I've been meaning to add a "View.FrameChanged" event (fired from LayoutComplete only if Frame has changed). Should we do that as part of this PR?
// QUESTION: Note I *did* add "View.ViewportChanged" in a previous PR.

View File

@@ -73,11 +73,17 @@ internal class ScrollSlider : View
/// <inheritdoc/>
protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
{
if (!_host._wasSliderLayoutComplete)
{
// Ensure not blocking scroll mouse event
_host._wasSliderLayoutComplete = true;
}
int location = _host.Orientation == Orientation.Vertical ? mouseEvent.Position.Y : mouseEvent.Position.X;
int offset = _lastLocation > -1 ? location - _lastLocation : 0;
int barSize = _host.Orientation == Orientation.Vertical ? _host.GetContentSize ().Height : _host.GetContentSize ().Width;
if (mouseEvent.Flags == MouseFlags.Button1Pressed)
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) && _lastLocation == -1)
{
if (Application.MouseGrabView != this)
{
@@ -143,6 +149,14 @@ internal class ScrollSlider : View
return base.OnMouseLeave (mouseEvent);
}
/// <inheritdoc />
internal override void OnLayoutComplete (LayoutEventArgs args)
{
base.OnLayoutComplete (args);
_host._wasSliderLayoutComplete = true;
}
private int GetPositionFromSliderLocation (int location)
{
if (_host.GetContentSize ().Height == 0 || _host.GetContentSize ().Width == 0)