StatusBar.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using System;
  2. using System.Reflection;
  3. namespace Terminal.Gui;
  4. /// <summary>
  5. /// A status bar is a <see cref="View"/> that snaps to the bottom of a <see cref="Toplevel"/> displaying set of
  6. /// <see cref="Shortcut"/>s. The <see cref="StatusBar"/> should be context sensitive. This means, if the main menu
  7. /// and an open text editor are visible, the items probably shown will be ~F1~ Help ~F2~ Save ~F3~ Load. While a dialog
  8. /// to ask a file to load is executed, the remaining commands will probably be ~F1~ Help. So for each context must be a
  9. /// new instance of a status bar.
  10. /// </summary>
  11. public class StatusBar : Bar, IDesignable
  12. {
  13. /// <inheritdoc/>
  14. public StatusBar () : this ([]) { }
  15. /// <inheritdoc/>
  16. public StatusBar (IEnumerable<Shortcut> shortcuts) : base (shortcuts)
  17. {
  18. Orientation = Orientation.Horizontal;
  19. Y = Pos.AnchorEnd ();
  20. Width = Dim.Fill ();
  21. Height = Dim.Auto (DimAutoStyle.Content, 1);
  22. BorderStyle = LineStyle.Dashed;
  23. ColorScheme = Colors.ColorSchemes ["Menu"];
  24. LayoutStarted += StatusBar_LayoutStarted;
  25. }
  26. // StatusBar arranges the items horizontally.
  27. // The first item has no left border, the last item has no right border.
  28. // The Shortcuts are configured with the command, help, and key views aligned in reverse order (EndToStart).
  29. private void StatusBar_LayoutStarted (object sender, LayoutEventArgs e)
  30. {
  31. for (int index = 0; index < Subviews.Count; index++)
  32. {
  33. View barItem = Subviews [index];
  34. barItem.BorderStyle = BorderStyle;
  35. if (index == Subviews.Count - 1)
  36. {
  37. barItem.Border.Thickness = new Thickness (0, 0, 0, 0);
  38. }
  39. else
  40. {
  41. barItem.Border.Thickness = new Thickness (0, 0, 1, 0);
  42. }
  43. if (barItem is Shortcut shortcut)
  44. {
  45. shortcut.Orientation = Orientation.Horizontal;
  46. }
  47. }
  48. }
  49. /// <inheritdoc/>
  50. public override View Add (View view)
  51. {
  52. // Call base first, because otherwise it resets CanFocus to true
  53. base.Add (view);
  54. view.CanFocus = false;
  55. if (view is Shortcut shortcut)
  56. {
  57. shortcut.KeyBindingScope = KeyBindingScope.Application;
  58. // TODO: not happy about using AlignmentModes for this. Too implied.
  59. // TODO: instead, add a property (a style enum?) to Shortcut to control this
  60. shortcut.AlignmentModes = AlignmentModes.EndToStart;
  61. }
  62. return view;
  63. }
  64. /// <inheritdoc />
  65. bool IDesignable.EnableForDesign ()
  66. {
  67. var shortcut = new Shortcut
  68. {
  69. Text = "Quit",
  70. Title = "Q_uit",
  71. Key = Key.Z.WithCtrl,
  72. };
  73. Add (shortcut);
  74. shortcut = new Shortcut
  75. {
  76. Text = "Help Text",
  77. Title = "Help",
  78. Key = Key.F1,
  79. };
  80. Add (shortcut);
  81. shortcut = new Shortcut
  82. {
  83. Title = "_Show/Hide",
  84. Key = Key.F10,
  85. CommandView = new CheckBox
  86. {
  87. CanFocus = false,
  88. Text = "_Show/Hide"
  89. },
  90. };
  91. Add (shortcut);
  92. var button1 = new Button
  93. {
  94. Text = "I'll Hide",
  95. // Visible = false
  96. };
  97. button1.Accept += Button_Clicked;
  98. Add (button1);
  99. shortcut.Accept += (s, e) =>
  100. {
  101. button1.Visible = !button1.Visible;
  102. button1.Enabled = button1.Visible;
  103. e.Handled = false;
  104. };
  105. Add (new Label
  106. {
  107. HotKeySpecifier = new Rune ('_'),
  108. Text = "Fo_cusLabel",
  109. CanFocus = true
  110. });
  111. var button2 = new Button
  112. {
  113. Text = "Or me!",
  114. };
  115. button2.Accept += (s, e) => Application.RequestStop ();
  116. Add (button2);
  117. return true;
  118. void Button_Clicked (object sender, EventArgs e) { MessageBox.Query ("Hi", $"You clicked {sender}"); }
  119. }
  120. }