StatusBar.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. TabStop = TabBehavior.NoStop;
  19. Orientation = Orientation.Horizontal;
  20. Y = Pos.AnchorEnd ();
  21. Width = Dim.Fill ();
  22. Height = Dim.Auto (DimAutoStyle.Content, 1);
  23. BorderStyle = LineStyle.Dashed;
  24. ColorScheme = Colors.ColorSchemes ["Menu"];
  25. SubviewLayout += StatusBar_LayoutStarted;
  26. }
  27. // StatusBar arranges the items horizontally.
  28. // The first item has no left border, the last item has no right border.
  29. // The Shortcuts are configured with the command, help, and key views aligned in reverse order (EndToStart).
  30. private void StatusBar_LayoutStarted (object sender, LayoutEventArgs e)
  31. {
  32. for (int index = 0; index < Subviews.Count; index++)
  33. {
  34. View barItem = Subviews [index];
  35. barItem.BorderStyle = BorderStyle;
  36. if (index == Subviews.Count - 1)
  37. {
  38. barItem.Border.Thickness = new Thickness (0, 0, 0, 0);
  39. }
  40. else
  41. {
  42. barItem.Border.Thickness = new Thickness (0, 0, 1, 0);
  43. }
  44. if (barItem is Shortcut shortcut)
  45. {
  46. shortcut.Orientation = Orientation.Horizontal;
  47. }
  48. }
  49. }
  50. /// <inheritdoc/>
  51. public override View Add (View view)
  52. {
  53. // Call base first, because otherwise it resets CanFocus to true
  54. base.Add (view);
  55. view.CanFocus = false;
  56. if (view is Shortcut shortcut)
  57. {
  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.Accepting += Button_Clicked;
  98. Add (button1);
  99. shortcut.Accepting += (s, e) =>
  100. {
  101. button1.Visible = !button1.Visible;
  102. button1.Enabled = button1.Visible;
  103. e.Cancel = 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.Accepting += (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. }