123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- using NStack;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using Terminal.Gui;
- using Terminal.Gui.Configuration;
- namespace UICatalog.Scenarios {
- /// <summary>
- /// This Scenario demonstrates how to use Termina.gui's Dim and Pos Layout System.
- /// [x] - Using Dim.Fill to fill a window
- /// [x] - Using Dim.Fill and Dim.Pos to automatically align controls based on an initial control
- /// [ ] - ...
- /// </summary>
- [ScenarioMetadata (Name: "Computed Layout", Description: "Demonstrates the Computed (Dim and Pos) Layout System.")]
- [ScenarioCategory ("Layout")]
- public class ComputedLayout : Scenario {
- public override void Init ()
- {
- Application.Init ();
- ConfigurationManager.Themes.Theme = Theme;
- ConfigurationManager.Apply ();
- Application.Top.ColorScheme = Colors.ColorSchemes [TopLevelColorScheme];
- }
- public override void Setup ()
- {
- // Demonstrate using Dim to create a horizontal ruler that always measures the parent window's width
- const string rule = "|123456789";
- var horizontalRuler = new Label ("") {
- AutoSize = false,
- X = 0,
- Y = 0,
- Width = Dim.Fill (),
- ColorScheme = Colors.Error
- };
- Application.Top.Add (horizontalRuler);
- // Demonstrate using Dim to create a vertical ruler that always measures the parent window's height
- const string vrule = "|\n1\n2\n3\n4\n5\n6\n7\n8\n9\n";
- var verticalRuler = new Label ("") {
- AutoSize = false,
- X = 0,
- Y = 0,
- Width = 1,
- Height = Dim.Fill (),
- ColorScheme = Colors.Error
- };
- Application.Top.LayoutComplete += (a) => {
- horizontalRuler.Text = rule.Repeat ((int)Math.Ceiling ((double)(horizontalRuler.Bounds.Width) / (double)rule.Length)) [0..(horizontalRuler.Bounds.Width)];
- verticalRuler.Text = vrule.Repeat ((int)Math.Ceiling ((double)(verticalRuler.Bounds.Height * 2) / (double)rule.Length)) [0..(verticalRuler.Bounds.Height*2)];
- };
- Application.Top.Add (verticalRuler);
- // Demonstrate At - Using Pos.At to locate a view in an absolute location
- var atButton = new Button ("At(2,1)") {
- X = Pos.At (2),
- Y = Pos.At (1)
- };
- Application.Top.Add (atButton);
- // Throw in a literal absolute - Should funciton identically to above
- var absoluteButton = new Button ("X = 30, Y = 1") {
- X = 30,
- Y = 1
- };
- Application.Top.Add (absoluteButton);
- // Demonstrate using Dim to create a window that fills the parent with a margin
- int margin = 10;
- var subWin = new Window () {
- X = Pos.Center (),
- Y = 2,
- Width = Dim.Fill (margin),
- Height = 7
- };
- subWin.Title = $"{subWin.GetType().Name} {{X={subWin.X},Y={subWin.Y},Width={subWin.Width},Height={subWin.Height}}}";
- Application.Top.Add (subWin);
- int i = 1;
- string txt = "Resize the terminal to see computed layout in action.";
- var labelList = new List<Label> ();
- labelList.Add (new Label ($"The lines below show different TextAlignments"));
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Left, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Right, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Centered, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Justified, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- subWin.Add (labelList.ToArray ());
- // #522 repro?
- var frameView = new FrameView () {
- X = 2, //Pos.Center (),
- Y = Pos.Bottom (subWin),
- Width = 30,
- Height = 7
- };
- frameView.Title = $"{frameView.GetType ().Name} {{X={frameView.X},Y={frameView.Y},Width={frameView.Width},Height={frameView.Height}}}";
- i = 1;
- labelList = new List<Label> ();
- labelList.Add (new Label ($"The lines below show different TextAlignments"));
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Left, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Right, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Centered, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- labelList.Add (new Label ($"{i++}-{txt}") { TextAlignment = Terminal.Gui.TextAlignment.Justified, Width = Dim.Fill (), X = 0, Y = Pos.Bottom (labelList.LastOrDefault ()), ColorScheme = Colors.Dialog });
- frameView.Add (labelList.ToArray ());
- Application.Top.Add (frameView);
- frameView = new FrameView () {
- X = Pos.Right(frameView),
- Y = Pos.Top (frameView),
- Width = Dim.Fill(),
- Height = 7,
- };
- frameView.Title = $"{frameView.GetType ().Name} {{X={frameView.X},Y={frameView.Y},Width={frameView.Width},Height={frameView.Height}}}";
- Application.Top.Add (frameView);
- // Demonstrate Dim & Pos using percentages - a TextField that is 30% height and 80% wide
- var textView = new TextView () {
- X = Pos.Center (),
- Y = Pos.Percent (50),
- Width = Dim.Percent (80),
- Height = Dim.Percent (10),
- ColorScheme = Colors.TopLevel,
- };
- textView.Text = $"This TextView should horizontally & vertically centered and \n10% of the screeen height, and 80% of its width.";
- Application.Top.Add (textView);
- var oddballButton = new Button ("These buttons demo convoluted PosCombine scenarios") {
- X = Pos.Center (),
- Y = Pos.Bottom (textView) + 1
- };
- Application.Top.Add (oddballButton);
- #region Issue2358
- // Demonstrate odd-ball Combine scenarios
- // Until https://github.com/gui-cs/Terminal.Gui/issues/2358 is fixed these won't work right
- oddballButton = new Button ("Center + 0") {
- X = Pos.Center () + 0,
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- oddballButton = new Button ("Center + 1") {
- X = Pos.Center () + 1,
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- oddballButton = new Button ("0 + Center") {
- X = 0 + Pos.Center (),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- oddballButton = new Button ("1 + Center") {
- X = 1 + Pos.Center (),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
- // The `- Pos.Percent(5)` is there so at least something is visible
- oddballButton = new Button ("Center + Center - Percent(50)") {
- X = Pos.Center () + Pos.Center () - Pos.Percent(50),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
- // The `- Pos.Percent(5)` is there so at least something is visible
- oddballButton = new Button ("Percent(50) + Center - Percent(50)") {
- X = Pos.Percent (50) + Pos.Center () - Pos.Percent (50),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- // This demonstrates nonsense: it the same as using Pos.AnchorEnd (100/2=50 + 100/2=50 = 100 - 50)
- // The `- Pos.Percent(5)` is there so at least something is visible
- oddballButton = new Button ("Center + Percent(50) - Percent(50)") {
- X = Pos.Center () + Pos.Percent (50) - Pos.Percent (50),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- #endregion
- // This demonstrates nonsense: Same as At(0)
- oddballButton = new Button ("Center - Center - Percent(50)") {
- X = Pos.Center () + Pos.Center () - Pos.Percent (50),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- // This demonstrates combining Percents)
- oddballButton = new Button ("Percent(40) + Percent(10)") {
- X = Pos.Percent (40) + Pos.Percent(10),
- Y = Pos.Bottom (oddballButton)
- };
- Application.Top.Add (oddballButton);
- // Demonstrate AnchorEnd - Button is anchored to bottom/right
- var anchorButton = new Button ("Button using AnchorEnd") {
- Y = Pos.AnchorEnd () - 1,
- };
- anchorButton.X = Pos.AnchorEnd () - (Pos.Right (anchorButton) - Pos.Left (anchorButton));
- anchorButton.Clicked += () => {
- // Ths demonstrates how to have a dynamically sized button
- // Each time the button is clicked the button's text gets longer
- // The call to Application.Top.LayoutSubviews causes the Computed layout to
- // get updated.
- anchorButton.Text += "!";
- Application.Top.LayoutSubviews ();
- };
- Application.Top.Add (anchorButton);
- // Demonstrate AnchorEnd(n)
- // This is intentionally convoluted to illustrate potential bugs.
- var anchorEndLabel1 = new Label ("This Label should be the 2nd to last line (AnchorEnd (2)).") {
- TextAlignment = Terminal.Gui.TextAlignment.Centered,
- ColorScheme = Colors.Menu,
- Width = Dim.Fill (5),
- X = 5,
- Y = Pos.AnchorEnd (2)
- };
- Application.Top.Add (anchorEndLabel1);
- // Demonstrate DimCombine (via AnchorEnd(n) - 1)
- // This is intentionally convoluted to illustrate potential bugs.
- var anchorEndLabel2 = new TextField ("This TextField should be the 3rd to last line (AnchorEnd (2) - 1).") {
- TextAlignment = Terminal.Gui.TextAlignment.Left,
- ColorScheme = Colors.Menu,
- Width = Dim.Fill (5),
- X = 5,
- Y = Pos.AnchorEnd (2) - 1 // Pos.Combine
- };
- Application.Top.Add (anchorEndLabel2);
- // Show positioning vertically using Pos.AnchorEnd via Pos.Combine
- var leftButton = new Button ("Left") {
- Y = Pos.AnchorEnd () - 1 // Pos.Combine
- };
- leftButton.Clicked += () => {
- // Ths demonstrates how to have a dynamically sized button
- // Each time the button is clicked the button's text gets longer
- // The call to Application.Top.LayoutSubviews causes the Computed layout to
- // get updated.
- leftButton.Text += "!";
- Application.Top.LayoutSubviews ();
- };
- // show positioning vertically using Pos.AnchorEnd
- var centerButton = new Button ("Center") {
- X = Pos.Center (),
- Y = Pos.AnchorEnd (1) // Pos.AnchorEnd(1)
- };
- centerButton.Clicked += () => {
- // Ths demonstrates how to have a dynamically sized button
- // Each time the button is clicked the button's text gets longer
- // The call to Application.Top.LayoutSubviews causes the Computed layout to
- // get updated.
- centerButton.Text += "!";
- Application.Top.LayoutSubviews ();
- };
- // show positioning vertically using another window and Pos.Bottom
- var rightButton = new Button ("Right") {
- Y = Pos.Y (centerButton)
- };
- rightButton.Clicked += () => {
- // Ths demonstrates how to have a dynamically sized button
- // Each time the button is clicked the button's text gets longer
- // The call to Application.Top.LayoutSubviews causes the Computed layout to
- // get updated.
- rightButton.Text += "!";
- Application.Top.LayoutSubviews ();
- };
- // Center three buttons with 5 spaces between them
- leftButton.X = Pos.Left (centerButton) - (Pos.Right (leftButton) - Pos.Left (leftButton)) - 5;
- rightButton.X = Pos.Right (centerButton) + 5;
- Application.Top.Add (leftButton);
- Application.Top.Add (centerButton);
- Application.Top.Add (rightButton);
- }
- public override void Run ()
- {
- base.Run ();
- }
- private void Quit ()
- {
- Application.RequestStop ();
- }
- }
- internal static class StringExtensions {
- public static string Repeat (this string instr, int n)
- {
- if (n <= 0) {
- return null;
- }
- if (string.IsNullOrEmpty (instr) || n == 1) {
- return instr;
- }
- return new StringBuilder (instr.Length * n)
- .Insert (0, instr, n)
- .ToString ();
- }
- }
- }
|