Upgraded Editeor Scenario

This commit is contained in:
Tig
2024-06-09 09:43:23 -06:00
parent 329cbbf699
commit 8d6436cc81

View File

@@ -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<CultureInfo> _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);