From 8bf0207171c299c37bb51bbbc83cbcb06429f9d5 Mon Sep 17 00:00:00 2001 From: Tig Date: Mon, 15 Jul 2024 12:00:50 -0600 Subject: [PATCH] Dialog works --- Terminal.Gui/View/Layout/DimAuto.cs | 163 +++++++++++++++++++--------- Terminal.Gui/Views/Dialog.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 3 + UICatalog/KeyBindingsDialog.cs | 6 +- UICatalog/Scenarios/Dialogs.cs | 5 +- UICatalog/Scenarios/ListColumns.cs | 2 +- UICatalog/Scenarios/TableEditor.cs | 14 ++- 7 files changed, 131 insertions(+), 64 deletions(-) diff --git a/Terminal.Gui/View/Layout/DimAuto.cs b/Terminal.Gui/View/Layout/DimAuto.cs index 9ea540cd8..00952abb4 100644 --- a/Terminal.Gui/View/Layout/DimAuto.cs +++ b/Terminal.Gui/View/Layout/DimAuto.cs @@ -1,4 +1,5 @@ #nullable enable +using System.Diagnostics; using System.Drawing; namespace Terminal.Gui; @@ -159,7 +160,18 @@ public class DimAuto () : Dim { View v = notDependentSubViews [i]; - int size = dimension == Dimension.Width ? v.X.GetAnchor (maxCalculatedSize) + v.Width.GetAnchor (maxCalculatedSize) : v.Y.GetAnchor (maxCalculatedSize) + v.Height.GetAnchor (maxCalculatedSize); + int size = 0; + + if (dimension == Dimension.Width) + { + int width = v.Width!.Calculate (0, 0, v, dimension); + size = v.X.GetAnchor (0) + width; + } + else + { + int height = v.Height!.Calculate (0, 0, v, dimension); + size = v.Y.GetAnchor (0) + height; + } if (size > maxCalculatedSize) { @@ -169,7 +181,7 @@ public class DimAuto () : Dim // ************** We now have some idea of `us.ContentSize` *************** - + #region Centered // [ ] PosCenter - Position is dependent `us.ContentSize` AND `subview.Frame` List centeredSubViews; if (dimension == Dimension.Width) @@ -181,17 +193,110 @@ public class DimAuto () : Dim centeredSubViews = us.Subviews.Where (v => v.Y.Has (typeof (PosCenter), out _)).ToList (); } + int maxCentered = 0; + for (var i = 0; i < centeredSubViews.Count; i++) { View v = centeredSubViews [i]; - int maxCentered = dimension == Dimension.Width ?/* v.X.GetAnchor (maxCalculatedSize) +*/ v.Width.GetAnchor (maxCalculatedSize) : /*v.Y.GetAnchor (maxCalculatedSize) + */v.Height.GetAnchor(maxCalculatedSize); - - if (maxCentered > maxCalculatedSize) + if (dimension == Dimension.Width) { - maxCalculatedSize = maxCentered; + int width = v.Width!.Calculate (0, 0, v, dimension); + maxCentered = (v.X.GetAnchor (0) + width) * 2; + } + else + { + int height = v.Height!.Calculate (0, 0, v, dimension); + maxCentered = (v.Y.GetAnchor (0) + height) * 2; } } + maxCalculatedSize = int.Max (maxCalculatedSize, maxCentered); + #endregion Centered + + #region Percent + // [ ] DimPercent - Dimension is dependent on `us.ContentSize` + List percentSubViews; + if (dimension == Dimension.Width) + { + percentSubViews = us.Subviews.Where (v => v.Width.Has (typeof (DimPercent), out _)).ToList (); + } + else + { + percentSubViews = us.Subviews.Where (v => v.Height.Has (typeof (DimPercent), out _)).ToList (); + } + + int maxPercent = 0; + + for (var i = 0; i < percentSubViews.Count; i++) + { + View v = percentSubViews [i]; + + if (dimension == Dimension.Width) + { + int width = v.Width!.Calculate (0, 0, v, dimension); + maxPercent = (v.X.GetAnchor (0) + width); + } + else + { + int height = v.Height!.Calculate (0, 0, v, dimension); + maxPercent = (v.Y.GetAnchor (0) + height); + } + } + maxCalculatedSize = int.Max (maxCalculatedSize, maxPercent); + #endregion Percent + + + #region Aligned + // [ ] PosAlign - Position is dependent on other views with `GroupId` AND `us.ContentSize` + int maxAlign = 0; + // Use Linq to get a list of distinct GroupIds from the subviews + List groupIds = includedSubviews.Select ( + v => + { + if (dimension == Dimension.Width) + { + if (v.X.Has (typeof (PosAlign), out Pos posAlign)) + { + return ((PosAlign)posAlign).GroupId; + } + } + else + { + if (v.Y.Has (typeof (PosAlign), out Pos posAlign)) + { + return ((PosAlign)posAlign).GroupId; + } + } + return -1; + }).Distinct ().ToList (); + + foreach (var groupId in groupIds.Where (g => g != -1)) + { + // PERF: If this proves a perf issue, consider caching a ref to this list in each item + List posAlignsInGroup = includedSubviews.Where ( + v => + { + return dimension switch + { + Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, + Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, + _ => false + }; + }) + .Select (v => dimension == Dimension.Width ? v.X as PosAlign : v.Y as PosAlign) + .ToList (); + + if (posAlignsInGroup.Count == 0) + { + continue; + } + + maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension); + } + + maxCalculatedSize = int.Max (maxCalculatedSize, maxAlign); + #endregion Aligned + #region Anchored @@ -226,7 +331,6 @@ public class DimAuto () : Dim maxCalculatedSize = Math.Max (maxCalculatedSize, maxAnchorEnd); #endregion Anchored - #region PosView // [x] PosView - Position is dependent on `subview.Target` - it can cause a change in `us.ContentSize` List posViewSubViews; @@ -405,51 +509,6 @@ public class DimAuto () : Dim // #endregion Not Anchored and Are Not Dependent - // //#region Aligned - - // //// Now, handle subviews that are aligned - // //// [x] PosAlign - // //int maxAlign = 0; - // //if (dimension == Dimension.Width) - // //{ - // // // Use Linq to get a list of distinct GroupIds from the subviews - // // List groupIds = includedSubviews.Select (v => v.X is PosAlign posAlign ? posAlign.GroupId : -1).Distinct ().ToList (); - - // // foreach (var groupId in groupIds) - // // { - // // List dimensionsList = new (); - - // // // PERF: If this proves a perf issue, consider caching a ref to this list in each item - // // List posAlignsInGroup = includedSubviews.Where ( - // // v => - // // { - // // return dimension switch - // // { - // // Dimension.Width when v.X is PosAlign alignX => alignX.GroupId == groupId, - // // Dimension.Height when v.Y is PosAlign alignY => alignY.GroupId == groupId, - // // _ => false - // // }; - // // }) - // // .Select (v => dimension == Dimension.Width ? v.X as PosAlign : v.Y as PosAlign) - // // .ToList (); - - // // if (posAlignsInGroup.Count == 0) - // // { - // // continue; - // // } - // // BUGBUG: ignores adornments - - // // maxAlign = PosAlign.CalculateMinDimension (groupId, includedSubviews, dimension); - // // } - // //} - // //else - // //{ - // // subviews = includedSubviews.Where (v => v.Y is PosAlign).ToList (); - // //} - - // //subviewsSize = int.Max (subviewsSize, maxAlign); - // //#endregion Aligned - // #region Auto diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 31982ac8a..f10e831a3 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -78,9 +78,9 @@ public class Dialog : Window X = Pos.Center (); Y = Pos.Center (); - Width = Dim.Auto (DimAutoStyle.Auto, Dim.Percent (DefaultMinimumWidth), Dim.Percent (90)); Height = Dim.Auto (DimAutoStyle.Auto, Dim.Percent (DefaultMinimumHeight), Dim.Percent (90)); + ColorScheme = Colors.ColorSchemes ["Dialog"]; Modal = true; diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 3be8ba4ef..fcdd2d6d2 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -60,6 +60,9 @@ public class FileDialog : Dialog /// This overload is mainly useful for testing. internal FileDialog (IFileSystem fileSystem) { + Height = Dim.Percent (80); + Width = Dim.Percent (80); + // Assume canceled Canceled = true; diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index d46c9314a..4fbfad24a 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -19,8 +19,8 @@ internal class KeyBindingsDialog : Dialog { Title = "Keybindings"; - //Height = 50; - //Width = 10; + Height = Dim.Percent(80); + Width = Dim.Percent(80); if (ViewTracker.Instance == null) { ViewTracker.Initialize (); @@ -32,7 +32,7 @@ internal class KeyBindingsDialog : Dialog _commandsListView = new ListView { Width = Dim.Percent (50), - Height = Dim.Percent (100) - 1, + Height = Dim.Fill () - 1, Source = new ListWrapper (_commands), SelectedItem = 0 }; diff --git a/UICatalog/Scenarios/Dialogs.cs b/UICatalog/Scenarios/Dialogs.cs index f67210417..c960669f4 100644 --- a/UICatalog/Scenarios/Dialogs.cs +++ b/UICatalog/Scenarios/Dialogs.cs @@ -312,7 +312,7 @@ public class Dialogs : Scenario var addChar = new Button { X = Pos.Center (), - Y = Pos.Center () + 1, + Y = Pos.Center () + 2, Text = $"A_dd a {char.ConvertFromUtf32 (CODE_POINT)} to each button. This text is really long for a reason." }; @@ -325,8 +325,9 @@ public class Dialogs : Scenario dialog.LayoutSubviews (); }; - dialog.Closed += (s, e) => { buttonPressedLabel.Text = $"{clicked}"; }; dialog.Add (addChar); + + dialog.Closed += (s, e) => { buttonPressedLabel.Text = $"{clicked}"; }; } catch (FormatException) { diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index 0f45b1e5d..c45fca6a5 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -284,7 +284,7 @@ public class ListColumns : Scenario cancel.Accept += (s, e) => { Application.RequestStop (); }; var d = new Dialog { Title = prompt, Buttons = [ok, cancel] }; - var tf = new TextField { Text = getter (_listColView).ToString (), X = 0, Y = 1, Width = Dim.Fill () }; + var tf = new TextField { Text = getter (_listColView).ToString (), X = 0, Y = 0, Width = Dim.Fill () }; d.Add (tf); tf.SetFocus (); diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index df86aceaf..8dd965e4a 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -1083,13 +1083,16 @@ public class TableEditor : Scenario }; var cancel = new Button { Text = "Cancel" }; cancel.Accept += (s, e) => { Application.RequestStop (); }; - var d = new Dialog { Title = prompt, Buttons = [ok, cancel] }; + var d = new Dialog + { + Title = prompt, + Buttons = [ok, cancel] + }; ColumnStyle style = _tableView.Style.GetOrCreateColumnStyle (col.Value); - var lbl = new Label { X = 0, Y = 1, Text = _tableView.Table.ColumnNames [col.Value] }; - - var tf = new TextField { Text = getter (style).ToString (), X = 0, Y = 2, Width = Dim.Fill () }; + var lbl = new Label { X = 0, Y = 0, Text = $"{_tableView.Table.ColumnNames [col.Value]}: " }; + var tf = new TextField { Text = getter (style).ToString (), X = Pos.Right (lbl), Y = 0, Width = 20 }; d.Add (lbl, tf); tf.SetFocus (); @@ -1461,7 +1464,8 @@ public class TableEditor : Scenario treeSource, _checkedFileSystemInfos.Contains, CheckOrUncheckFile - ) { UseRadioButtons = radio }; + ) + { UseRadioButtons = radio }; } else {