Label.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. namespace Terminal.Gui.Views;
  2. /// <summary>
  3. /// Displays text that describes the View next in the <see cref="View.SubViews"/>. When
  4. /// the user presses a hotkey that matches the <see cref="View.HotKey"/> of the Label, the next <see cref="View"/> in
  5. /// <see cref="View.SubViews"/> will be activated.
  6. /// </summary>
  7. /// <remarks>
  8. /// <para>
  9. /// Title and Text are the same property. When Title is set Text s also set. When Text is set Title is also set.
  10. /// </para>
  11. /// <para>
  12. /// If <see cref="View.CanFocus"/> is <see langword="false"/> and the use clicks on the Label,
  13. /// the <see cref="Command.HotKey"/> will be invoked on the next <see cref="View"/> in
  14. /// <see cref="View.SubViews"/>.
  15. /// </para>
  16. /// </remarks>
  17. public class Label : View, IDesignable
  18. {
  19. /// <inheritdoc/>
  20. public Label ()
  21. {
  22. Height = Dim.Auto (DimAutoStyle.Text);
  23. Width = Dim.Auto (DimAutoStyle.Text);
  24. // On HoKey, pass it to the next view
  25. AddCommand (Command.HotKey, InvokeHotKeyOnNextPeer!);
  26. TitleChanged += Label_TitleChanged;
  27. MouseClick += Label_MouseClick;
  28. }
  29. private void Label_MouseClick (object? sender, MouseEventArgs e)
  30. {
  31. if (!CanFocus)
  32. {
  33. e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new ([Command.HotKey], this, this)) == true;
  34. }
  35. }
  36. private void Label_TitleChanged (object? sender, EventArgs<string> e)
  37. {
  38. base.Text = e.Value;
  39. TextFormatter.HotKeySpecifier = HotKeySpecifier;
  40. }
  41. /// <inheritdoc/>
  42. public override string Text
  43. {
  44. get => Title;
  45. set => base.Text = Title = value;
  46. }
  47. /// <inheritdoc/>
  48. public override Rune HotKeySpecifier
  49. {
  50. get => base.HotKeySpecifier;
  51. set => TextFormatter.HotKeySpecifier = base.HotKeySpecifier = value;
  52. }
  53. private bool? InvokeHotKeyOnNextPeer (ICommandContext commandContext)
  54. {
  55. if (RaiseHandlingHotKey (commandContext) == true)
  56. {
  57. return true;
  58. }
  59. if (CanFocus)
  60. {
  61. SetFocus ();
  62. // Always return true on hotkey, even if SetFocus fails because
  63. // hotkeys are always handled by the View (unless RaiseHandlingHotKey cancels).
  64. // This is the same behavior as the base (View).
  65. return true;
  66. }
  67. if (HotKey.IsValid)
  68. {
  69. // If the Label has a hotkey, we need to find the next view in the subview list
  70. int me = SuperView?.SubViews.IndexOf (this) ?? -1;
  71. if (me != -1 && me < SuperView?.SubViews.Count - 1)
  72. {
  73. return SuperView?.SubViews.ElementAt (me + 1).InvokeCommand (Command.HotKey) == true;
  74. }
  75. }
  76. return false;
  77. }
  78. /// <inheritdoc/>
  79. bool IDesignable.EnableForDesign ()
  80. {
  81. Text = "_Label";
  82. return true;
  83. }
  84. }