Fixes #4320 - Dialog focus (#4321)

* Fixes #4320 - Dialog and MessageBox rendering of Text should ignore HasFocus

Refactor and enhance text drawing logic

Refactored `DoDrawText` in `View.Drawing.cs` to improve efficiency by adding early exits for unnecessary operations and introducing extensibility points (`OnDrawingText`, `OnDrewText`, and `DrewText` event). Simplified `DrawText` by delegating logic to `DoDrawText`.

Added `OnDrewText` and `DrewText` event to allow custom post-draw handling. Updated `Dialog` class to ensure consistent text rendering using the `Normal` attribute and cleaned up event handling logic.

* Update Terminal.Gui/ViewBase/View.Drawing.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Refactor Dialog text rendering logic

Refactored the `Dialog` class to improve text rendering behavior:
- Introduced `_drawingText` flag to track text drawing state.
- Updated `OnDrawingText` to set `_drawingText` to `true`.
- Updated `OnDrewText` to reset `_drawingText` to `false`.
- Replaced `GettingAttributeForRoleHandler` with `OnGettingAttributeForRole`.
  - Ensures `VisualRole.Focus` uses the normal scheme attribute when drawing text.
- Removed unused event handler `GettingAttributeForRoleHandler`.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Tig
2025-10-25 06:58:20 -06:00
committed by GitHub
parent 4437398508
commit db5fdebfa9
2 changed files with 51 additions and 10 deletions

View File

@@ -377,6 +377,16 @@ public partial class View // Drawing APIs
private void DoDrawText (DrawContext? context = null) private void DoDrawText (DrawContext? context = null)
{ {
if (!NeedsDraw)
{
return;
}
if (!string.IsNullOrEmpty (TextFormatter.Text))
{
TextFormatter.NeedsFormat = true;
}
if (OnDrawingText (context)) if (OnDrawingText (context))
{ {
return; return;
@@ -397,6 +407,9 @@ public partial class View // Drawing APIs
} }
DrawText (context); DrawText (context);
OnDrewText();
DrewText?.Invoke(this, EventArgs.Empty);
} }
/// <summary> /// <summary>
@@ -425,11 +438,6 @@ public partial class View // Drawing APIs
/// <param name="context">The draw context to report drawn areas to.</param> /// <param name="context">The draw context to report drawn areas to.</param>
public void DrawText (DrawContext? context = null) public void DrawText (DrawContext? context = null)
{ {
if (!string.IsNullOrEmpty (TextFormatter.Text))
{
TextFormatter.NeedsFormat = true;
}
var drawRect = new Rectangle (ContentToScreen (Point.Empty), GetContentSize ()); var drawRect = new Rectangle (ContentToScreen (Point.Empty), GetContentSize ());
// Use GetDrawRegion to get precise drawn areas // Use GetDrawRegion to get precise drawn areas
@@ -438,11 +446,6 @@ public partial class View // Drawing APIs
// Report the drawn area to the context // Report the drawn area to the context
context?.AddDrawnRegion (textRegion); context?.AddDrawnRegion (textRegion);
if (!NeedsDraw)
{
return;
}
TextFormatter?.Draw ( TextFormatter?.Draw (
drawRect, drawRect,
HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal), HasFocus ? GetAttributeForRole (VisualRole.Focus) : GetAttributeForRole (VisualRole.Normal),
@@ -454,6 +457,14 @@ public partial class View // Drawing APIs
SetSubViewNeedsDraw (); SetSubViewNeedsDraw ();
} }
/// <summary>
/// Called when the <see cref="Text"/> of the View has been drawn.
/// </summary>
protected virtual void OnDrewText () { }
/// <summary>Raised when the <see cref="Text"/> of the View has been drawn.</summary>
public event EventHandler? DrewText;
#endregion DrawText #endregion DrawText
#region DrawContent #region DrawContent

View File

@@ -138,4 +138,34 @@ public class Dialog : Window
/// </summary> /// </summary>
[ConfigurationProperty (Scope = typeof (ThemeScope))] [ConfigurationProperty (Scope = typeof (ThemeScope))]
public new static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.Transparent; public new static ShadowStyle DefaultShadow { get; set; } = ShadowStyle.Transparent;
// Dialogs are Modal and Focus is indicated by their Border. The following code ensures the
// Text of the dialog (e.g. for a MessageBox) is always drawn using the Normal Attribute.
private bool _drawingText;
/// <inheritdoc/>
protected override bool OnDrawingText ()
{
_drawingText = true;
return false;
}
/// <inheritdoc/>
protected override void OnDrewText ()
{
_drawingText = false;
}
/// <inheritdoc />
protected override bool OnGettingAttributeForRole (in VisualRole role, ref Attribute currentAttribute)
{
if (_drawingText && role is VisualRole.Focus && Border?.Thickness != Thickness.Empty)
{
currentAttribute = GetScheme ().Normal;
return true;
}
return false;
}
} }