View.Drawing.Attribute.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #nullable enable
  2. using System.ComponentModel;
  3. namespace Terminal.Gui.ViewBase;
  4. public partial class View
  5. {
  6. #region Get
  7. /// <summary>Gets the current <see cref="System.Attribute"/> used by <see cref="AddRune(System.Text.Rune)"/>.</summary>
  8. /// <returns>The current attribute.</returns>
  9. public Attribute GetCurrentAttribute () { return Driver?.GetAttribute () ?? Attribute.Default; }
  10. /// <summary>
  11. /// Gets the <see cref="Attribute"/> associated with a specified <see cref="Drawing.VisualRole"/>
  12. /// from the <see cref="Drawing.Scheme"/>.
  13. /// <para>
  14. /// Raises <see cref="OnGettingAttributeForRole"/>/<see cref="GettingAttributeForRole"/>
  15. /// which can cancel the default behavior, and optionally change the attribute in the event args.
  16. /// </para>
  17. /// <para>
  18. /// If <see cref="Enabled"/> is <see langword="false"/>, <see cref="Drawing.VisualRole.Disabled"/>
  19. /// will be used instead of <paramref name="role"></paramref>.
  20. /// To override this behavior use <see cref="OnGettingAttributeForRole"/>/<see cref="GettingAttributeForRole"/>
  21. /// to cancel the method, and return a different attribute.
  22. /// </para>
  23. /// <para>
  24. /// If <see cref="HighlightStyle"/> is not <see cref="HighlightStyle.None"/> and <see cref="MouseHovering"/> is <see langword="true"/>,
  25. /// the <see cref="Drawing.VisualRole.Highlight"/> will be used instead of <paramref name="role"/>.
  26. /// To override this behavior use <see cref="OnGettingAttributeForRole"/>/<see cref="GettingAttributeForRole"/>
  27. /// to cancel the method, and return a different attribute.
  28. /// </para>
  29. /// </summary>
  30. /// <param name="role">The semantic <see cref="Drawing.VisualRole"/> describing the element being rendered.</param>
  31. /// <returns>The corresponding <see cref="Attribute"/> from the <see cref="Drawing.Scheme"/>.</returns>
  32. public Attribute GetAttributeForRole (VisualRole role)
  33. {
  34. Attribute schemeAttribute = GetScheme ()!.GetAttributeForRole (role);
  35. if (OnGettingAttributeForRole (role, ref schemeAttribute))
  36. {
  37. // The implementation may have changed the attribute
  38. return schemeAttribute;
  39. }
  40. VisualRoleEventArgs args = new (role, newValue: ref schemeAttribute, currentValue: ref schemeAttribute);
  41. GettingAttributeForRole?.Invoke (this, args);
  42. if (args.Cancel)
  43. {
  44. // A handler may have changed the attribute
  45. return args.NewValue;
  46. }
  47. if (HighlightStyle != HighlightStyle.None)
  48. {
  49. if (MouseHovering && HighlightStyle.HasFlag (HighlightStyle.Hover) && role != VisualRole.Highlight && role != VisualRole.Disabled)
  50. {
  51. schemeAttribute = GetAttributeForRole (VisualRole.Highlight);
  52. }
  53. }
  54. return Enabled || role == VisualRole.Disabled ? schemeAttribute : GetAttributeForRole (VisualRole.Disabled);
  55. }
  56. /// <summary>
  57. /// Called when the Attribute for a <see cref="GetAttributeForRole(VisualRole)"/> is being retrieved.
  58. /// Implementations can
  59. /// return <see langword="true"/> to stop further processing and optionally set the <see cref="Attribute"/> in the
  60. /// event args to a different value.
  61. /// </summary>
  62. /// <param name="role"></param>
  63. /// <param name="currentAttribute">The current value of the Attribute for the VisualRole. This by-ref value can be changed</param>
  64. /// <returns></returns>
  65. protected virtual bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute) { return false; }
  66. /// <summary>
  67. /// Raised when the Attribute for a <see cref="GetAttributeForRole(VisualRole)"/> is being retrieved.
  68. /// Handlers should check if <see cref="CancelEventArgs.Cancel"/>
  69. /// has been set to <see langword="true"/> and do nothing if so. If Cancel is <see langword="false"/>
  70. /// a handler can set it to <see langword="true"/> to stop further processing optionally change the
  71. /// `CurrentValue` in the event args to a different value.
  72. /// </summary>
  73. public event EventHandler<VisualRoleEventArgs>? GettingAttributeForRole;
  74. #endregion Get
  75. #region Set
  76. /// <summary>
  77. /// Selects the specified Attribute
  78. /// as the Attribute to use for subsequent calls to <see cref="AddRune(System.Text.Rune)"/> and <see cref="AddStr"/>.
  79. /// </summary>
  80. /// <param name="attribute">THe Attribute to set.</param>
  81. /// <returns>The previously set Attribute.</returns>
  82. public Attribute SetAttribute (Attribute attribute) { return Driver?.SetAttribute (attribute) ?? Attribute.Default; }
  83. /// <summary>
  84. /// Selects the Attribute associated with the specified <see cref="VisualRole"/>
  85. /// as the Attribute to use for subsequent calls to <see cref="AddRune(System.Text.Rune)"/> and <see cref="AddStr"/>.
  86. /// <para>
  87. /// Calls <see cref="GetAttributeForRole"/> to get the Attribute associated with the specified role, which will
  88. /// raise <see cref="OnGettingAttributeForRole"/>/<see cref="GettingAttributeForRole"/>.
  89. /// </para>
  90. /// </summary>
  91. /// <param name="role">The semantic <see cref="VisualRole"/> describing the element being rendered.</param>
  92. /// <returns>The previously set Attribute.</returns>
  93. public Attribute? SetAttributeForRole (VisualRole role)
  94. {
  95. Attribute schemeAttribute = GetAttributeForRole (role);
  96. Attribute currentAttribute = GetCurrentAttribute ();
  97. return SetAttribute (schemeAttribute);
  98. }
  99. #endregion Set
  100. }