Allows ListView trigger the Enter and Leave events. (#1508)

* Allows ListView trigger the Enter and Leave events.

* Added unit test for Enter and Leave events to all views.
This commit is contained in:
BDisp
2021-11-13 15:46:49 +00:00
committed by GitHub
parent ce99df4629
commit d84ab39ec3
6 changed files with 120 additions and 50 deletions

View File

@@ -256,7 +256,7 @@ namespace Terminal.Gui {
///<inheritdoc/>
public override void PositionCursor ()
{
if (HotKey == Key.Unknown) {
if (HotKey == Key.Unknown && text != "") {
for (int i = 0; i < base.Text.RuneCount; i++) {
if (base.Text [i] == text [0]) {
Move (i, 0);

View File

@@ -238,7 +238,7 @@ namespace Terminal.Gui {
search.CursorPosition = search.Text.RuneCount;
return true;
return base.OnEnter (view);
}
///<inheritdoc/>
@@ -251,7 +251,7 @@ namespace Terminal.Gui {
listview.TabStop = false;
}
return true;
return base.OnLeave (view);
}
/// <summary>

View File

@@ -673,7 +673,6 @@ namespace Terminal.Gui {
if (lastSelectedItem == -1) {
EnsuresVisibilitySelectedItem ();
OnSelectedChanged ();
return true;
}
return base.OnEnter (view);
@@ -684,10 +683,9 @@ namespace Terminal.Gui {
{
if (lastSelectedItem > -1) {
lastSelectedItem = -1;
return true;
}
return false;
return base.OnLeave (view);
}
void EnsuresVisibilitySelectedItem ()

View File

@@ -174,7 +174,7 @@ namespace Terminal.Gui {
int startAtY = Math.Max (0, GetTabHeight (true) - 1);
DrawFrame (new Rect (0, startAtY, bounds.Width,
bounds.Height - spaceAtBottom - startAtY), 0, true);
Math.Max (bounds.Height - spaceAtBottom - startAtY, 0)), 0, true);
}
if (Tabs.Any ()) {

View File

@@ -454,7 +454,7 @@ namespace Terminal.Gui {
// Fixed = true, is for inputs thar have fixed width, like masked ones.
// Fixed = false, is for normal input.
// When it's right-aligned and it's a normal input, the cursor behaves differently.
if (provider.Fixed == false && TextAlignment == TextAlignment.Right) {
if (provider?.Fixed == false && TextAlignment == TextAlignment.Right) {
Move (cursorPosition + left - 1, 0);
} else {
Move (cursorPosition + left, 0);
@@ -591,7 +591,7 @@ namespace Terminal.Gui {
public override bool ProcessKey (KeyEvent kb)
{
if (provider == null) {
return true;
return false;
}
switch (kb.Key) {

View File

@@ -22,53 +22,67 @@ namespace Terminal.Gui.Views {
public bool Constructors_FullTest (Type type)
{
foreach (var ctor in type.GetConstructors ()) {
if (type.IsGenericType && type.IsTypeDefinition) {
List<Type> gTypes = new List<Type> ();
foreach (var args in type.GetGenericArguments ()) {
gTypes.Add (typeof (object));
}
type = type.MakeGenericType (gTypes.ToArray ());
Assert.IsType (type, (View)Activator.CreateInstance (type));
} else {
ParameterInfo [] paramsInfo = ctor.GetParameters ();
Type paramType;
List<object> pTypes = new List<object> ();
if (type.IsGenericType) {
foreach (var args in type.GetGenericArguments ()) {
paramType = args.GetType ();
if (args.Name == "T") {
pTypes.Add (typeof (object));
} else {
AddArguments (paramType, pTypes);
}
}
}
foreach (var p in paramsInfo) {
paramType = p.ParameterType;
if (p.HasDefaultValue) {
pTypes.Add (p.DefaultValue);
} else {
AddArguments (paramType, pTypes);
}
}
if (type.IsGenericType && !type.IsTypeDefinition) {
Assert.IsType (type, (View)Activator.CreateInstance (type));
} else {
Assert.IsType (type, ctor.Invoke (pTypes.ToArray ()));
}
var view = GetTypeInitializer (type, ctor);
if (view != null) {
Assert.True (type.FullName == view.GetType ().FullName);
}
}
return true;
}
private static View GetTypeInitializer (Type type, ConstructorInfo ctor)
{
View viewType = null;
if (type.IsGenericType && type.IsTypeDefinition) {
List<Type> gTypes = new List<Type> ();
foreach (var args in type.GetGenericArguments ()) {
gTypes.Add (typeof (object));
}
type = type.MakeGenericType (gTypes.ToArray ());
Assert.IsType (type, (View)Activator.CreateInstance (type));
} else {
ParameterInfo [] paramsInfo = ctor.GetParameters ();
Type paramType;
List<object> pTypes = new List<object> ();
if (type.IsGenericType) {
foreach (var args in type.GetGenericArguments ()) {
paramType = args.GetType ();
if (args.Name == "T") {
pTypes.Add (typeof (object));
} else {
AddArguments (paramType, pTypes);
}
}
}
foreach (var p in paramsInfo) {
paramType = p.ParameterType;
if (p.HasDefaultValue) {
pTypes.Add (p.DefaultValue);
} else {
AddArguments (paramType, pTypes);
}
}
if (type.IsGenericType && !type.IsTypeDefinition) {
viewType = (View)Activator.CreateInstance (type);
Assert.IsType (type, viewType);
} else {
viewType = (View)ctor.Invoke (pTypes.ToArray ());
Assert.IsType (type, viewType);
}
}
return viewType;
}
private static void AddArguments (Type paramType, List<object> pTypes)
{
if (paramType == typeof (Rect)) {
@@ -108,5 +122,63 @@ namespace Terminal.Gui.Views {
}
return types;
}
[Fact]
public void AllViews_Enter_Leave_Events ()
{
foreach (var type in GetAllViewClassesCollection ()) {
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
var top = Application.Top;
var vType = GetTypeInitializer (type, type.GetConstructor (Array.Empty<Type> ()));
if (vType == null) {
Application.Shutdown ();
continue;
}
vType.X = 0;
vType.Y = 0;
vType.Width = 10;
vType.Height = 1;
var view = new View () {
X = 0,
Y = 1,
Width = 10,
Height = 1,
CanFocus = true
};
var vTypeEnter = 0;
var vTypeLeave = 0;
var viewEnter = 0;
var viewLeave = 0;
vType.Enter += _ => vTypeEnter++;
vType.Leave += _ => vTypeLeave++;
view.Enter += _ => viewEnter++;
view.Leave += _ => viewLeave++;
top.Add (vType, view);
Application.Begin (top);
if (!vType.CanFocus || (vType is Toplevel && ((Toplevel)vType).Modal)) {
Application.Shutdown ();
continue;
}
if (vType is TextView) {
top.ProcessKey (new KeyEvent (Key.Tab | Key.CtrlMask, new KeyModifiers ()));
} else {
top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
}
top.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()));
Assert.Equal (2, vTypeEnter);
Assert.Equal (1, vTypeLeave);
Assert.Equal (1, viewEnter);
Assert.Equal (1, viewLeave);
Application.Shutdown ();
}
}
}
}