Files
Terminal.Gui/Examples/UICatalog/Scenarios/WideGlyphs.cs
Tig fb1a3e03f3 Fixes some bugs in the Scenario/EditorsAndHelpers and backports WideGlyphs (#4494)
* Fix scenario editors and tweak scenarios.

Enhance ShadowStyles with a second shadow window (transparent style) and a button event handler that shows a message box. In WideGlyphs, add AdornmentsEditor and ViewportSettingsEditor for view property editing, apply custom color schemes to arrangeable views, and update superView with a transparent shadow and increased shadow width. These changes improve interactivity and visualization in the demo scenarios.

* Fix scenario editors and tweak scenarios.

Enhance ShadowStyles with a second shadow window (transparent style) and a button event handler that shows a message box. In WideGlyphs, add AdornmentsEditor and ViewportSettingsEditor for view property editing, apply custom color schemes to arrangeable views, and update superView with a transparent shadow and increased shadow width. These changes improve interactivity and visualization in the demo scenarios.

* Scenario Editors code cleanup & latent bug fixes.

Refactored event handler patterns to use correct sender values and discards for unused parameters, aligning with .NET conventions. Cleaned up code by removing redundant usings and comments, and clarified logic in property setters and switch statements. Enhanced robustness and clarity in editor components, fixing issues with value changes, event subscriptions, and nullability. Improved disposal logic in EditorBase and made minor UI and label adjustments. Added "diag" to the custom dictionary. These changes modernize event handling and address subtle bugs in the UICatalog editors.

* code cleanup

* Update Examples/UICatalog/Scenarios/EditorsAndHelpers/EditorBase.cs

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

* PR feedback.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-14 17:31:57 -07:00

227 lines
7.3 KiB
C#

#nullable enable
using System.Text;
namespace UICatalog.Scenarios;
[ScenarioMetadata ("WideGlyphs", "Demonstrates wide glyphs with overlapped views & clipping")]
[ScenarioCategory ("Unicode")]
[ScenarioCategory ("Drawing")]
public sealed class WideGlyphs : Scenario
{
private Rune [,]? _codepoints;
public override void Main ()
{
// Init
Application.Init ();
// Setup - Create a top-level application window and configure it.
Window appWindow = new ()
{
Title = GetQuitKeyAndName (),
BorderStyle = LineStyle.None
};
// Add Editors
AdornmentsEditor adornmentsEditor = new ()
{
BorderStyle = LineStyle.Single,
X = Pos.AnchorEnd (),
AutoSelectViewToEdit = true,
AutoSelectAdornments = false,
ShowViewIdentifier = true
};
adornmentsEditor.ExpanderButton.Accepting += (sender, args) =>
{
//adornmentsEditor.ExpanderButton.Collapsed = args.NewValue;
};
appWindow.Add (adornmentsEditor);
ViewportSettingsEditor viewportSettingsEditor = new ()
{
BorderStyle = LineStyle.Single,
Y = Pos.AnchorEnd (),
X = Pos.AnchorEnd (),
AutoSelectViewToEdit = true,
};
appWindow.Add (viewportSettingsEditor);
// Build the array of codepoints once when subviews are laid out
appWindow.SubViewsLaidOut += (s, _) =>
{
View? view = s as View;
if (view is null)
{
return;
}
// Only rebuild if size changed or array is null
if (_codepoints is null ||
_codepoints.GetLength (0) != view.Viewport.Height ||
_codepoints.GetLength (1) != view.Viewport.Width)
{
_codepoints = new Rune [view.Viewport.Height, view.Viewport.Width];
for (int r = 0; r < view.Viewport.Height; r++)
{
for (int c = 0; c < view.Viewport.Width; c += 2)
{
_codepoints [r, c] = GetRandomWideCodepoint ();
}
}
}
};
// Fill the window with the pre-built codepoints array
// For detailed documentation on the draw code flow from Application.Run to this event,
// see WideGlyphs.DrawFlow.md in this directory
appWindow.DrawingContent += (s, e) =>
{
View? view = s as View;
if (view is null || _codepoints is null)
{
return;
}
// Traverse the Viewport, using the pre-built array
for (int r = 0; r < view.Viewport.Height && r < _codepoints.GetLength (0); r++)
{
for (int c = 0; c < view.Viewport.Width && c < _codepoints.GetLength (1); c += 2)
{
Rune codepoint = _codepoints [r, c];
if (codepoint != default (Rune))
{
view.AddRune (c, r, codepoint);
}
}
}
e.DrawContext?.AddDrawnRectangle (view.Viewport);
};
Line verticalLineAtEven = new ()
{
X = 10,
Orientation = Orientation.Vertical,
Length = Dim.Fill ()
};
appWindow.Add (verticalLineAtEven);
Line verticalLineAtOdd = new ()
{
X = 25,
Orientation = Orientation.Vertical,
Length = Dim.Fill ()
};
appWindow.Add (verticalLineAtOdd);
View arrangeableViewAtEven = new ()
{
CanFocus = true,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
X = 30,
Y = 5,
Width = 15,
Height = 5,
//BorderStyle = LineStyle.Dashed
};
// Proves it's not LineCanvas related
arrangeableViewAtEven!.Border!.Thickness = new (1);
arrangeableViewAtEven.Border.Add (new View () { Height = Dim.Auto (), Width = Dim.Auto (), Text = "Even" });
appWindow.Add (arrangeableViewAtEven);
View arrangeableViewAtOdd = new ()
{
CanFocus = true,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable,
X = 31,
Y = 11,
Width = 15,
Height = 5,
BorderStyle = LineStyle.Dashed,
};
appWindow.Add (arrangeableViewAtOdd);
var superView = new View
{
CanFocus = true,
X = 30, // on an even column to start
Y = Pos.Center (),
Width = Dim.Auto (),
Height = Dim.Auto (),
BorderStyle = LineStyle.Single,
Arrangement = ViewArrangement.Movable | ViewArrangement.Resizable
};
Rune codepoint = Glyphs.Apple;
superView.DrawingContent += (s, e) =>
{
var view = s as View;
for (var r = 0; r < view!.Viewport.Height; r++)
{
for (var c = 0; c < view.Viewport.Width; c += 2)
{
if (codepoint != default (Rune))
{
view.AddRune (c, r, codepoint);
}
}
}
e.DrawContext?.AddDrawnRectangle (view.Viewport);
e.Cancel = true;
};
appWindow.Add (superView);
var viewWithBorderAtX0 = new View
{
Text = "viewWithBorderAtX0",
BorderStyle = LineStyle.Dashed,
X = 0,
Y = 1,
Width = Dim.Auto (),
Height = 3
};
var viewWithBorderAtX1 = new View
{
Text = "viewWithBorderAtX1",
BorderStyle = LineStyle.Dashed,
X = 1,
Y = Pos.Bottom (viewWithBorderAtX0) + 1,
Width = Dim.Auto (),
Height = 3
};
var viewWithBorderAtX2 = new View
{
Text = "viewWithBorderAtX2",
BorderStyle = LineStyle.Dashed,
X = 2,
Y = Pos.Bottom (viewWithBorderAtX1) + 1,
Width = Dim.Auto (),
Height = 3
};
superView.Add (viewWithBorderAtX0, viewWithBorderAtX1, viewWithBorderAtX2);
// Run - Start the application.
Application.Run (appWindow);
appWindow.Dispose ();
// Shutdown - Calling Application.Shutdown is required.
Application.Shutdown ();
}
private Rune GetRandomWideCodepoint ()
{
Random random = new ();
int codepoint = random.Next (0x4E00, 0x9FFF);
return new (codepoint);
}
}