| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- namespace Terminal.Gui.Views;
- /// <summary>
- /// A status bar is a <see cref="View"/> that snaps to the bottom of a <see cref="Toplevel"/> displaying set of
- /// <see cref="Shortcut"/>s. The <see cref="StatusBar"/> 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.
- /// </summary>
- public class StatusBar : Bar, IDesignable
- {
- private static LineStyle _defaultSeparatorLineStyle = LineStyle.Single; // Resources/config.json overrides
- /// <inheritdoc/>
- public StatusBar () : this ([]) { }
- /// <inheritdoc/>
- public StatusBar (IEnumerable<Shortcut> 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;
- }
- }
- /// <summary>
- /// Gets or sets the default Line Style for the separators between the shortcuts of the StatusBar.
- /// </summary>
- [ConfigurationProperty (Scope = typeof (ThemeScope))]
- public static LineStyle DefaultSeparatorLineStyle
- {
- get => _defaultSeparatorLineStyle;
- set => _defaultSeparatorLineStyle = value;
- }
- /// <inheritdoc />
- 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);
- }
- /// <inheritdoc/>
- 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;
- }
- }
- /// <inheritdoc />
- 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}"); }
- }
- /// <inheritdoc />
- protected override void Dispose (bool disposing)
- {
- base.Dispose (disposing);
- SuperViewChanged -= OnSuperViewChanged;
- ConfigurationManager.Applied -= OnConfigurationManagerApplied;
- }
- }
|