From da5bfd46f22c7c893d76afba953946f7c37c1d0e Mon Sep 17 00:00:00 2001 From: Charlie Kindel Date: Thu, 4 Jun 2020 23:09:14 -0600 Subject: [PATCH] feature complete --- Example/demo.cs | 38 ++-- Terminal.Gui/Core/View.cs | 5 +- UICatalog/Scenarios/AllViewsTester.cs | 300 +++++++++++++++++++++----- UICatalog/UICatalog.cs | 9 - 4 files changed, 272 insertions(+), 80 deletions(-) diff --git a/Example/demo.cs b/Example/demo.cs index 2e4be94e4..9d839b8d0 100644 --- a/Example/demo.cs +++ b/Example/demo.cs @@ -422,26 +422,26 @@ static class Demo { MessageBox.Query (60, 10, "Selected Animals", result == "" ? "No animals selected" : result, "Ok"); } - static void ComboBoxDemo () - { - IList items = new List (); - foreach (var dir in new [] { "/etc", @"\windows\System32" }) { - if (Directory.Exists (dir)) { - items = Directory.GetFiles (dir) - .Select (Path.GetFileName) - .Where (x => char.IsLetterOrDigit (x [0])) - .Distinct () - .OrderBy (x => x).ToList (); - } - } - var list = new ComboBox (0, 0, 36, 7, items); - list.Changed += (object sender, ustring text) => { Application.RequestStop (); }; + //static void ComboBoxDemo () + //{ + // IList items = new List (); + // foreach (var dir in new [] { "/etc", @"\windows\System32" }) { + // if (Directory.Exists (dir)) { + // items = Directory.GetFiles (dir) + // .Select (Path.GetFileName) + // .Where (x => char.IsLetterOrDigit (x [0])) + // .Distinct () + // .OrderBy (x => x).ToList (); + // } + // } + // var list = new ComboBox (0, 0, 36, 7, items); + // list.Changed += (object sender, ustring text) => { Application.RequestStop (); }; - var d = new Dialog ("Select source file", 40, 12) { list }; - Application.Run (d); + // var d = new Dialog ("Select source file", 40, 12) { list }; + // Application.Run (d); - MessageBox.Query (60, 10, "Selected file", list.Text.ToString() == "" ? "Nothing selected" : list.Text.ToString(), "Ok"); - } + // MessageBox.Query (60, 10, "Selected file", list.Text.ToString() == "" ? "Nothing selected" : list.Text.ToString(), "Ok"); + //} #endregion @@ -573,7 +573,7 @@ static class Demo { new MenuBarItem ("_List Demos", new MenuItem [] { new MenuItem ("Select _Multiple Items", "", () => ListSelectionDemo (true)), new MenuItem ("Select _Single Item", "", () => ListSelectionDemo (false)), - new MenuItem ("Search Single Item", "", ComboBoxDemo) +// new MenuItem ("Search Single Item", "", ComboBoxDemo) }), new MenuBarItem ("A_ssorted", new MenuItem [] { new MenuItem ("_Show text alignments", "", () => ShowTextAlignments ()), diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 822494642..81420b490 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -285,7 +285,8 @@ namespace Terminal.Gui { } } - Pos x, y; + Pos x = Pos.At (0); + Pos y = Pos.At (0); /// /// Gets or sets the X position for the view (the column). Only used whe is . /// @@ -382,6 +383,8 @@ namespace Terminal.Gui { { CanFocus = false; LayoutStyle = LayoutStyle.Computed; + Height = 0; + Width = 0; } /// diff --git a/UICatalog/Scenarios/AllViewsTester.cs b/UICatalog/Scenarios/AllViewsTester.cs index 00db4f74c..306f2284d 100644 --- a/UICatalog/Scenarios/AllViewsTester.cs +++ b/UICatalog/Scenarios/AllViewsTester.cs @@ -7,29 +7,34 @@ using System.Text; using Terminal.Gui; namespace UICatalog { - /// - /// 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 - /// [ ] - ... - /// [ScenarioMetadata (Name: "All Views Tester", Description: "Provides a test UI for all classes derived from View")] [ScenarioCategory ("Layout")] class AllViewsTester : Scenario { - private static Window _leftPane; - private static ListView _classListView; - private static FrameView _settingsPane; - private static FrameView _hostPane; + Window _leftPane; + ListView _classListView; + FrameView _hostPane; Dictionary _viewClasses; - Type _curClass = null; View _curView = null; - StatusItem _currentClassStatusItem; - // Settings + FrameView _settingsPane; CheckBox _computedCheckBox; + FrameView _locationFrame; + RadioGroup _xRadioGroup; + TextField _xText; + int _xVal = 0; + RadioGroup _yRadioGroup; + TextField _yText; + int _yVal = 0; + FrameView _sizeFrame; + RadioGroup _wRadioGroup; + TextField _wText; + int _wVal = 0; + RadioGroup _hRadioGroup; + TextField _hText; + int _hVal = 0; public override void Init (Toplevel top) { @@ -51,10 +56,16 @@ namespace UICatalog { public override void Setup () { - _currentClassStatusItem = new StatusItem (Key.Unknown, "Class:", null); var statusBar = new StatusBar (new StatusItem [] { new StatusItem(Key.ControlQ, "~^Q~ Quit", () => Quit()), - _currentClassStatusItem, + new StatusItem(Key.F2, "~F2~ Toggle Frame Ruler", () => { + ConsoleDriver.Diagnostics ^= ConsoleDriver.DiagnosticFlags.FrameRuler; + Top.SetNeedsDisplay (); + }), + new StatusItem(Key.F3, "~F3~ Toggle Frame Padding", () => { + ConsoleDriver.Diagnostics ^= ConsoleDriver.DiagnosticFlags.FramePadding; + Top.SetNeedsDisplay (); + }), }); Top.Add (statusBar); @@ -72,7 +83,7 @@ namespace UICatalog { ColorScheme = Colors.TopLevel, }; - _classListView = new ListView (_viewClasses.Keys.ToList()) { + _classListView = new ListView (_viewClasses.Keys.ToList ()) { X = 0, Y = 0, Width = Dim.Fill (0), @@ -84,13 +95,13 @@ namespace UICatalog { Top.SetFocus (_settingsPane); }; _classListView.SelectedChanged += (sender, args) => { - _curClass = _viewClasses.Values.ToArray()[_classListView.SelectedItem]; - SetCurrentClass (); + ClearClass (_curView); + _curView = CreateClass (_viewClasses.Values.ToArray () [_classListView.SelectedItem]); }; _leftPane.Add (_classListView); _settingsPane = new FrameView ("Settings") { - X = Pos.Right(_leftPane), + X = Pos.Right (_leftPane), Y = 0, // for menu Width = Dim.Fill (), Height = 10, @@ -103,22 +114,209 @@ namespace UICatalog { _curView.LayoutStyle = previousState ? LayoutStyle.Absolute : LayoutStyle.Computed; _hostPane.LayoutSubviews (); } - }; _settingsPane.Add (_computedCheckBox); + var radioItems = new [] { "Percent(x)", "AnchorEnd(x)", "Center", "At(x)" }; + _locationFrame = new FrameView ("Location (Pos)") { + X = Pos.Left (_computedCheckBox), + Y = Pos.Bottom (_computedCheckBox), + Height = 3 + radioItems.Length, + Width = 36, + }; + _settingsPane.Add (_locationFrame); + + var label = new Label ("x:") { X = 0, Y = 0 }; + _locationFrame.Add (label); + _xRadioGroup = new RadioGroup (radioItems) { + X = 0, + Y = Pos.Bottom (label), + SelectionChanged = (selected) => DimPosChanged (_curView), + }; + _xText = new TextField ($"{_xVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 }; + _xText.Changed += (sender, args) => { + try { + _xVal = int.Parse (_xText.Text.ToString ()); + DimPosChanged (_curView); + } catch { + + } + }; + _locationFrame.Add (_xText); + + _locationFrame.Add (_xRadioGroup); + + radioItems = new [] { "Percent(y)", "AnchorEnd(y)", "Center", "At(y)" }; + label = new Label ("y:") { X = Pos.Right (_xRadioGroup) + 1, Y = 0 }; + _locationFrame.Add (label); + _yText = new TextField ($"{_yVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 }; + _yText.Changed += (sender, args) => { + try { + _yVal = int.Parse (_yText.Text.ToString ()); + DimPosChanged (_curView); + } catch { + + } + }; + _locationFrame.Add (_yText); + _yRadioGroup = new RadioGroup (radioItems) { + X = Pos.X (label), + Y = Pos.Bottom (label), + SelectionChanged = (selected) => DimPosChanged (_curView), + }; + _locationFrame.Add (_yRadioGroup); + + _sizeFrame = new FrameView ("Size (Dim)") { + X = Pos.Right (_locationFrame), + Y = Pos.Y (_locationFrame), + Height = 3 + radioItems.Length, + Width = 40, + }; + + radioItems = new [] { "Percent(width)", "Fill(width)", "Sized(width)" }; + label = new Label ("width:") { X = 0, Y = 0 }; + _sizeFrame.Add (label); + _wRadioGroup = new RadioGroup (radioItems) { + X = 0, + Y = Pos.Bottom (label), + SelectionChanged = (selected) => DimPosChanged (_curView) + }; + _wText = new TextField ($"{_wVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 }; + _wText.Changed += (sender, args) => { + try { + _wVal = int.Parse (_wText.Text.ToString ()); + DimPosChanged (_curView); + } catch { + + } + }; + _sizeFrame.Add (_wText); + _sizeFrame.Add (_wRadioGroup); + + radioItems = new [] { "Percent(height)", "Fill(height)", "Sized(height)" }; + label = new Label ("height:") { X = Pos.Right (_wRadioGroup) + 1, Y = 0 }; + _sizeFrame.Add (label); + _hText = new TextField ($"{_hVal}") { X = Pos.Right (label) + 1, Y = 0, Width = 4 }; + _hText.Changed += (sender, args) => { + try { + _hVal = int.Parse (_hText.Text.ToString ()); + DimPosChanged (_curView); + } catch { + + } + }; + _sizeFrame.Add (_hText); + + _hRadioGroup = new RadioGroup (radioItems) { + X = Pos.X (label), + Y = Pos.Bottom (label), + SelectionChanged = (selected) => DimPosChanged (_curView), + }; + _sizeFrame.Add (_hRadioGroup); + + _settingsPane.Add (_sizeFrame); + _hostPane = new FrameView ("") { - X = Pos.Right (_leftPane) + 2, - Y = Pos.Bottom(_settingsPane) + 2, - Width = Dim.Fill (2), - Height = Dim.Fill (3), // + 1 for status bar + X = Pos.Right (_leftPane), + Y = Pos.Bottom (_settingsPane), + Width = Dim.Fill (), + Height = Dim.Fill (1), // + 1 for status bar ColorScheme = Colors.Dialog, }; Top.Add (_leftPane, _settingsPane, _hostPane); - _curClass = _viewClasses.First().Value; - SetCurrentClass (); + _curView = CreateClass (_viewClasses.First ().Value); + } + + void DimPosChanged (View view) + { + if (view == null) { + return; + } + try { + switch (_xRadioGroup.Selected) { + case 0: + view.X = Pos.Percent (_xVal); + break; + case 1: + view.X = Pos.AnchorEnd (_xVal); + break; + case 2: + view.X = Pos.Center (); + break; + case 3: + view.X = Pos.At (_xVal); + break; + } + + switch (_yRadioGroup.Selected) { + case 0: + view.Y = Pos.Percent (_yVal); + break; + case 1: + view.Y = Pos.AnchorEnd (_yVal); + break; + case 2: + view.Y = Pos.Center (); + break; + case 3: + view.Y = Pos.At (_yVal); + break; + } + + switch (_wRadioGroup.Selected) { + case 0: + view.Width = Dim.Percent (_wVal); + break; + case 1: + view.Width = Dim.Fill (_wVal); + break; + case 2: + view.Width = Dim.Sized (_wVal); + break; + } + + switch (_hRadioGroup.Selected) { + case 0: + view.Height = Dim.Percent (_hVal); + break; + case 1: + view.Height = Dim.Fill (_hVal); + break; + case 2: + view.Height = Dim.Sized (_hVal); + break; + } + } catch (Exception e) { + MessageBox.ErrorQuery ("Exception", e.Message, "Ok"); + } + UpdateTitle (view); + } + + List posNames = new List { "Factor", "AnchorEnd", "Center", "Absolute" }; + List dimNames = new List { "Factor", "Fill", "Absolute" }; + + void UpdateSettings (View view) + { + var x = view.X.ToString (); + var y = view.Y.ToString (); + _xRadioGroup.Selected = posNames.IndexOf (posNames.Where (s => x.Contains (s)).First ()); + _yRadioGroup.Selected = posNames.IndexOf (posNames.Where (s => y.Contains (s)).First ()); + _xText.Text = $"{view.Frame.X}"; + _yText.Text = $"{view.Frame.Y}"; + + var w = view.Width.ToString (); + var h = view.Height.ToString (); + _wRadioGroup.Selected = dimNames.IndexOf (dimNames.Where (s => w.Contains (s)).First ()); + _hRadioGroup.Selected = dimNames.IndexOf (dimNames.Where (s => h.Contains (s)).First ()); + _wText.Text = $"{view.Frame.Width}"; + _hText.Text = $"{view.Frame.Height}"; + } + + void UpdateTitle (View view) + { + _hostPane.Title = $"{view.GetType().Name} - {view.X.ToString ()}, {view.Y.ToString ()}, {view.Width.ToString ()}, {view.Height.ToString ()}"; } List GetAllViewClassesCollection () @@ -131,57 +329,57 @@ namespace UICatalog { return types; } - void SetCurrentClass () + void ClearClass (View view) { - _hostPane.Title = _currentClassStatusItem.Title = $"Class: {_curClass.Name}"; - // Remove existing class, if any - if (_curView != null) { - _hostPane.Remove (_curView); + if (view != null) { + _hostPane.Remove (view); _hostPane.Clear (); - _curView = null; } + } + View CreateClass (Type type) + { // Instantiate view - _curView = (View)Activator.CreateInstance (_curClass); + var view = (View)Activator.CreateInstance (type); - _curView.X = Pos.Center (); - _curView.Y = Pos.Center (); - _curView.Width = Dim.Fill (5); - _curView.Height = Dim.Fill (5); + //_curView.X = Pos.Center (); + //_curView.Y = Pos.Center (); + //_curView.Width = Dim.Fill (5); + //_curView.Height = Dim.Fill (5); // Set the colorscheme to make it stand out - _curView.ColorScheme = Colors.Base; + view.ColorScheme = Colors.Base; // If the view supports a Text property, set it so we have something to look at - if (_curClass.GetProperty ("Text") != null) { + if (view.GetType ().GetProperty ("Text") != null) { try { - _curView.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (_curView, new [] { ustring.Make ("Test Text") }); - } - catch (TargetInvocationException e) { + view.GetType ().GetProperty ("Text")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Text") }); + } catch (TargetInvocationException e) { MessageBox.ErrorQuery ("Exception", e.InnerException.Message, "Ok"); - _hostPane.Remove (_curView); - _hostPane.Clear (); - _curView = null; + view = null; } } - if (_curView == null) return; + if (view == null) return null; // If the view supports a Title property, set it so we have something to look at - if (_curClass.GetProperty ("Title") != null) { - _curView?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (_curView, new [] { ustring.Make ("Test Title") }); + if (view.GetType ().GetProperty ("Title") != null) { + view?.GetType ().GetProperty ("Title")?.GetSetMethod ()?.Invoke (view, new [] { ustring.Make ("Test Title") }); } // Set Settings - _computedCheckBox.Checked = _curView.LayoutStyle == LayoutStyle.Computed; - + _computedCheckBox.Checked = view.LayoutStyle == LayoutStyle.Computed; // Add - _hostPane.Add (_curView); + _hostPane.Add (view); + //DimPosChanged (); _hostPane.LayoutSubviews (); _hostPane.Clear (); _hostPane.SetNeedsDisplay (); + UpdateSettings (view); + UpdateTitle (view); + return view; } public override void Run () diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index f9b72ce6d..acb2465b6 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -59,7 +59,6 @@ namespace UICatalog { private static Scenario _runningScenario = null; private static bool _useSystemConsole = false; - private static MenuItem _consoleFramePaddingMenu; static void Main (string [] args) { @@ -150,14 +149,6 @@ namespace UICatalog { var framePaddingMenuText = "Diagnostics: _Frame Padding"; - void HandleFramePaddingMenuChange () - { - ConsoleDriver.Diagnostics ^= ConsoleDriver.DiagnosticFlags.FramePadding; - _consoleFramePaddingMenu.Title = $"[{((ConsoleDriver.Diagnostics & ConsoleDriver.DiagnosticFlags.FramePadding) == ConsoleDriver.DiagnosticFlags.FramePadding ? 'x' : ' ')}] {framePaddingMenuText}"; - _top.SetNeedsDisplay (); - } - _consoleFramePaddingMenu = new MenuItem ($"[{((ConsoleDriver.Diagnostics & ConsoleDriver.DiagnosticFlags.FramePadding) == ConsoleDriver.DiagnosticFlags.FramePadding ? 'x' : ' ')}] {framePaddingMenuText}", "", () => HandleFramePaddingMenuChange ()); - _menu = new MenuBar (new MenuBarItem [] { new MenuBarItem ("_File", new MenuItem [] { new MenuItem ("_Quit", "", () => Application.RequestStop() )