diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs
index 8fb9a2156..1d66b853d 100644
--- a/Terminal.Gui/Views/StatusBar.cs
+++ b/Terminal.Gui/Views/StatusBar.cs
@@ -27,11 +27,13 @@ namespace Terminal.Gui {
/// Shortcut to activate the .
/// Title for the .
/// Action to invoke when the is activated.
- public StatusItem (Key shortcut, string title, Action action)
+ /// Function to determine if the action can currently be executed.
+ public StatusItem (Key shortcut, string title, Action action, Func canExecute = null)
{
Title = title ?? "";
Shortcut = shortcut;
Action = action;
+ CanExecute = canExecute;
}
///
@@ -54,7 +56,22 @@ namespace Terminal.Gui {
/// Gets or sets the action to be invoked when the statusbar item is triggered
///
/// Action to invoke.
- public Action Action { get; }
+ public Action Action { get; set; }
+
+ ///
+ /// Gets or sets the action to be invoked to determine if the can be triggered.
+ /// If returns the status item will be enabled. Otherwise, it will be disabled.
+ ///
+ /// Function to determine if the action is can be executed or not.
+ public Func CanExecute { get; set; }
+
+ ///
+ /// Returns if the status item is enabled. This method is a wrapper around .
+ ///
+ public bool IsEnabled ()
+ {
+ return CanExecute == null ? true : CanExecute ();
+ }
///
/// 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 ();
+ }
+
///
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;
diff --git a/UnitTests/Views/StatusBarTests.cs b/UnitTests/Views/StatusBarTests.cs
index 06ef9d597..d2e81ead1 100644
--- a/UnitTests/Views/StatusBarTests.cs
+++ b/UnitTests/Views/StatusBarTests.cs
@@ -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 ());
+ }
}
}