mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Fixed #3905, #3918 * Tweaked Generic * Label code cleanup * Clean up. * Clean up. * Clean up2.
This commit is contained in:
@@ -19,15 +19,19 @@ internal partial class LoginView : IRecipient<Message<LoginActions>>
|
|||||||
{
|
{
|
||||||
ViewModel.Password = passwordInput.Text;
|
ViewModel.Password = passwordInput.Text;
|
||||||
};
|
};
|
||||||
loginButton.Accepting += (_, _) =>
|
loginButton.Accepting += (_, e) =>
|
||||||
{
|
{
|
||||||
if (!ViewModel.CanLogin) { return; }
|
if (!ViewModel.CanLogin) { return; }
|
||||||
ViewModel.LoginCommand.Execute (null);
|
ViewModel.LoginCommand.Execute (null);
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
clearButton.Accepting += (_, _) =>
|
clearButton.Accepting += (_, e) =>
|
||||||
{
|
{
|
||||||
ViewModel.ClearCommand.Execute (null);
|
ViewModel.ClearCommand.Execute (null);
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Initialized += (_, _) => { ViewModel.Initialized (); };
|
Initialized += (_, _) => { ViewModel.Initialized (); };
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ public class ExampleWindow : Window
|
|||||||
{
|
{
|
||||||
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
||||||
}
|
}
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the views to the Window
|
// Add the views to the Window
|
||||||
|
|||||||
@@ -105,6 +105,8 @@ public class ExampleWindow : Window
|
|||||||
{
|
{
|
||||||
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
||||||
}
|
}
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the views to the Window
|
// Add the views to the Window
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ public class ExampleWindow : Window
|
|||||||
{
|
{
|
||||||
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok");
|
||||||
}
|
}
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the views to the Window
|
// Add the views to the Window
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ public class DefaultFileOperations : IFileOperations
|
|||||||
{
|
{
|
||||||
confirm = true;
|
confirm = true;
|
||||||
Application.RequestStop ();
|
Application.RequestStop ();
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
var btnCancel = new Button { Text = Strings.btnCancel };
|
var btnCancel = new Button { Text = Strings.btnCancel };
|
||||||
|
|
||||||
@@ -146,6 +148,8 @@ public class DefaultFileOperations : IFileOperations
|
|||||||
{
|
{
|
||||||
confirm = false;
|
confirm = false;
|
||||||
Application.RequestStop ();
|
Application.RequestStop ();
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
var lbl = new Label { Text = Strings.fdRenamePrompt };
|
var lbl = new Label { Text = Strings.fdRenamePrompt };
|
||||||
|
|||||||
@@ -559,7 +559,8 @@ public partial class View // Mouse APIs
|
|||||||
// If mouse is still in bounds, generate a click
|
// If mouse is still in bounds, generate a click
|
||||||
if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position))
|
if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position))
|
||||||
{
|
{
|
||||||
return RaiseMouseClickEvent (mouseEvent);
|
|
||||||
|
return RaiseMouseClickEvent (mouseEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mouseEvent.Handled = true;
|
return mouseEvent.Handled = true;
|
||||||
|
|||||||
@@ -165,10 +165,10 @@ public class Button : View, IDesignable
|
|||||||
/// If <see langword="true"/>:
|
/// If <see langword="true"/>:
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// - the Button will display an indicator that it is the default Button.
|
/// - The Button will display an indicator that it is the default Button.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// - when clicked, if the Accepting event is not handled, <see cref="Command.Accept"/> will be
|
/// - When clicked, if the Accepting event is not handled, <see cref="Command.Accept"/> will be
|
||||||
/// invoked on the SuperView.
|
/// invoked on the SuperView.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>
|
/// <para>
|
||||||
@@ -197,7 +197,7 @@ public class Button : View, IDesignable
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets whether the Button will show decorations or not. If <see langword="true"/> the glyphs that normally
|
/// Gets or sets whether the Button will show decorations or not. If <see langword="true"/> the glyphs that normally
|
||||||
/// brakcet the Button Title and the <see cref="IsDefault"/> indicator will not be shown.
|
/// bracket the Button Title and the <see cref="IsDefault"/> indicator will not be shown.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool NoDecorations { get; set; }
|
public bool NoDecorations { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Label <see cref="View"/> displays text that describes the View next in the <see cref="View.Subviews"/>. When
|
/// The Label <see cref="View"/> displays text that describes the View next in the <see cref="View.Subviews"/>. When
|
||||||
/// Label
|
/// Label
|
||||||
/// recieves a <see cref="Command.HotKey"/> command it will pass it to the next <see cref="View"/> in
|
/// receives a <see cref="Command.HotKey"/> command it will pass it to the next <see cref="View"/> in
|
||||||
/// <see cref="View.Subviews"/>.
|
/// <see cref="View.Subviews"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
/// <para>
|
/// <para>
|
||||||
/// If <see cref="View.CanFocus"/> is <see langword="false"/> and the use clicks on the Label,
|
/// If <see cref="View.CanFocus"/> is <see langword="false"/> and the use clicks on the Label,
|
||||||
/// the <see cref="Command.HotKey"/> will be invoked on the next <see cref="View"/> in
|
/// the <see cref="Command.HotKey"/> will be invoked on the next <see cref="View"/> in
|
||||||
/// <see cref="View.Subviews"/>."
|
/// <see cref="View.Subviews"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class Label : View, IDesignable
|
public class Label : View, IDesignable
|
||||||
@@ -31,7 +31,6 @@ public class Label : View, IDesignable
|
|||||||
MouseClick += Label_MouseClick;
|
MouseClick += Label_MouseClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: base raises Select, but we want to raise HotKey. This can be simplified?
|
|
||||||
private void Label_MouseClick (object sender, MouseEventArgs e)
|
private void Label_MouseClick (object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (!CanFocus)
|
if (!CanFocus)
|
||||||
@@ -74,12 +73,15 @@ public class Label : View, IDesignable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int me = SuperView?.Subviews.IndexOf (this) ?? -1;
|
if (HotKey.IsValid)
|
||||||
|
|
||||||
if (me != -1 && me < SuperView?.Subviews.Count - 1)
|
|
||||||
{
|
{
|
||||||
|
int me = SuperView?.Subviews.IndexOf (this) ?? -1;
|
||||||
|
|
||||||
return SuperView?.Subviews [me + 1].InvokeCommand (Command.HotKey) == true;
|
if (me != -1 && me < SuperView?.Subviews.Count - 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
return SuperView?.Subviews [me + 1].InvokeCommand (Command.HotKey) == true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -20,7 +20,13 @@ public sealed class Generic : Scenario
|
|||||||
|
|
||||||
var button = new Button { Id = "button", X = Pos.Center (), Y = 1, Text = "_Press me!" };
|
var button = new Button { Id = "button", X = Pos.Center (), Y = 1, Text = "_Press me!" };
|
||||||
|
|
||||||
button.Accepting += (s, e) => MessageBox.ErrorQuery ("Error", "You pressed the button!", "_Ok");
|
button.Accepting += (s, e) =>
|
||||||
|
{
|
||||||
|
// Anytime Accepting is handled, make sure to set e.Cancel to false.
|
||||||
|
e.Cancel = true;
|
||||||
|
MessageBox.ErrorQuery ("Error", "You pressed the button!", "_Ok");
|
||||||
|
};
|
||||||
|
|
||||||
appWindow.Add (button);
|
appWindow.Add (button);
|
||||||
|
|
||||||
// Run - Start the application.
|
// Run - Start the application.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class ViewCommandTests
|
|||||||
var view = new ViewEventTester ();
|
var view = new ViewEventTester ();
|
||||||
Assert.False (view.HasFocus);
|
Assert.False (view.HasFocus);
|
||||||
|
|
||||||
Assert.False (view.InvokeCommand (Command.Accept)); // false means it was not handled
|
Assert.False (view.InvokeCommand (Command.Accept)); // there's no superview, so it should return true?
|
||||||
|
|
||||||
Assert.Equal (1, view.OnAcceptedCount);
|
Assert.Equal (1, view.OnAcceptedCount);
|
||||||
|
|
||||||
@@ -124,6 +124,148 @@ public class ViewCommandTests
|
|||||||
Assert.Equal (0, view.OnAcceptedCount);
|
Assert.Equal (0, view.OnAcceptedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/gui-cs/Terminal.Gui/issues/3913
|
||||||
|
[Fact]
|
||||||
|
public void Button_IsDefault_Raises_Accepted_Correctly ()
|
||||||
|
{
|
||||||
|
int A_AcceptedCount = 0;
|
||||||
|
bool A_CancelAccepting = false;
|
||||||
|
|
||||||
|
int B_AcceptedCount = 0;
|
||||||
|
bool B_CancelAccepting = false;
|
||||||
|
|
||||||
|
var w = new Window ()
|
||||||
|
{
|
||||||
|
BorderStyle = LineStyle.None,
|
||||||
|
Width = 10,
|
||||||
|
Height = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
var btnA = new Button ()
|
||||||
|
{
|
||||||
|
Width = 3,
|
||||||
|
IsDefault = true
|
||||||
|
};
|
||||||
|
btnA.Accepting += (s, e) =>
|
||||||
|
{
|
||||||
|
A_AcceptedCount++;
|
||||||
|
e.Cancel = A_CancelAccepting;
|
||||||
|
};
|
||||||
|
|
||||||
|
var btnB = new Button ()
|
||||||
|
{
|
||||||
|
Width = 3,
|
||||||
|
X = Pos.Right (btnA)
|
||||||
|
};
|
||||||
|
|
||||||
|
btnB.Accepting += (s, e) =>
|
||||||
|
{
|
||||||
|
B_AcceptedCount++;
|
||||||
|
e.Cancel = B_CancelAccepting;
|
||||||
|
};
|
||||||
|
w.Add (btnA, btnB);
|
||||||
|
|
||||||
|
w.LayoutSubviews ();
|
||||||
|
|
||||||
|
Application.Begin (w);
|
||||||
|
Assert.Same (Application.Top, w);
|
||||||
|
|
||||||
|
// Click button 2
|
||||||
|
var btn2Frame = btnB.FrameToScreen ();
|
||||||
|
|
||||||
|
Application.RaiseMouseEvent (
|
||||||
|
new MouseEventArgs ()
|
||||||
|
{
|
||||||
|
ScreenPosition = btn2Frame.Location,
|
||||||
|
Flags = MouseFlags.Button1Clicked
|
||||||
|
});
|
||||||
|
|
||||||
|
// Button A should have been accepted because B didn't cancel and A IsDefault
|
||||||
|
Assert.Equal (1, A_AcceptedCount);
|
||||||
|
Assert.Equal (1, B_AcceptedCount);
|
||||||
|
|
||||||
|
B_CancelAccepting = true;
|
||||||
|
Application.RaiseMouseEvent (
|
||||||
|
new MouseEventArgs ()
|
||||||
|
{
|
||||||
|
ScreenPosition = btn2Frame.Location,
|
||||||
|
Flags = MouseFlags.Button1Clicked
|
||||||
|
});
|
||||||
|
|
||||||
|
// Button A (IsDefault) should NOT have been accepted because B canceled
|
||||||
|
Assert.Equal (1, A_AcceptedCount);
|
||||||
|
Assert.Equal (2, B_AcceptedCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See: https://github.com/gui-cs/Terminal.Gui/issues/3905
|
||||||
|
[Fact]
|
||||||
|
public void Button_CanFocus_False_Raises_Accepted_Correctly ()
|
||||||
|
{
|
||||||
|
int wAcceptedCount = 0;
|
||||||
|
bool wCancelAccepting = false;
|
||||||
|
var w = new Window ()
|
||||||
|
{
|
||||||
|
Title = "Window",
|
||||||
|
BorderStyle = LineStyle.None,
|
||||||
|
Width = 10,
|
||||||
|
Height = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
w.Accepting += (s, e) =>
|
||||||
|
{
|
||||||
|
wAcceptedCount++;
|
||||||
|
e.Cancel = wCancelAccepting;
|
||||||
|
};
|
||||||
|
|
||||||
|
int btnAcceptedCount = 0;
|
||||||
|
bool btnCancelAccepting = false;
|
||||||
|
var btn = new Button ()
|
||||||
|
{
|
||||||
|
Title = "Button",
|
||||||
|
Width = 3,
|
||||||
|
IsDefault = true,
|
||||||
|
};
|
||||||
|
btn.CanFocus = true;
|
||||||
|
|
||||||
|
btn.Accepting += (s, e) =>
|
||||||
|
{
|
||||||
|
btnAcceptedCount++;
|
||||||
|
e.Cancel = btnCancelAccepting;
|
||||||
|
};
|
||||||
|
|
||||||
|
w.Add (btn);
|
||||||
|
|
||||||
|
w.LayoutSubviews ();
|
||||||
|
|
||||||
|
Application.Begin (w);
|
||||||
|
|
||||||
|
// Click button just like a driver would
|
||||||
|
var btnFrame = btn.FrameToScreen ();
|
||||||
|
Application.RaiseMouseEvent (
|
||||||
|
new MouseEventArgs ()
|
||||||
|
{
|
||||||
|
ScreenPosition = btnFrame.Location,
|
||||||
|
Flags = MouseFlags.Button1Pressed
|
||||||
|
});
|
||||||
|
|
||||||
|
Application.RaiseMouseEvent (
|
||||||
|
new MouseEventArgs ()
|
||||||
|
{
|
||||||
|
ScreenPosition = btnFrame.Location,
|
||||||
|
Flags = MouseFlags.Button1Released
|
||||||
|
});
|
||||||
|
|
||||||
|
Application.RaiseMouseEvent (
|
||||||
|
new MouseEventArgs ()
|
||||||
|
{
|
||||||
|
ScreenPosition = btnFrame.Location,
|
||||||
|
Flags = MouseFlags.Button1Clicked
|
||||||
|
});
|
||||||
|
|
||||||
|
Assert.Equal (1, btnAcceptedCount);
|
||||||
|
Assert.Equal (2, wAcceptedCount);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion OnAccept/Accept tests
|
#endregion OnAccept/Accept tests
|
||||||
|
|
||||||
#region OnSelect/Select tests
|
#region OnSelect/Select tests
|
||||||
@@ -140,7 +282,7 @@ public class ViewCommandTests
|
|||||||
Assert.Equal (canFocus, view.CanFocus);
|
Assert.Equal (canFocus, view.CanFocus);
|
||||||
Assert.False (view.HasFocus);
|
Assert.False (view.HasFocus);
|
||||||
|
|
||||||
Assert.Equal (canFocus, view.InvokeCommand (Command.Select));
|
view.InvokeCommand (Command.Select);
|
||||||
|
|
||||||
Assert.Equal (1, view.OnSelectingCount);
|
Assert.Equal (1, view.OnSelectingCount);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace Terminal.Gui.ViewsTests;
|
namespace Terminal.Gui.ViewsTests;
|
||||||
@@ -30,11 +31,13 @@ public class LabelTests (ITestOutputHelper output)
|
|||||||
Assert.Equal ("Hello", label.TitleTextFormatter.Text);
|
Assert.Equal ("Hello", label.TitleTextFormatter.Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void HotKey_Command_SetsFocus_OnNextSubview ()
|
[CombinatorialData]
|
||||||
|
public void HotKey_Command_SetsFocus_OnNextSubview (bool hasHotKey)
|
||||||
{
|
{
|
||||||
var superView = new View { CanFocus = true };
|
var superView = new View { CanFocus = true };
|
||||||
var label = new Label ();
|
var label = new Label ();
|
||||||
|
label.HotKey = hasHotKey ? Key.A.WithAlt : Key.Empty;
|
||||||
var nextSubview = new View { CanFocus = true };
|
var nextSubview = new View { CanFocus = true };
|
||||||
superView.Add (label, nextSubview);
|
superView.Add (label, nextSubview);
|
||||||
superView.BeginInit ();
|
superView.BeginInit ();
|
||||||
@@ -45,15 +48,18 @@ public class LabelTests (ITestOutputHelper output)
|
|||||||
|
|
||||||
label.InvokeCommand (Command.HotKey);
|
label.InvokeCommand (Command.HotKey);
|
||||||
Assert.False (label.HasFocus);
|
Assert.False (label.HasFocus);
|
||||||
Assert.True (nextSubview.HasFocus);
|
Assert.Equal (hasHotKey, nextSubview.HasFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void MouseClick_SetsFocus_OnNextSubview ()
|
[CombinatorialData]
|
||||||
|
public void MouseClick_SetsFocus_OnNextSubview (bool hasHotKey)
|
||||||
{
|
{
|
||||||
var superView = new View { CanFocus = true, Height = 1, Width = 15 };
|
var superView = new View { CanFocus = true, Height = 1, Width = 15 };
|
||||||
var focusedView = new View { CanFocus = true, Width = 1, Height = 1 };
|
var focusedView = new View { CanFocus = true, Width = 1, Height = 1 };
|
||||||
var label = new Label { X = 2, Title = "_x" };
|
var label = new Label { X = 2 };
|
||||||
|
label.HotKey = hasHotKey ? Key.X.WithAlt : Key.Empty;
|
||||||
|
|
||||||
var nextSubview = new View { CanFocus = true, X = 4, Width = 4, Height = 1 };
|
var nextSubview = new View { CanFocus = true, X = 4, Width = 4, Height = 1 };
|
||||||
superView.Add (focusedView, label, nextSubview);
|
superView.Add (focusedView, label, nextSubview);
|
||||||
superView.BeginInit ();
|
superView.BeginInit ();
|
||||||
@@ -65,7 +71,7 @@ public class LabelTests (ITestOutputHelper output)
|
|||||||
|
|
||||||
label.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked });
|
label.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1Clicked });
|
||||||
Assert.False (label.HasFocus);
|
Assert.False (label.HasFocus);
|
||||||
Assert.True (nextSubview.HasFocus);
|
Assert.Equal (hasHotKey, nextSubview.HasFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user