Fixes #3209 - Formalize Cancellable Work Pattern and add helpers (#4092)

This commit is contained in:
Tig
2025-06-03 08:12:57 -06:00
committed by GitHub
parent 7490ac9776
commit 764a804ddd
127 changed files with 3720 additions and 1421 deletions

View File

@@ -144,7 +144,7 @@ public class ShadowStyleTests (ITestOutputHelper output)
Width = Dim.Auto (),
Height = Dim.Auto (),
Text = "0123",
HighlightStyle = HighlightStyle.Pressed,
HighlightStates = MouseState.Pressed,
ShadowStyle = style,
CanFocus = true
};

View File

@@ -291,66 +291,54 @@ public class MouseTests : TestsAllViews
Assert.Equal (2, clickedCount);
me.Handled = false;
// Stay in Viewport
me.Flags = MouseFlags.Button1Pressed;
me.Position = me.Position with { X = 0 };
view.NewMouseEvent (me);
Assert.Equal (3, clickedCount);
me.Handled = false;
view.Dispose ();
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
}
[Theory (Skip = "This test needs to be redone.")]
[InlineData (HighlightStyle.None, 0, 0)]
[InlineData (HighlightStyle.Pressed | HighlightStyle.PressedOutside, 1, 1)]
public void HighlightOnPress_Fires_Events_And_Highlights (HighlightStyle highlightOnPress, int expectedEnabling, int expectedDisabling)
{
var view = new View
{
CanFocus = true,
HighlightStyle = highlightOnPress,
Height = 1,
Width = 1
};
//[Theory]
//[InlineData (true, MouseState.None, 0, 0, 0, 0)]
//[InlineData (true, MouseState.In, 0, 0, 0, 0)]
//[InlineData (true, MouseState.Pressed, 0, 0, 1, 0)]
//[InlineData (true, MouseState.PressedOutside, 0, 0, 0, 1)]
//public void MouseState_Button1_Pressed_Then_Released_Outside (bool inViewport, MouseState highlightFlags, int noneCount, int expectedInCount, int expectedPressedCount, int expectedPressedOutsideCount)
//{
// var testView = new MouseEventTestView
// {
// HighlightStates = highlightFlags
// };
var enablingHighlight = 0;
var disablingHighlight = 0;
view.Highlight += ViewHighlight;
view.SetScheme (new (new Attribute (ColorName16.Red, ColorName16.Blue)));
Scheme originalScheme = view.GetScheme ();
// Assert.Equal (0, testView.MouseStateInCount);
// Assert.Equal (0, testView.MouseStatePressedCount);
// Assert.Equal (0, testView.MouseStatePressedOutsideCount);
// Assert.Equal (0, testView.MouseStateNoneCount);
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
// testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (inViewport ? 0 : 1, 0) });
// Assert.Equal (expectedInCount, testView.MouseStateInCount);
// Assert.Equal (expectedPressedCount, testView.MouseStatePressedCount);
// Assert.Equal (expectedPressedOutsideCount, testView.MouseStatePressedOutsideCount);
// Assert.Equal (noneCount, testView.MouseStateNoneCount);
if (highlightOnPress != HighlightStyle.None)
{
Assert.NotEqual (originalScheme, view.GetScheme ());
}
else
{
Assert.Equal (originalScheme, view.GetScheme ());
}
// testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Released, Position = new (inViewport ? 0 : 1, 0) });
// Assert.Equal (expectedInCount, testView.MouseStateInCount);
// Assert.Equal (expectedPressedCount, testView.MouseStatePressedCount);
// Assert.Equal (expectedPressedOutsideCount, testView.MouseStatePressedOutsideCount);
// Assert.Equal (noneCount, testView.MouseStateNoneCount);
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Released });
Assert.Equal (originalScheme, view.GetScheme ());
Assert.Equal (expectedEnabling, enablingHighlight);
Assert.Equal (expectedDisabling, disablingHighlight);
// testView.Dispose ();
view.Dispose ();
// // Button1Pressed, Button1Released cause Application.MouseGrabView to be set
// Application.ResetState (true);
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
return;
void ViewHighlight (object sender, CancelEventArgs<HighlightStyle> e)
{
if (e.NewValue == HighlightStyle.None)
{
disablingHighlight++;
}
else
{
enablingHighlight++;
}
}
}
//}
// TODO: Add tests for each combination of HighlightFlags
@@ -358,70 +346,298 @@ public class MouseTests : TestsAllViews
[InlineData (0)]
[InlineData (1)]
[InlineData (10)]
public void HighlightOnPress_Move_Keeps_Highlight (int x)
public void MouseState_None_Button1_Pressed_Move_No_Changes (int x)
{
var view = new View
var testView = new MouseEventTestView
{
CanFocus = true,
HighlightStyle = HighlightStyle.Pressed | HighlightStyle.PressedOutside,
Height = 1,
Width = 1
HighlightStates = MouseState.None
};
var enablingHighlight = 0;
var disablingHighlight = 0;
view.Highlight += ViewHighlight;
bool inViewport = view.Viewport.Contains (x, 0);
bool inViewport = testView.Viewport.Contains (x, 0);
// Start at 0,0 ; in viewport
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
Assert.Equal (1, enablingHighlight);
Assert.Equal (0, disablingHighlight);
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
// Move to x,0
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (x, 0) });
if (inViewport)
{
Assert.Equal (2, enablingHighlight);
Assert.Equal (0, disablingHighlight);
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (2, enablingHighlight);
Assert.Equal (0, disablingHighlight);
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
// Move backto 0,0 ; in viewport
view.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
if (inViewport)
{
Assert.Equal (3, enablingHighlight);
Assert.Equal (0, disablingHighlight);
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (3, enablingHighlight);
Assert.Equal (0, disablingHighlight);
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
view.Dispose ();
testView.Dispose ();
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
}
return;
void ViewHighlight (object sender, CancelEventArgs<HighlightStyle> e)
[Theory]
[InlineData (0)]
[InlineData (1)]
[InlineData (10)]
public void MouseState_Pressed_Button1_Pressed_Move_Keeps_Pressed (int x)
{
var testView = new MouseEventTestView
{
if (e.NewValue == HighlightStyle.None)
HighlightStates = MouseState.Pressed
};
bool inViewport = testView.Viewport.Contains (x, 0);
// Start at 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (1, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
// Move to x,0
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (x, 0) });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (1, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (1, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
// Move backto 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (1, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (1, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
testView.Dispose ();
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
}
[Theory]
[InlineData (0)]
[InlineData (1)]
[InlineData (10)]
public void MouseState_PressedOutside_Button1_Pressed_Move_Raises_PressedOutside (int x)
{
var testView = new MouseEventTestView
{
HighlightStates = MouseState.PressedOutside,
WantContinuousButtonPressed = false
};
bool inViewport = testView.Viewport.Contains (x, 0);
// Start at 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
// Move to x,0
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (x, 0) });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (1, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
// Move backto 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (1, testView.MouseStatePressedOutsideCount);
Assert.Equal (1, testView.MouseStateNoneCount);
}
testView.Dispose ();
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
}
[Theory]
[InlineData (0)]
[InlineData (1)]
[InlineData (10)]
public void MouseState_PressedOutside_Button1_Pressed_Move_Raises_PressedOutside_WantContinuousButtonPressed (int x)
{
var testView = new MouseEventTestView
{
HighlightStates = MouseState.PressedOutside,
WantContinuousButtonPressed = true
};
bool inViewport = testView.Viewport.Contains (x, 0);
// Start at 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
// Move to x,0
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (x, 0) });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
// Move backto 0,0 ; in viewport
testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
if (inViewport)
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
else
{
Assert.Equal (0, testView.MouseStateInCount);
Assert.Equal (0, testView.MouseStatePressedCount);
Assert.Equal (0, testView.MouseStatePressedOutsideCount);
Assert.Equal (0, testView.MouseStateNoneCount);
}
testView.Dispose ();
// Button1Pressed, Button1Released cause Application.MouseGrabView to be set
Application.ResetState (true);
}
private class MouseEventTestView : View
{
public int MouseEnterCount { get; private set; }
public int MouseLeaveCount { get; private set; }
public int MouseStatePressedOutsideCount { get; private set; }
public int MouseStateInCount { get; private set; }
public int MouseStatePressedCount { get; private set; }
public int MouseStateNoneCount { get; private set; }
public MouseEventTestView ()
{
Height = 1;
Width = 1;
CanFocus = true;
Id = "mouseEventTestView";
MouseLeave += (s, e) => { MouseEnterCount++; };
MouseEnter += (s, e) => { MouseLeaveCount++; };
}
/// <inheritdoc/>
protected override void OnMouseStateChanged (EventArgs<MouseState> args)
{
switch (args.Value)
{
disablingHighlight++;
}
else
{
enablingHighlight++;
case MouseState.None:
MouseStateNoneCount++;
break;
case MouseState.In:
MouseStateInCount++;
break;
case MouseState.Pressed:
MouseStatePressedCount++;
break;
case MouseState.PressedOutside:
MouseStatePressedOutsideCount++;
break;
}
base.OnMouseStateChanged (args);
}
}
}