mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Merge pull request #2843 from BDisp/v2_statusitem-can-execute-fix_2789
Fixes #2789. StatusItem should have a disabled attribute if it can't execute.
This commit is contained in:
@@ -27,11 +27,13 @@ namespace Terminal.Gui {
|
||||
/// <param name="shortcut">Shortcut to activate the <see cref="StatusItem"/>.</param>
|
||||
/// <param name="title">Title for the <see cref="StatusItem"/>.</param>
|
||||
/// <param name="action">Action to invoke when the <see cref="StatusItem"/> is activated.</param>
|
||||
public StatusItem (Key shortcut, string title, Action action)
|
||||
/// <param name="canExecute">Function to determine if the action can currently be executed.</param>
|
||||
public StatusItem (Key shortcut, string title, Action action, Func<bool> canExecute = null)
|
||||
{
|
||||
Title = title ?? "";
|
||||
Shortcut = shortcut;
|
||||
Action = action;
|
||||
CanExecute = canExecute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -54,7 +56,22 @@ namespace Terminal.Gui {
|
||||
/// Gets or sets the action to be invoked when the statusbar item is triggered
|
||||
/// </summary>
|
||||
/// <value>Action to invoke.</value>
|
||||
public Action Action { get; }
|
||||
public Action Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the action to be invoked to determine if the <see cref="StatusItem"/> can be triggered.
|
||||
/// If <see cref="CanExecute"/> returns <see langword="true"/> the status item will be enabled. Otherwise, it will be disabled.
|
||||
/// </summary>
|
||||
/// <value>Function to determine if the action is can be executed or not.</value>
|
||||
public Func<bool> CanExecute { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns <see langword="true"/> if the status item is enabled. This method is a wrapper around <see cref="CanExecute"/>.
|
||||
/// </summary>
|
||||
public bool IsEnabled ()
|
||||
{
|
||||
return CanExecute == null ? true : CanExecute ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets arbitrary data for the status item.
|
||||
@@ -116,6 +133,17 @@ namespace Terminal.Gui {
|
||||
return result;
|
||||
}
|
||||
|
||||
Attribute DetermineColorSchemeFor (StatusItem item)
|
||||
{
|
||||
if (item != null) {
|
||||
if (item.IsEnabled ()) {
|
||||
return GetNormalColor ();
|
||||
}
|
||||
return ColorScheme.Disabled;
|
||||
}
|
||||
return GetNormalColor ();
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void OnDrawContent (Rect contentArea)
|
||||
{
|
||||
@@ -130,9 +158,12 @@ namespace Terminal.Gui {
|
||||
Driver.SetAttribute (scheme);
|
||||
for (int i = 0; i < Items.Length; i++) {
|
||||
var title = Items [i].Title;
|
||||
Driver.SetAttribute (DetermineColorSchemeFor (Items [i]));
|
||||
for (int n = 0; n < Items [i].Title.GetRuneCount (); n++) {
|
||||
if (title [n] == '~') {
|
||||
scheme = ToggleScheme (scheme);
|
||||
if (Items [i].IsEnabled ()) {
|
||||
scheme = ToggleScheme (scheme);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Driver.AddRune ((Rune)title [n]);
|
||||
@@ -150,7 +181,9 @@ namespace Terminal.Gui {
|
||||
{
|
||||
foreach (var item in Items) {
|
||||
if (kb.Key == item.Shortcut) {
|
||||
Run (item.Action);
|
||||
if (item.IsEnabled ()) {
|
||||
Run (item.Action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +199,10 @@ namespace Terminal.Gui {
|
||||
int pos = 1;
|
||||
for (int i = 0; i < Items.Length; i++) {
|
||||
if (me.X >= pos && me.X < pos + GetItemTitleLength (Items [i].Title)) {
|
||||
Run (Items [i].Action);
|
||||
var item = Items [i];
|
||||
if (item.IsEnabled ()) {
|
||||
Run (item.Action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
pos += GetItemTitleLength (Items [i].Title) + 3;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Terminal.Gui.ViewsTests {
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StatusBar_Contructor_Default ()
|
||||
public void StatusBar_Constructor_Default ()
|
||||
{
|
||||
var sb = new StatusBar ();
|
||||
|
||||
@@ -160,5 +160,43 @@ CTRL-O Open {CM.Glyphs.VLine} CTRL-Q Quit
|
||||
Assert.Equal ("~^A~ Save As", sb.Items [1].Title);
|
||||
Assert.Equal ("~^Q~ Quit", sb.Items [^1].Title);
|
||||
}
|
||||
|
||||
[Fact, AutoInitShutdown]
|
||||
public void CanExecute_ProcessHotKey ()
|
||||
{
|
||||
Window win = null;
|
||||
var statusBar = new StatusBar (new StatusItem [] {
|
||||
new StatusItem (Key.CtrlMask | Key.N, "~^N~ New", New, CanExecuteNew),
|
||||
new StatusItem (Key.CtrlMask | Key.C, "~^C~ Close", Close, CanExecuteClose)
|
||||
});
|
||||
var top = Application.Top;
|
||||
top.Add (statusBar);
|
||||
|
||||
bool CanExecuteNew () => win == null;
|
||||
|
||||
void New ()
|
||||
{
|
||||
win = new Window ();
|
||||
}
|
||||
|
||||
bool CanExecuteClose () => win != null;
|
||||
|
||||
void Close ()
|
||||
{
|
||||
win = null;
|
||||
}
|
||||
|
||||
Application.Begin (top);
|
||||
|
||||
Assert.Null (win);
|
||||
Assert.True (CanExecuteNew ());
|
||||
Assert.False (CanExecuteClose ());
|
||||
|
||||
Assert.True (top.ProcessHotKey (new KeyEvent (Key.N | Key.CtrlMask, new KeyModifiers () { Alt = true })));
|
||||
Application.MainLoop.RunIteration ();
|
||||
Assert.NotNull (win);
|
||||
Assert.False (CanExecuteNew ());
|
||||
Assert.True (CanExecuteClose ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user