using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using JetBrains.Annotations; namespace UICatalog.Scenarios; [ScenarioMetadata ("Buttons", "Demonstrates all sorts of Buttons.")] [ScenarioCategory ("Controls")] [ScenarioCategory ("Layout")] public class Buttons : Scenario { public override void Main () { Application.Init (); Window main = new () { Title = GetQuitKeyAndName () }; // Add a label & text field so we can demo IsDefault var editLabel = new Label { X = 0, Y = 0, Text = "TextField (to demo IsDefault):" }; main.Add (editLabel); // Add a TextField using Absolute layout. var edit = new TextField { X = 31, Width = 15, HotKey = Key.Y.WithAlt }; main.Add (edit); // This is the default button (IsDefault = true); if user presses ENTER in the TextField // the scenario will quit var defaultButton = new Button { X = Pos.Center (), Y = Pos.AnchorEnd (), IsDefault = true, Text = "_Quit" }; main.Add (defaultButton); // Note we handle Accept on main, not defaultButton main.Accepting += (s, e) => Application.RequestStop (); var swapButton = new Button { X = 50, Width = 45, Height = 3, Text = "S_wap Default (Size = 45, 3)", SchemeName = "Error" }; swapButton.Accepting += (s, e) => { e.Handled = !swapButton.IsDefault; defaultButton.IsDefault = !defaultButton.IsDefault; swapButton.IsDefault = !swapButton.IsDefault; }; defaultButton.Accepting += (s, e) => { e.Handled = !defaultButton.IsDefault; if (e.Handled) { MessageBox.ErrorQuery ((s as View)?.App, "Error", "This button is no longer the Quit button; the Swap Default button is.", "_Ok"); } }; main.Add (swapButton); static void DoMessage (Button button, string txt) { button.Accepting += (s, e) => { string btnText = button.Text; MessageBox.Query ((s as View)?.App, "Message", $"Did you click {txt}?", "Yes", "No"); e.Handled = true; }; } var colorButtonsLabel = new Label { X = 0, Y = Pos.Bottom (swapButton) + 1, Text = "Color Buttons: " }; main.Add (colorButtonsLabel); View prev = colorButtonsLabel; foreach (KeyValuePair scheme in SchemeManager.GetSchemesForCurrentTheme ()) { var colorButton = new Button { X = Pos.Right (prev), Y = Pos.Y (colorButtonsLabel), Text = $"_{scheme.Key}", SchemeName = scheme.Key, }; DoMessage (colorButton, colorButton.Text); main.Add (colorButton); prev = colorButton; } Button button; main.Add ( button = new () { X = 2, Y = Pos.Bottom (colorButtonsLabel) + 1, Text = "A super l_öng Button that will probably expose a bug in clipping or wrapping of text. Will it?" } ); DoMessage (button, button.Text); // Note the 'N' in 'Newline' will be the hotkey main.Add ( button = new () { X = 2, Y = Pos.Bottom (button) + 1, Height = 2, Text = "a Newline\nin the button" } ); button.Accepting += (s, e) => { MessageBox.Query ((s as View)?.App, "Message", "Question?", "Yes", "No"); e.Handled = true; }; var textChanger = new Button { X = 2, Y = Pos.Bottom (button) + 1, Text = "Te_xt Changer" }; main.Add (textChanger); textChanger.Accepting += (s, e) => { textChanger.Text += "!"; e.Handled = true; }; main.Add ( button = new () { X = Pos.Right (textChanger) + 2, Y = Pos.Y (textChanger), Text = "Lets see if this will move as \"Text Changer\" grows" } ); button.Accepting += (sender, args) => { args.Handled = true; }; var removeButton = new Button { X = 2, Y = Pos.Bottom (button) + 1, SchemeName = SchemeManager.SchemesToSchemeName (Schemes.Error), Text = "Remove this button" }; main.Add (removeButton); // This in interesting test case because `moveBtn` and below are laid out relative to this one! removeButton.Accepting += (s, e) => { removeButton.Visible = false; e.Handled = true; }; var computedFrame = new FrameView { X = 0, Y = Pos.Bottom (removeButton) + 1, Width = Dim.Percent (50), Height = 6, Title = "Computed Layout" }; main.Add (computedFrame); // Demonstrates how changing the View.Frame property can move Views var moveBtn = new Button { X = 0, Y = Pos.Center () - 1, Width = 30, SchemeName = "Error", Text = "Move This \u263b Button v_ia Pos" }; moveBtn.Accepting += (s, e) => { moveBtn.X = moveBtn.Frame.X + 5; e.Handled = true; }; computedFrame.Add (moveBtn); // Demonstrates how changing the View.Frame property can SIZE Views (#583) var sizeBtn = new Button { Y = Pos.Center () + 1, X = 0, Width = 30, Text = "Grow This \u263a Button _via Pos", SchemeName = "Error", }; sizeBtn.Accepting += (s, e) => { sizeBtn.Width = sizeBtn.Frame.Width + 5; e.Handled = true; }; computedFrame.Add (sizeBtn); var absoluteFrame = new FrameView { X = Pos.Right (computedFrame), Y = Pos.Bottom (removeButton) + 1, Width = Dim.Fill (), Height = 6, Title = "Absolute Layout" }; main.Add (absoluteFrame); // Demonstrates how changing the View.Frame property can move Views var moveBtnA = new Button { SchemeName = "Error", Text = "Move This Button via Frame" }; moveBtnA.Accepting += (s, e) => { moveBtnA.Frame = new ( moveBtnA.Frame.X + 5, moveBtnA.Frame.Y, moveBtnA.Frame.Width, moveBtnA.Frame.Height ); e.Handled = true; }; absoluteFrame.Add (moveBtnA); // Demonstrates how changing the View.Frame property can SIZE Views (#583) var sizeBtnA = new Button { Y = 2, SchemeName = "Error", Text = " ~  s  gui.cs   master ↑_10 = Сохранить" }; sizeBtnA.Accepting += (s, e) => { sizeBtnA.Frame = new ( sizeBtnA.Frame.X, sizeBtnA.Frame.Y, sizeBtnA.Frame.Width + 5, sizeBtnA.Frame.Height ); e.Handled = true; }; absoluteFrame.Add (sizeBtnA); var label = new Label { X = 2, Y = Pos.Bottom (computedFrame) + 1, Text = "Text Ali_gnment (changes the four buttons above): " }; main.Add (label); OptionSelector osAlignment = new () { X = 4, Y = Pos.Bottom (label) + 1, Value = Alignment.Center, AssignHotKeys = true, Title = "_9 OptionSelector", BorderStyle = LineStyle.Dotted, // CanFocus = false }; main.Add (osAlignment); // Demo changing hotkey string MoveHotkey (string txt) { // Remove the '_' List runes = txt.ToRuneList (); int i = runes.IndexOf ((Rune)'_'); var start = ""; if (i > -1) { start = StringExtensions.ToString (runes.GetRange (0, i)); } txt = start + StringExtensions.ToString (runes.GetRange (i + 1, runes.Count - (i + 1))); runes = txt.ToRuneList (); // Move over one or go to start i++; if (i >= runes.Count) { i = 0; } // Slip in the '_' start = StringExtensions.ToString (runes.GetRange (0, i)); return start + '_' + StringExtensions.ToString (runes.GetRange (i, runes.Count - i)); } var mhkb = "Click to Change th_is Button's Hotkey"; var moveHotKeyBtn = new Button { X = 2, Y = Pos.Bottom (osAlignment) + 1, Width = Dim.Width (computedFrame) - 2, SchemeName = "Runnable", Text = mhkb }; moveHotKeyBtn.Accepting += (s, e) => { moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text); e.Handled = true; }; main.Add (moveHotKeyBtn); var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить"; var moveUnicodeHotKeyBtn = new Button { X = Pos.Left (absoluteFrame) + 1, Y = Pos.Bottom (osAlignment) + 1, Width = Dim.Width (absoluteFrame) - 2, SchemeName = "Runnable", Text = muhkb }; moveUnicodeHotKeyBtn.Accepting += (s, e) => { moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text); e.Handled = true; }; main.Add (moveUnicodeHotKeyBtn); osAlignment.ValueChanged += (s, args) => { if (args.Value is null) { return; } Alignment newValue = args.Value.Value; moveBtn.TextAlignment = newValue; sizeBtn.TextAlignment = newValue; moveBtnA.TextAlignment = newValue; sizeBtnA.TextAlignment = newValue; moveHotKeyBtn.TextAlignment = newValue; moveUnicodeHotKeyBtn.TextAlignment = newValue; }; label = new () { X = 0, Y = Pos.Bottom (moveUnicodeHotKeyBtn) + 1, Title = "_Numeric Up/Down (press-and-hold):", }; var numericUpDown = new NumericUpDown { Value = 69, X = Pos.Right (label) + 1, Y = Pos.Top (label), }; numericUpDown.ValueChanged += NumericUpDown_ValueChanged; void NumericUpDown_ValueChanged (object sender, EventArgs e) { } main.Add (label, numericUpDown); label = new () { X = 0, Y = Pos.Bottom (numericUpDown) + 1, Title = "_No Repeat:" }; var noRepeatAcceptCount = 0; var noRepeatButton = new Button { X = Pos.Right (label) + 1, Y = Pos.Top (label), Title = $"Accept Cou_nt: {noRepeatAcceptCount}", WantContinuousButtonPressed = false }; noRepeatButton.Accepting += (s, e) => { noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}"; e.Handled = true; }; main.Add (label, noRepeatButton); label = new () { X = 0, Y = Pos.Bottom (label) + 1, Title = "_Repeat (press-and-hold):" }; var acceptCount = 0; var repeatButton = new Button { Id = "repeatButton", X = Pos.Right (label) + 1, Y = Pos.Top (label), Title = $"Accept Co_unt: {acceptCount}", WantContinuousButtonPressed = true }; repeatButton.Accepting += (s, e) => { repeatButton.Title = $"Accept Co_unt: {++acceptCount}"; e.Handled = true; }; var enableCB = new CheckBox { X = Pos.Right (repeatButton) + 1, Y = Pos.Top (repeatButton), Title = "Enabled", CheckedState = CheckState.Checked }; enableCB.CheckedStateChanging += (s, e) => { repeatButton.Enabled = !repeatButton.Enabled; }; main.Add (label, repeatButton, enableCB); var decNumericUpDown = new NumericUpDown { Value = 911, Increment = 1, Format = "{0:X}", X = 0, Y = Pos.Bottom (enableCB) + 1, }; main.Add (decNumericUpDown); Application.Run (main); main.Dispose (); Application.Shutdown (); } }