mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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 ()) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user