mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-29 09:18:01 +01:00
* Added View.DefaultCommand etc... Started on dedicated scenario * Fixed un-shifted hotkeys -> Fixed Key Equals. Fixed WindowsDriver passing wrong key. Etc. * Fixed Key Bindings and HotKeys * Fixed Key Bindings and HotKeys * Label now correctly supports hotkey * Disabled unix hot keys because they are annoying and get in the way * Updated nuget. fixed warnings * Trying to fix ci/ci issue * Trying to fix ci/ci issue * Trying to fix ci/ci issue * Changed TextChangingEventArgs to inherit from CancelEventArgs * TextChangingEventArgs -> TextEventArgs * Simplified Text events by having only on args class * Fixed unit tests fail * Simplified by removing TitleEventArgs * POC of Title being primary for hotkey. Label and Button hacked to work * POC of Title being primary for hotkey. Label and Button hacked to work - all unit tests pass * Dropped Microsoft.NETFramework.ReferenceAssemblies * Fixed Dialogs scenario hotkeys * Fixed build warnings * Fixed Border Title render bug * Regiggering default command handling * Regiggering default command handling * Checkbox clean up * Added StateEventArgs POC * Command.Default -> Command.HotKey * Command.Default -> Command.HotKey - fixed TableView * Command.Default -> Command.HotKey - fixed TableView * Updated reactive example * Fixed Toplevel.BringOverlappedTopToFront - was reordering SubViews when it shouldn't * WIP - broke * Finished impl of StateEventArgs * Deleted ToggleEventArgs.cs. Added StateEventArgs.cs * XML doc fix * Removed old code * Removed commented out code * Label.Clicked -> Label.Accept (missed this before) * Removed Labels as Buttons scenario as it's not really useful * Moved SubView tests to own file * Moved SubView tests to own file * Simplified Text test * Added OnAccept test * Deleted DefaultCommand * Modernized CheckBox * New button test * Cleaned up RadioGroup; added tests * KeyCode->Key in ListView * Added ListView unit tests * ListView now does Accept correctly * TreeView now does Accept correctly * Cleaned up some TextField tests * TextView now handles Accept properly; updated CharMap and Adornments scenarios to test * Fixed ComboBox to deal with TextView now handles Accept properly; updated CharMap and Adornments scenarios to test * Removed un-needed using statement
415 lines
17 KiB
C#
415 lines
17 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Terminal.Gui;
|
|
|
|
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 ("Computed Layout", "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 (),
|
|
Height = 1,
|
|
ColorScheme = Colors.ColorSchemes ["Error"],
|
|
Text = rule
|
|
};
|
|
|
|
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.ColorSchemes ["Error"],
|
|
Text = vrule
|
|
};
|
|
|
|
Application.Top.LayoutComplete += (s, a) =>
|
|
{
|
|
horizontalRuler.Text =
|
|
rule.Repeat ((int)Math.Ceiling (horizontalRuler.Bounds.Width / (double)rule.Length)) [
|
|
..horizontalRuler.Bounds.Width];
|
|
|
|
verticalRuler.Text =
|
|
vrule.Repeat ((int)Math.Ceiling (verticalRuler.Bounds.Height * 2 / (double)rule.Length))
|
|
[..(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 { Text = "At(2,1)", X = Pos.At (2), Y = Pos.At (1) };
|
|
Application.Top.Add (atButton);
|
|
|
|
// Throw in a literal absolute - Should function identically to above
|
|
var absoluteButton = new Button { Text = "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
|
|
var margin = 10;
|
|
var subWin = new Window { X = Pos.Center (), Y = 2, Width = Dim.Fill (margin), Height = 7 };
|
|
|
|
subWin.Initialized += (s, a) =>
|
|
{
|
|
subWin.Title =
|
|
$"{subWin.GetType ().Name} {{X={subWin.X},Y={subWin.Y},Width={subWin.Width},Height={subWin.Height}}}";
|
|
};
|
|
Application.Top.Add (subWin);
|
|
|
|
var i = 1;
|
|
var txt = "Resize the terminal to see computed layout in action.";
|
|
List<Label> labelList = new ();
|
|
labelList.Add (new Label { Text = "The lines below show different TextAlignments" });
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Left,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Right,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Centered,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Justified,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
subWin.Add (labelList.ToArray ());
|
|
|
|
var frameView = new FrameView { X = 2, Y = Pos.Bottom (subWin), Width = 30, Height = 7 };
|
|
|
|
frameView.Initialized += (sender, args) =>
|
|
{
|
|
var fv = sender as FrameView;
|
|
|
|
fv.Title =
|
|
$"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.Height}}}";
|
|
};
|
|
i = 1;
|
|
labelList = new List<Label> ();
|
|
labelList.Add (new Label { Text = "The lines below show different TextAlignments" });
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Left,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Right,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Centered,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
|
|
labelList.Add (
|
|
new Label
|
|
{
|
|
TextAlignment = TextAlignment.Justified,
|
|
AutoSize = false,
|
|
Width = Dim.Fill (),
|
|
X = 0,
|
|
Y = Pos.Bottom (labelList.LastOrDefault ()),
|
|
ColorScheme = Colors.ColorSchemes ["Dialog"],
|
|
Text = $"{i++}-{txt}"
|
|
}
|
|
);
|
|
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.Initialized += (sender, args) =>
|
|
{
|
|
var fv = sender as FrameView;
|
|
|
|
fv.Title =
|
|
$"{frameView.GetType ().Name} {{X={fv.X},Y={fv.Y},Width={fv.Width},Height={fv.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.ColorSchemes ["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
|
|
{
|
|
Text = "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 { Text = "Center + 0", X = Pos.Center () + 0, Y = Pos.Bottom (oddballButton) };
|
|
Application.Top.Add (oddballButton);
|
|
|
|
oddballButton = new Button { Text = "Center + 1", X = Pos.Center () + 1, Y = Pos.Bottom (oddballButton) };
|
|
Application.Top.Add (oddballButton);
|
|
|
|
oddballButton = new Button { Text = "0 + Center", X = 0 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
|
|
Application.Top.Add (oddballButton);
|
|
|
|
oddballButton = new Button { Text = "1 + Center", X = 1 + Pos.Center (), Y = Pos.Bottom (oddballButton) };
|
|
Application.Top.Add (oddballButton);
|
|
|
|
oddballButton = new Button { Text = "Center - 1", X = Pos.Center () - 1, 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
|
|
{
|
|
Text = "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
|
|
{
|
|
Text = "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
|
|
{
|
|
Text = "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
|
|
{
|
|
Text = "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
|
|
{
|
|
Text = "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 { Text = "Button using AnchorEnd", Y = Pos.AnchorEnd () - 1 };
|
|
anchorButton.X = Pos.AnchorEnd () - (Pos.Right (anchorButton) - Pos.Left (anchorButton));
|
|
|
|
anchorButton.Accept += (s, e) =>
|
|
{
|
|
// This 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
|
|
{
|
|
Text = "This Label should be the 2nd to last line (AnchorEnd (2)).",
|
|
TextAlignment = TextAlignment.Centered,
|
|
ColorScheme = Colors.ColorSchemes ["Menu"],
|
|
AutoSize = false,
|
|
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
|
|
{
|
|
Text =
|
|
"This TextField should be the 3rd to last line (AnchorEnd (2) - 1).",
|
|
TextAlignment = TextAlignment.Left,
|
|
ColorScheme = Colors.ColorSchemes ["Menu"],
|
|
AutoSize = false,
|
|
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
|
|
{
|
|
Text = "Left", Y = Pos.AnchorEnd () - 1 // Pos.Combine
|
|
};
|
|
|
|
leftButton.Accept += (s, e) =>
|
|
{
|
|
// This 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
|
|
{
|
|
Text = "Center", X = Pos.Center (), Y = Pos.AnchorEnd (1) // Pos.AnchorEnd(1)
|
|
};
|
|
|
|
centerButton.Accept += (s, e) =>
|
|
{
|
|
// This 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 { Text = "Right", Y = Pos.Y (centerButton) };
|
|
|
|
rightButton.Accept += (s, e) =>
|
|
{
|
|
// This 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);
|
|
}
|
|
}
|