#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 }; // 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, _) => { 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); } } } }; 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 () + 4, Height = Dim.Auto () + 1, 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); } }