From 8d6436cc8120e08b736e791d124fc4c0d3883b8a Mon Sep 17 00:00:00 2001 From: Tig Date: Sun, 9 Jun 2024 09:43:23 -0600 Subject: [PATCH] Upgraded Editeor Scenario --- UICatalog/Scenarios/Editor.cs | 294 +++++++++++++++------------------- 1 file changed, 133 insertions(+), 161 deletions(-) diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index b5fa7fe7f..d82e5bd85 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -8,6 +8,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; using Terminal.Gui; +using static UICatalog.Scenarios.DynamicMenuBar; namespace UICatalog.Scenarios; @@ -18,8 +19,10 @@ namespace UICatalog.Scenarios; [ScenarioCategory ("Top Level Windows")] [ScenarioCategory ("Files and IO")] [ScenarioCategory ("TextView")] +[ScenarioCategory ("Menus")] public class Editor : Scenario { + private Window _appWindow; private List _cultureInfos; private string _fileName = "demo.txt"; private bool _forceMinimumPosToZero = true; @@ -33,41 +36,36 @@ public class Editor : Scenario private string _textToFind; private string _textToReplace; private TextView _textView; - private Window _winDialog; + private FindReplaceWindow _findReplaceWindow; - public override void Init () + public override void Main () { + // Init Application.Init (); - _cultureInfos = Application.SupportedCultures; - ConfigurationManager.Themes.Theme = Theme; - ConfigurationManager.Apply (); - Top = new (); - - Win = new() + // Setup - Create a top-level application window and configure it. + _appWindow = new () { + //Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", Title = _fileName ?? "Untitled", + BorderStyle = LineStyle.None + }; + + _cultureInfos = Application.SupportedCultures; + + _textView = new () + { X = 0, Y = 1, Width = Dim.Fill (), - Height = Dim.Fill (), - ColorScheme = Colors.ColorSchemes [TopLevelColorScheme] - }; - Top.Add (Win); - - _textView = new() - { - X = 0, - Y = 0, - Width = Dim.Fill (), - Height = Dim.Fill () + Height = Dim.Fill (1), }; CreateDemoFile (_fileName); LoadFile (); - Win.Add (_textView); + _appWindow.Add (_textView); var menu = new MenuBar { @@ -238,7 +236,7 @@ public class Editor : Scenario ] }; - Top.Add (menu); + _appWindow.Add (menu); var siCursorPosition = new StatusItem (KeyCode.Null, "", null); @@ -267,7 +265,7 @@ public class Editor : Scenario siCursorPosition.Title = $"Ln {e.Point.Y + 1}, Col {e.Point.X + 1}"; }; - Top.Add (statusBar); + _appWindow.Add (statusBar); _scrollBar = new (_textView, true); @@ -310,50 +308,19 @@ public class Editor : Scenario _scrollBar.Refresh (); }; - Win.KeyDown += (s, e) => - { - if (_winDialog != null && (e.KeyCode == KeyCode.Esc || e == Application.QuitKey)) - { - DisposeWinDialog (); - } - else if (e == Application.QuitKey) - { - Quit (); - e.Handled = true; - } - else if (_winDialog != null && e.KeyCode == (KeyCode.Tab | KeyCode.CtrlMask)) - { - if (_tabView.SelectedTab == _tabView.Tabs.ElementAt (_tabView.Tabs.Count - 1)) - { - _tabView.SelectedTab = _tabView.Tabs.ElementAt (0); - } - else - { - _tabView.SwitchTabBy (1); - } - e.Handled = true; - } - else if (_winDialog != null && e.KeyCode == (KeyCode.Tab | KeyCode.CtrlMask | KeyCode.ShiftMask)) - { - if (_tabView.SelectedTab == _tabView.Tabs.ElementAt (0)) - { - _tabView.SelectedTab = _tabView.Tabs.ElementAt (_tabView.Tabs.Count - 1); - } - else - { - _tabView.SwitchTabBy (-1); - } + _appWindow.Closed += (s, e) => Thread.CurrentThread.CurrentUICulture = new ("en-US"); - e.Handled = true; - } - }; - Top.Closed += (s, e) => Thread.CurrentThread.CurrentUICulture = new ("en-US"); + // Run - Start the application. + Application.Run (_appWindow); + _appWindow.Dispose (); + + // Shutdown - Calling Application.Shutdown is required. + Application.Shutdown (); + } - public override void Setup () { } - private bool CanCloseFile () { if (_textView.Text == Encoding.Unicode.GetString (_originalText)) @@ -366,7 +333,7 @@ public class Editor : Scenario int r = MessageBox.ErrorQuery ( "Save File", - $"Do you want save changes in {Win.Title}?", + $"Do you want save changes in {_appWindow.Title}?", "Yes", "No", "Cancel" @@ -414,7 +381,7 @@ public class Editor : Scenario if (replace && (string.IsNullOrEmpty (_textToFind) - || (_winDialog == null && string.IsNullOrEmpty (_textToReplace)))) + || (_findReplaceWindow == null && string.IsNullOrEmpty (_textToReplace)))) { Replace (); @@ -689,11 +656,7 @@ public class Editor : Scenario for (var i = 0; i < 30; i++) { sb.Append ( - $"{ - i - } - This is a test with a very long line and many lines to test the ScrollViewBar against the TextView. - { - i - }\n" + $"{i} - This is a test with a very long line and many lines to test the ScrollViewBar against the TextView. - {i}\n" ); } @@ -721,38 +684,76 @@ public class Editor : Scenario return item; } + private class FindReplaceWindow : Window + { + private TextView _textView; + public FindReplaceWindow (TextView textView) + { + _textView = textView; + X = Pos.AnchorEnd (); + Y = 0; + Width = 55; + Height = 12; + Arrangement = ViewArrangement.Movable; + + KeyBindings.Add (Key.Esc, KeyBindingScope.Focused, Command.Cancel); + AddCommand (Command.Cancel, () => + { + Visible = false; + + return true; + }); + VisibleChanged += FindReplaceWindow_VisibleChanged; + Initialized += FindReplaceWindow_Initialized; + } + + private void FindReplaceWindow_VisibleChanged (object sender, EventArgs e) + { + if (Visible == false) + { + _textView.SetFocus (); + } + } + + private void FindReplaceWindow_Initialized (object sender, EventArgs e) + { + Border.LineStyle = LineStyle.Dashed; + Border.Thickness = new (1, 2, 1, 1); + } + } + private void CreateFindReplace (bool isFind = true) { - if (_winDialog != null) + if (_findReplaceWindow != null) { - _winDialog.SetFocus (); - + _findReplaceWindow.Visible = true; + _findReplaceWindow.SetFocus (); + _findReplaceWindow.Title = isFind ? "Find" : "Replace"; + _tabView.SelectedTab = isFind ? _tabView.Tabs.ToArray () [0] : _tabView.Tabs.ToArray () [1]; + _tabView.SelectedTab.View.FocusFirst (); return; } - _winDialog = new() + _findReplaceWindow = new (_textView) { Title = isFind ? "Find" : "Replace", - X = Win.Viewport.Width / 2 - 30, - Y = Win.Viewport.Height / 2 - 10, - ColorScheme = Colors.ColorSchemes ["TopLevel"] + }; + _tabView = new () + { + X = 0, Y = 0, + Width = Dim.Fill (), Height = Dim.Fill () }; - _tabView = new() { X = 0, Y = 0, Width = Dim.Fill (), Height = Dim.Fill () }; - - _tabView.AddTab (new() { DisplayText = "Find", View = FindTab () }, isFind); + _tabView.AddTab (new () { DisplayText = "Find", View = FindTab () }, isFind); View replace = ReplaceTab (); - _tabView.AddTab (new() { DisplayText = "Replace", View = replace }, !isFind); + _tabView.AddTab (new () { DisplayText = "Replace", View = replace }, !isFind); _tabView.SelectedTabChanged += (s, e) => _tabView.SelectedTab.View.FocusFirst (); - _winDialog.Add (_tabView); + _findReplaceWindow.Add (_tabView); - Win.Add (_winDialog); + _appWindow.Add (_findReplaceWindow); - _winDialog.Width = replace.Width + 4; - _winDialog.Height = replace.Height + 4; - - _winDialog.SuperView.BringSubviewToFront (_winDialog); - _winDialog.SetFocus (); + _findReplaceWindow.SuperView.BringSubviewToFront (_findReplaceWindow); + _findReplaceWindow.SetFocus (); } private MenuItem [] CreateKeepChecked () @@ -822,34 +823,22 @@ public class Editor : Scenario } } - private void DisposeWinDialog () - { - _winDialog.Dispose (); - Win.Remove (_winDialog); - _winDialog = null; - } - private void Find () { CreateFindReplace (); } private void FindNext () { ContinueFind (); } private void FindPrevious () { ContinueFind (false); } private View FindTab () { - var d = new View (); - - d.DrawContent += (s, e) => - { - foreach (View v in d.Subviews) - { - v.SetNeedsDisplay (); - } - }; + var d = new View () + { + Width = Dim.Fill (), + Height = Dim.Fill () + }; int lblWidth = "Replace:".Length; var label = new Label { - Y = 1, Width = lblWidth, TextAlignment = Alignment.End, @@ -861,18 +850,19 @@ public class Editor : Scenario var txtToFind = new TextField { - X = Pos.Right (label) + 1, Y = Pos.Top (label), Width = 20, Text = _textToFind + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = 20, + Text = _textToFind }; txtToFind.Enter += (s, e) => txtToFind.Text = _textToFind; d.Add (txtToFind); var btnFindNext = new Button { - X = Pos.Right (txtToFind) + 1, + X = Pos.AnchorEnd (), Y = Pos.Top (label), - Width = 20, Enabled = !string.IsNullOrEmpty (txtToFind.Text), - TextAlignment = Alignment.Center, IsDefault = true, Text = "Find _Next" @@ -882,12 +872,9 @@ public class Editor : Scenario var btnFindPrevious = new Button { - X = Pos.Right (txtToFind) + 1, + X = Pos.AnchorEnd (), Y = Pos.Top (btnFindNext) + 1, - Width = 20, Enabled = !string.IsNullOrEmpty (txtToFind.Text), - TextAlignment = Alignment.Center, - Text = "Find _Previous" }; btnFindPrevious.Accept += (s, e) => FindPrevious (); @@ -903,14 +890,11 @@ public class Editor : Scenario var btnCancel = new Button { - X = Pos.Right (txtToFind) + 1, - Y = Pos.Top (btnFindPrevious) + 2, - Width = 20, - TextAlignment = Alignment.Center, - + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), Text = "Cancel" }; - btnCancel.Accept += (s, e) => { DisposeWinDialog (); }; + btnCancel.Accept += (s, e) => { _findReplaceWindow.Visible = false; }; d.Add (btnCancel); var ckbMatchCase = new CheckBox @@ -927,9 +911,6 @@ public class Editor : Scenario ckbMatchWholeWord.Toggled += (s, e) => _matchWholeWord = (bool)ckbMatchWholeWord.Checked; d.Add (ckbMatchWholeWord); - d.Width = label.Width + txtToFind.Width + btnFindNext.Width + 2; - d.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4; - return d; } @@ -950,7 +931,7 @@ public class Editor : Scenario CreateAction (supportedCultures, culture); supportedCultures.Add (culture); index++; - culture = new() { CheckType = MenuItemCheckStyle.Checked }; + culture = new () { CheckType = MenuItemCheckStyle.Checked }; } culture.Title = $"_{c.Parent.EnglishName}"; @@ -986,7 +967,7 @@ public class Editor : Scenario //_textView.Text = System.IO.File.ReadAllText (_fileName); _originalText = Encoding.Unicode.GetBytes (_textView.Text); - Win.Title = _fileName; + _appWindow.Title = _fileName; _saved = true; } } @@ -998,7 +979,7 @@ public class Editor : Scenario return; } - Win.Title = "Untitled.txt"; + _appWindow.Title = "Untitled.txt"; _fileName = null; _originalText = new MemoryStream ().ToArray (); _textView.Text = Encoding.Unicode.GetString (_originalText); @@ -1057,7 +1038,7 @@ public class Editor : Scenario private void ReplaceAll () { - if (string.IsNullOrEmpty (_textToFind) || (string.IsNullOrEmpty (_textToReplace) && _winDialog == null)) + if (string.IsNullOrEmpty (_textToFind) || (string.IsNullOrEmpty (_textToReplace) && _findReplaceWindow == null)) { Replace (); @@ -1087,21 +1068,16 @@ public class Editor : Scenario private View ReplaceTab () { - var d = new View (); - - d.DrawContent += (s, e) => - { - foreach (View v in d.Subviews) - { - v.SetNeedsDisplay (); - } - }; + var d = new View () + { + Width = Dim.Fill (), + Height = Dim.Fill () + }; int lblWidth = "Replace:".Length; var label = new Label { - Y = 1, Width = lblWidth, TextAlignment = Alignment.End, @@ -1113,45 +1089,50 @@ public class Editor : Scenario var txtToFind = new TextField { - X = Pos.Right (label) + 1, Y = Pos.Top (label), Width = 20, Text = _textToFind + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = 20, + Text = _textToFind }; txtToFind.Enter += (s, e) => txtToFind.Text = _textToFind; d.Add (txtToFind); var btnFindNext = new Button { - X = Pos.Right (txtToFind) + 1, + X = Pos.AnchorEnd (), Y = Pos.Top (label), - Width = 20, Enabled = !string.IsNullOrEmpty (txtToFind.Text), - TextAlignment = Alignment.Center, IsDefault = true, - Text = "Replace _Next" }; btnFindNext.Accept += (s, e) => ReplaceNext (); d.Add (btnFindNext); - label = new() { X = Pos.Left (label), Y = Pos.Top (label) + 1, Text = "Replace:" }; + label = new () + { + X = Pos.Left (label), + Y = Pos.Top (label) + 1, + Text = "Replace:" + }; d.Add (label); SetFindText (); var txtToReplace = new TextField { - X = Pos.Right (label) + 1, Y = Pos.Top (label), Width = 20, Text = _textToReplace + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = 20, + Text = _textToReplace }; txtToReplace.TextChanged += (s, e) => _textToReplace = txtToReplace.Text; d.Add (txtToReplace); var btnFindPrevious = new Button { - X = Pos.Right (txtToFind) + 1, + X = Pos.AnchorEnd (), Y = Pos.Top (btnFindNext) + 1, - Width = 20, Enabled = !string.IsNullOrEmpty (txtToFind.Text), - TextAlignment = Alignment.Center, - Text = "Replace _Previous" }; btnFindPrevious.Accept += (s, e) => ReplacePrevious (); @@ -1159,12 +1140,9 @@ public class Editor : Scenario var btnReplaceAll = new Button { - X = Pos.Right (txtToFind) + 1, + X = Pos.AnchorEnd (), Y = Pos.Top (btnFindPrevious) + 1, - Width = 20, Enabled = !string.IsNullOrEmpty (txtToFind.Text), - TextAlignment = Alignment.Center, - Text = "Replace _All" }; btnReplaceAll.Accept += (s, e) => ReplaceAll (); @@ -1181,14 +1159,11 @@ public class Editor : Scenario var btnCancel = new Button { - X = Pos.Right (txtToFind) + 1, - Y = Pos.Top (btnReplaceAll) + 1, - Width = 20, - TextAlignment = Alignment.Center, - + X = Pos.AnchorEnd (), + Y = Pos.AnchorEnd (), Text = "Cancel" }; - btnCancel.Accept += (s, e) => { DisposeWinDialog (); }; + btnCancel.Accept += (s, e) => { _findReplaceWindow.Visible = false; }; d.Add (btnCancel); var ckbMatchCase = new CheckBox @@ -1205,9 +1180,6 @@ public class Editor : Scenario ckbMatchWholeWord.Toggled += (s, e) => _matchWholeWord = (bool)ckbMatchWholeWord.Checked; d.Add (ckbMatchWholeWord); - d.Width = lblWidth + txtToFind.Width + btnFindNext.Width + 2; - d.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4; - return d; } @@ -1217,7 +1189,7 @@ public class Editor : Scenario { // FIXED: BUGBUG: #279 TextView does not know how to deal with \r\n, only \r // As a result files saved on Windows and then read back will show invalid chars. - return SaveFile (Win.Title, _fileName); + return SaveFile (_appWindow.Title, _fileName); } return SaveAs (); @@ -1231,7 +1203,7 @@ public class Editor : Scenario }; var sd = new SaveDialog { Title = "Save file", AllowedTypes = aTypes }; - sd.Path = Win.Title; + sd.Path = _appWindow.Title; Application.Run (sd); bool canceled = sd.Canceled; string path = sd.Path; @@ -1270,7 +1242,7 @@ public class Editor : Scenario { try { - Win.Title = title; + _appWindow.Title = title; _fileName = file; File.WriteAllText (_fileName, _textView.Text); _originalText = Encoding.Unicode.GetBytes (_textView.Text);