Label.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. }
  28. private void Label_TitleChanged (object? sender, EventArgs<string> e)
  29. {
  30. base.Text = e.Value;
  31. TextFormatter.HotKeySpecifier = HotKeySpecifier;
  32. }
  33. /// <inheritdoc/>
  34. public override string Text
  35. {
  36. get => Title;
  37. set => base.Text = Title = value;
  38. }
  39. /// <inheritdoc/>
  40. public override Rune HotKeySpecifier
  41. {
  42. get => base.HotKeySpecifier;
  43. set => TextFormatter.HotKeySpecifier = base.HotKeySpecifier = value;
  44. }
  45. private bool? InvokeHotKeyOnNextPeer (ICommandContext commandContext)
  46. {
  47. if (RaiseHandlingHotKey (commandContext) == true)
  48. {
  49. return true;
  50. }
  51. if (CanFocus)
  52. {
  53. SetFocus ();
  54. // Always return true on hotkey, even if SetFocus fails because
  55. // hotkeys are always handled by the View (unless RaiseHandlingHotKey cancels).
  56. // This is the same behavior as the base (View).
  57. return true;
  58. }
  59. if (HotKey.IsValid)
  60. {
  61. // If the Label has a hotkey, we need to find the next view in the subview list
  62. int me = SuperView?.SubViews.IndexOf (this) ?? -1;
  63. if (me != -1 && me < SuperView?.SubViews.Count - 1)
  64. {
  65. return SuperView?.SubViews.ElementAt (me + 1).InvokeCommand (Command.HotKey) == true;
  66. }
  67. }
  68. return false;
  69. }
  70. /// <inheritdoc/>
  71. protected override bool OnSelecting (CommandEventArgs args)
  72. {
  73. // If Label can't focus and is clicked, invoke HotKey on next peer
  74. if (!CanFocus)
  75. {
  76. return InvokeCommand (Command.HotKey, args.Context) == true;
  77. }
  78. return base.OnSelecting (args);
  79. }
  80. /// <inheritdoc/>
  81. bool IDesignable.EnableForDesign ()
  82. {
  83. Text = "_Label";
  84. return true;
  85. }
  86. }