Fixes #134. TextView: Add line wrapping. (#1147)

* Fixes #134. TextView: Add line wrapping.

* Facilitates exception handling in Debug mode.

* Fixes the cursor position if it is always on the same line.

* Fixed TextView column position and hiding the cursor if it is outside outbound frame.

* Added more wrap lines features.. Added a BottomOffset property. Fixed Ctrl+K and Ctrl+Y.

* Fixes the Text property and fixing a redraw behavior not cleaning well at right.

* Fixes Ctrl+K from adding an extra line feed.

* Implemented Ctrl+K and Ctrl-Y on wrapped lines and preventing left Column to be greater than 0 on wrap.

* Fixes more line feed issues.

* More line feed fixing.

* Fixes UpdateModel that must return the new row and new column from the wrapped lines.

* Fixes #1155. MoveForward/MoveBackward not bound on Text controls.

* Added much more features to TextView.

* Fixes ResetPosition and forcing the cursor visibility.

* Implemented the New, Save and SaveAs methods in the Editor.
This commit is contained in:
BDisp
2021-04-01 17:14:14 +01:00
committed by GitHub
parent f1fa8256de
commit 0669e2cc94
5 changed files with 932 additions and 128 deletions

View File

@@ -702,8 +702,13 @@ namespace Terminal.Gui {
var resume = true;
while (resume)
{
try
{
#if DEBUG
resume = false;
var runToken = Begin (view);
RunLoop (runToken);
End (runToken);
#else
try {
resume = false;
var runToken = Begin (view);
RunLoop (runToken);
@@ -717,6 +722,7 @@ namespace Terminal.Gui {
}
resume = errorHandler(error);
}
#endif
}
}

View File

@@ -1471,6 +1471,8 @@ namespace Terminal.Gui {
KeyPress?.Invoke (args);
if (args.Handled)
return true;
if (Focused?.ProcessKey (keyEvent) == true)
return true;
if (subviews == null || subviews.Count == 0)
return false;
foreach (var view in subviews)
@@ -1486,6 +1488,8 @@ namespace Terminal.Gui {
KeyPress?.Invoke (args);
if (args.Handled)
return true;
if (Focused?.ProcessKey (keyEvent) == true)
return true;
if (subviews == null || subviews.Count == 0)
return false;
foreach (var view in subviews)

View File

@@ -389,6 +389,7 @@ namespace Terminal.Gui {
case Key.CursorLeft | Key.ShiftMask | Key.CtrlMask:
case Key.CursorUp | Key.ShiftMask | Key.CtrlMask:
case (Key)((int)'B' + Key.ShiftMask | Key.AltMask):
if (point > 0) {
int x = start > -1 && start > point ? start : point;
if (x > 0) {
@@ -402,6 +403,7 @@ namespace Terminal.Gui {
case Key.CursorRight | Key.ShiftMask | Key.CtrlMask:
case Key.CursorDown | Key.ShiftMask | Key.CtrlMask:
case (Key)((int)'F' + Key.ShiftMask | Key.AltMask):
if (point < text.Count) {
int x = start > -1 && start > point ? start : point;
int sfw = WordForward (x);
@@ -503,7 +505,7 @@ namespace Terminal.Gui {
case Key.CursorLeft | Key.CtrlMask:
case Key.CursorUp | Key.CtrlMask:
case (Key)((int)'b' + Key.AltMask):
case (Key)((int)'B' + Key.AltMask):
ClearAllSelection ();
int bw = WordBackward (point);
if (bw != -1)
@@ -513,7 +515,7 @@ namespace Terminal.Gui {
case Key.CursorRight | Key.CtrlMask:
case Key.CursorDown | Key.CtrlMask:
case (Key)((int)'f' + Key.AltMask):
case (Key)((int)'F' + Key.AltMask):
ClearAllSelection ();
int fw = WordForward (point);
if (fw != -1)
@@ -604,7 +606,7 @@ namespace Terminal.Gui {
}
}
if (i != p)
return i;
return i + 1;
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,7 @@ namespace UICatalog {
private TextView _textView;
private bool _saved = true;
private ScrollBarView _scrollBar;
private byte [] _originalText;
public override void Init (Toplevel top, ColorScheme colorScheme)
{
@@ -28,13 +29,14 @@ namespace UICatalog {
new MenuItem ("_New", "", () => New()),
new MenuItem ("_Open", "", () => Open()),
new MenuItem ("_Save", "", () => Save()),
new MenuItem ("_Save As", "", () => SaveAs()),
null,
new MenuItem ("_Quit", "", () => Quit()),
}),
new MenuBarItem ("_Edit", new MenuItem [] {
new MenuItem ("_Copy", "", () => Copy()),
new MenuItem ("C_ut", "", () => Cut()),
new MenuItem ("_Paste", "", () => Paste())
new MenuItem ("_Copy", "", () => Copy(),null,null, Key.CtrlMask | Key.C),
new MenuItem ("C_ut", "", () => Cut(),null,null, Key.CtrlMask | Key.W),
new MenuItem ("_Paste", "", () => Paste(),null,null, Key.CtrlMask | Key.Y)
}),
new MenuBarItem ("_ScrollBarView", CreateKeepChecked ()),
new MenuBarItem ("_Cursor", new MenuItem [] {
@@ -49,7 +51,8 @@ namespace UICatalog {
new MenuItem (" V_ertical Fix", "", () => SetCursor(CursorVisibility.VerticalFix)),
new MenuItem (" B_ox Fix", "", () => SetCursor(CursorVisibility.BoxFix)),
new MenuItem (" U_nderline Fix","", () => SetCursor(CursorVisibility.UnderlineFix))
})
}),
new MenuBarItem ("Forma_t", CreateWrapChecked ())
});
Top.Add (menu);
@@ -76,7 +79,8 @@ namespace UICatalog {
Y = 0,
Width = Dim.Fill (),
Height = Dim.Fill (),
BottomOffset = 1,
RightOffset = 1
};
LoadFile ();
@@ -102,10 +106,12 @@ namespace UICatalog {
};
_textView.DrawContent += (e) => {
_scrollBar.Size = _textView.Lines - 1;
_scrollBar.Size = _textView.Lines;
_scrollBar.Position = _textView.TopRow;
_scrollBar.OtherScrollBarView.Size = _textView.Maxlength;
_scrollBar.OtherScrollBarView.Position = _textView.LeftColumn;
if (_scrollBar.OtherScrollBarView != null) {
_scrollBar.OtherScrollBarView.Size = _textView.Maxlength;
_scrollBar.OtherScrollBarView.Position = _textView.LeftColumn;
}
_scrollBar.LayoutSubviews ();
_scrollBar.Refresh ();
};
@@ -117,20 +123,23 @@ namespace UICatalog {
private void New ()
{
Win.Title = _fileName = "Untitled";
throw new NotImplementedException ();
if (!CanCloseFile ()) {
return;
}
Win.Title = "Untitled.txt";
_fileName = null;
_originalText = new System.IO.MemoryStream ().ToArray ();
_textView.Text = _originalText;
}
private void LoadFile ()
{
if (!_saved) {
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
}
if (_fileName != null) {
// BUGBUG: #452 TextView.LoadFile keeps file open and provides no way of closing it
//_textView.LoadFile(_fileName);
_textView.Text = System.IO.File.ReadAllText (_fileName);
_originalText = _textView.Text.ToByteArray ();
Win.Title = _fileName;
_saved = true;
}
@@ -138,20 +147,23 @@ namespace UICatalog {
private void Paste ()
{
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
if (_textView != null) {
_textView.Paste ();
}
}
private void Cut ()
{
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
if (_textView != null) {
_textView.Cut ();
}
}
private void Copy ()
{
MessageBox.ErrorQuery ("Not Implemented", "Functionality not yet implemented.", "Ok");
//if (_textView != null && _textView.SelectedLength != 0) {
// _textView.Copy ();
//}
if (_textView != null) {
_textView.Copy ();
}
}
private void SetCursor (CursorVisibility visibility)
@@ -159,8 +171,29 @@ namespace UICatalog {
_textView.DesiredCursorVisibility = visibility;
}
private bool CanCloseFile ()
{
if (_textView.Text == _originalText) {
return true;
}
var r = MessageBox.ErrorQuery ("Save File",
$"Do you want save changes in {Win.Title}?", "Yes", "No", "Cancel");
if (r == 0) {
return Save ();
} else if (r == 1) {
return true;
}
return false;
}
private void Open ()
{
if (!CanCloseFile ()) {
return;
}
var d = new OpenDialog ("Open", "Open a file") { AllowsMultipleSelection = false };
Application.Run (d);
@@ -170,22 +203,62 @@ namespace UICatalog {
}
}
private void Save ()
private bool Save ()
{
if (_fileName != null) {
// 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.
System.IO.File.WriteAllText (_fileName, _textView.Text.ToString());
_saved = true;
return SaveFile (Win.Title.ToString (), _fileName);
} else {
return SaveAs ();
}
}
private bool SaveAs ()
{
var sd = new SaveDialog ("Save file", "Choose the path where to save the file.");
sd.FilePath = System.IO.Path.Combine (sd.FilePath.ToString (), Win.Title.ToString ());
Application.Run (sd);
if (!sd.Canceled) {
if (System.IO.File.Exists (sd.FilePath.ToString ())) {
if (MessageBox.Query ("Save File",
"File already exists. Overwrite any way?", "No", "Ok") == 1) {
return SaveFile (sd.FileName.ToString (), sd.FilePath.ToString ());
} else {
return _saved = false;
}
} else {
return SaveFile (sd.FileName.ToString (), sd.FilePath.ToString ());
}
} else {
return _saved = false;
}
}
private bool SaveFile (string title, string file)
{
try {
Win.Title = title;
_fileName = file;
System.IO.File.WriteAllText (_fileName, _textView.Text.ToString ());
_saved = true;
MessageBox.Query ("Save File", "File was successfully saved.", "Ok");
} catch (Exception ex) {
MessageBox.ErrorQuery ("Error", ex.Message, "Ok");
return false;
}
return true;
}
private void Quit ()
{
Application.RequestStop ();
}
private void CreateDemoFile(string fileName)
private void CreateDemoFile (string fileName)
{
var sb = new StringBuilder ();
// BUGBUG: #279 TextView does not know how to deal with \r\n, only \r
@@ -211,6 +284,27 @@ namespace UICatalog {
return new MenuItem [] { item };
}
private MenuItem [] CreateWrapChecked ()
{
var item = new MenuItem ();
item.Title = "Word Wrap";
item.CheckType |= MenuItemCheckStyle.Checked;
item.Checked = false;
item.Action += () => {
_textView.WordWrap = item.Checked = !item.Checked;
if (_textView.WordWrap) {
_scrollBar.AutoHideScrollBars = false;
_scrollBar.OtherScrollBarView.ShowScrollIndicator = false;
_textView.BottomOffset = 0;
} else {
_scrollBar.AutoHideScrollBars = true;
_textView.BottomOffset = 1;
}
};
return new MenuItem [] { item };
}
public override void Run ()
{
base.Run ();