namespace Terminal.Gui.Views;
///
/// A status bar is a that snaps to the bottom of a displaying set of
/// s. The should be context sensitive. This means, if the main menu
/// and an open text editor are visible, the items probably shown will be ~F1~ Help ~F2~ Save ~F3~ Load. While a dialog
/// to ask a file to load is executed, the remaining commands will probably be ~F1~ Help. So for each context must be a
/// new instance of a status bar.
///
public class StatusBar : Bar, IDesignable
{
private static LineStyle _defaultSeparatorLineStyle = LineStyle.Single; // Resources/config.json overrides
///
public StatusBar () : this ([]) { }
///
public StatusBar (IEnumerable shortcuts) : base (shortcuts)
{
TabStop = TabBehavior.NoStop;
Orientation = Orientation.Horizontal;
Y = Pos.AnchorEnd ();
Width = Dim.Fill ();
Height = Dim.Auto (DimAutoStyle.Content, 1);
if (Border is { })
{
Border.LineStyle = DefaultSeparatorLineStyle;
}
SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Menu);
ConfigurationManager.Applied += OnConfigurationManagerApplied;
SuperViewChanged += OnSuperViewChanged;
}
private void OnSuperViewChanged (object? sender, SuperViewChangedEventArgs e)
{
if (SuperView is null)
{
// BUGBUG: This is a hack for avoiding a race condition in ConfigurationManager.Apply
// BUGBUG: For some reason in some unit tests, when Top is disposed, MenuBar.Dispose does not get called.
// BUGBUG: Yet, the MenuBar does get Removed from Top (and it's SuperView set to null).
// BUGBUG: Related: https://github.com/gui-cs/Terminal.Gui/issues/4021
ConfigurationManager.Applied -= OnConfigurationManagerApplied;
}
}
private void OnConfigurationManagerApplied (object? sender, ConfigurationManagerEventArgs e)
{
if (Border is { })
{
Border.LineStyle = DefaultSeparatorLineStyle;
}
}
///
/// Gets or sets the default Line Style for the separators between the shortcuts of the StatusBar.
///
[ConfigurationProperty (Scope = typeof (ThemeScope))]
public static LineStyle DefaultSeparatorLineStyle
{
get => _defaultSeparatorLineStyle;
set => _defaultSeparatorLineStyle = value;
}
///
protected override void OnSubViewLayout (LayoutEventArgs args)
{
for (int index = 0; index < SubViews.Count; index++)
{
View barItem = SubViews.ElementAt (index);
barItem.BorderStyle = BorderStyle;
if (barItem.Border is { })
{
barItem.Border!.Thickness = index == SubViews.Count - 1 ? new Thickness (0, 0, 0, 0) : new Thickness (0, 0, 1, 0);
}
if (barItem is Shortcut shortcut)
{
shortcut.Orientation = Orientation.Horizontal;
}
}
base.OnSubViewLayout (args);
}
///
protected override void OnSubViewAdded (View subView)
{
subView.CanFocus = false;
if (subView is Shortcut shortcut)
{
// TODO: not happy about using AlignmentModes for this. Too implied.
// TODO: instead, add a property (a style enum?) to Shortcut to control this
shortcut.AlignmentModes = AlignmentModes.EndToStart;
}
}
///
bool IDesignable.EnableForDesign ()
{
var shortcut = new Shortcut
{
Text = "Quit",
Title = "Q_uit",
Key = Key.Z.WithCtrl,
};
Add (shortcut);
shortcut = new Shortcut
{
Text = "Help Text",
Title = "Help",
Key = Key.F1,
};
Add (shortcut);
shortcut = new Shortcut
{
Title = "_Show/Hide",
Key = Key.F10,
CommandView = new CheckBox
{
CanFocus = false,
Text = "_Show/Hide"
},
};
Add (shortcut);
var button1 = new Button
{
Text = "I'll Hide",
// Visible = false
};
button1.Accepting += OnButtonClicked;
Add (button1);
#pragma warning disable TGUI001
shortcut.Accepting += (_, e) =>
{
button1.Visible = !button1.Visible;
button1.Enabled = button1.Visible;
e.Handled = false;
};
#pragma warning restore TGUI001
Add (new Label
{
HotKeySpecifier = new Rune ('_'),
Text = "Fo_cusLabel",
CanFocus = true
});
var button2 = new Button
{
Text = "Or me!",
};
button2.Accepting += (s, e) => App?.RequestStop ();
Add (button2);
return true;
void OnButtonClicked (object? sender, EventArgs? e) { MessageBox.Query (App, "Hi", $"You clicked {sender}"); }
}
///
protected override void Dispose (bool disposing)
{
base.Dispose (disposing);
SuperViewChanged -= OnSuperViewChanged;
ConfigurationManager.Applied -= OnConfigurationManagerApplied;
}
}