mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
* Fixes #1133. Flaw in LayoutSubviews/TopologicalSort. * Toplevel can't be used on Pos/Dim but only his subviews. Was not caught before because the LayoutSubviews method never gone so deep before. * Fixed the error that is triggered when the Pos/Dim is the current Application.Top. * Application.Top is the only exception in the TopologicalSort method check. * Fixes #1179. TextView does not copy to the clipboard on deleting. * Added Button DoubleClick and fixed WordForward/WordBackward issues. * Prevents a negative height. * Fixes the enter key line feed. * Fixes #1187. Prevents WordBackward throwing an exception if point is greater than the text length. * Fixes #1189. Prevents negative index. * Fixes #1193. A non auto size default Button now preserves his width and thus the text alignment now work. * Fixing the Width and Height checks of the Dim class with AutoSize dependence. * Fixes #1197. Prevents width negative value if added directly to the Application.Top * Fixes #1199. Normalize views constructors and did some typo fixing. * Fixing the Application.Top Pos/Dim settings. * Always uses inverted color for selected text to avoid same colors. * Prevents throw an exception if the clipboard content is null. * Added Find and Replace (next/previous). Replace All and Select All. A non modal dialog box. * Keeps tracking the selected replaced text. * Fixes #1202. CheckBox now deals with a functional '_' underscore hotkey. * The selected text should be maintained when losing focus. * Fixes an extra line on page down. * Fixes the WordBackward if it text has more than one whitespaces or when has only one digit or letter. * Fixes WordForward/WordBackward on text with more than one whitespace or with only one digit or letter. * Forgot to replace the hacking. * Added unit tests for the TextField view. Fixed some more bugs. * Redraw should only show the selected text if it is focused. * Fixes cursor position on double click and ensures the setting of the selected text. * Added match whole word checking. * Added missing parameters documentation. * Ensures the SelectedLength property to be always with positive value. * Fixes the WordBackward when at the end of the text has a character between two whitespace. * Added unit tests to the TextView, Used property and fixed some more bugs. * Fixed Used to only show if it has focus. * Fixed ReplaceAll and prevents Debug.Assert from showing.
This commit is contained in:
@@ -36,7 +36,7 @@ namespace Terminal.Gui {
|
||||
return 0;
|
||||
}
|
||||
|
||||
class PosFactor : Pos {
|
||||
internal class PosFactor : Pos {
|
||||
float factor;
|
||||
|
||||
public PosFactor (float n)
|
||||
@@ -82,7 +82,7 @@ namespace Terminal.Gui {
|
||||
|
||||
static PosAnchorEnd endNoMargin;
|
||||
|
||||
class PosAnchorEnd : Pos {
|
||||
internal class PosAnchorEnd : Pos {
|
||||
int n;
|
||||
|
||||
public PosAnchorEnd (int n)
|
||||
@@ -205,8 +205,8 @@ namespace Terminal.Gui {
|
||||
return new PosAbsolute (n);
|
||||
}
|
||||
|
||||
class PosCombine : Pos {
|
||||
Pos left, right;
|
||||
internal class PosCombine : Pos {
|
||||
internal Pos left, right;
|
||||
bool add;
|
||||
public PosCombine (bool add, Pos left, Pos right)
|
||||
{
|
||||
@@ -500,7 +500,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
|
||||
internal class DimCombine : Dim {
|
||||
Dim left, right;
|
||||
internal Dim left, right;
|
||||
bool add;
|
||||
public DimCombine (bool add, Dim left, Dim right)
|
||||
{
|
||||
|
||||
@@ -625,7 +625,8 @@ namespace Terminal.Gui {
|
||||
Application.Driver?.AddRune (rune);
|
||||
}
|
||||
col += Rune.ColumnWidth (rune);
|
||||
if (idx + 1 < runes.Length && col + Rune.ColumnWidth (runes [idx + 1]) > bounds.Width) {
|
||||
if (idx + 1 > - 1 && idx + 1 < runes.Length && col
|
||||
+ Rune.ColumnWidth (runes [idx + 1]) > bounds.Width) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ namespace Terminal.Gui {
|
||||
l = SuperView.Frame.Width;
|
||||
}
|
||||
nx = nx + top.Frame.Width > l ? Math.Max (l - top.Frame.Width, 0) : nx;
|
||||
SetWidth (top.Frame.Width, out int rWidth);
|
||||
SetWidth (top.Frame.Width, out int rWidth, out _);
|
||||
if (rWidth < 0 && nx >= top.Frame.X) {
|
||||
nx = Math.Max (top.Frame.Right - 2, 0);
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace Terminal.Gui {
|
||||
}
|
||||
ny = Math.Min (ny, l);
|
||||
ny = ny + top.Frame.Height > l ? Math.Max (l - top.Frame.Height, m ? 1 : 0) : ny;
|
||||
SetHeight (top.Frame.Height, out int rHeight);
|
||||
SetHeight (top.Frame.Height, out int rHeight, out _);
|
||||
if (rHeight < 0 && ny >= top.Frame.Y) {
|
||||
ny = Math.Max (top.Frame.Bottom - 2, 0);
|
||||
}
|
||||
|
||||
@@ -1753,7 +1753,7 @@ namespace Terminal.Gui {
|
||||
var result = new List<View> ();
|
||||
|
||||
// Set of all nodes with no incoming edges
|
||||
var S = new HashSet<View> (nodes.Where (n => edges.All (e => e.To.Equals (n) == false)));
|
||||
var S = new HashSet<View> (nodes.Where (n => edges.All (e => !e.To.Equals (n))));
|
||||
|
||||
while (S.Any ()) {
|
||||
// remove a node n from S
|
||||
@@ -1772,15 +1772,15 @@ namespace Terminal.Gui {
|
||||
edges.Remove (e);
|
||||
|
||||
// if m has no other incoming edges then
|
||||
if (edges.All (me => me.To.Equals (m) == false) && m != this?.SuperView) {
|
||||
if (edges.All (me => !me.To.Equals (m)) && m != this?.SuperView) {
|
||||
// insert m into S
|
||||
S.Add (m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (edges.Any ()) {
|
||||
if (!object.ReferenceEquals (edges.First ().From, edges.First ().To)) {
|
||||
if (edges.Any () && edges.First ().From != Application.Top) {
|
||||
if (!ReferenceEquals (edges.First ().From, edges.First ().To)) {
|
||||
throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {edges.First ().From}. Did you forget to add it to {this}?");
|
||||
} else {
|
||||
throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
|
||||
@@ -1863,20 +1863,60 @@ namespace Terminal.Gui {
|
||||
var nodes = new HashSet<View> ();
|
||||
var edges = new HashSet<(View, View)> ();
|
||||
|
||||
foreach (var v in InternalSubviews) {
|
||||
nodes.Add (v);
|
||||
if (v.LayoutStyle == LayoutStyle.Computed) {
|
||||
if (v.X is Pos.PosView vX)
|
||||
edges.Add ((vX.Target, v));
|
||||
if (v.Y is Pos.PosView vY)
|
||||
edges.Add ((vY.Target, v));
|
||||
if (v.Width is Dim.DimView vWidth)
|
||||
edges.Add ((vWidth.Target, v));
|
||||
if (v.Height is Dim.DimView vHeight)
|
||||
edges.Add ((vHeight.Target, v));
|
||||
void CollectPos (Pos pos, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
{
|
||||
if (pos is Pos.PosView pv) {
|
||||
if (pv.Target != this) {
|
||||
nEdges.Add ((pv.Target, from));
|
||||
}
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectAll (v, ref nNodes, ref nEdges);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (pos is Pos.PosCombine pc) {
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectPos (pc.left, from, ref nNodes, ref nEdges);
|
||||
CollectPos (pc.right, from, ref nNodes, ref nEdges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollectDim (Dim dim, View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
{
|
||||
if (dim is Dim.DimView dv) {
|
||||
if (dv.Target != this) {
|
||||
nEdges.Add ((dv.Target, from));
|
||||
}
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectAll (v, ref nNodes, ref nEdges);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (dim is Dim.DimCombine dc) {
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
CollectDim (dc.left, from, ref nNodes, ref nEdges);
|
||||
CollectDim (dc.right, from, ref nNodes, ref nEdges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CollectAll (View from, ref HashSet<View> nNodes, ref HashSet<(View, View)> nEdges)
|
||||
{
|
||||
foreach (var v in from.InternalSubviews) {
|
||||
nNodes.Add (v);
|
||||
if (v.layoutStyle != LayoutStyle.Computed) {
|
||||
continue;
|
||||
}
|
||||
CollectPos (v.X, v, ref nNodes, ref nEdges);
|
||||
CollectPos (v.Y, v, ref nNodes, ref nEdges);
|
||||
CollectDim (v.Width, v, ref nNodes, ref nEdges);
|
||||
CollectDim (v.Height, v, ref nNodes, ref nEdges);
|
||||
}
|
||||
}
|
||||
|
||||
CollectAll (this, ref nodes, ref edges);
|
||||
|
||||
var ordered = TopologicalSort (nodes, edges);
|
||||
|
||||
foreach (var v in ordered) {
|
||||
@@ -1886,7 +1926,6 @@ namespace Terminal.Gui {
|
||||
|
||||
v.LayoutSubviews ();
|
||||
v.LayoutNeeded = false;
|
||||
|
||||
}
|
||||
|
||||
if (SuperView == Application.Top && LayoutNeeded && ordered.Count == 0 && LayoutStyle == LayoutStyle.Computed) {
|
||||
@@ -2154,14 +2193,17 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
/// <param name="desiredWidth">The desired width.</param>
|
||||
/// <param name="resultWidth">The real result width.</param>
|
||||
/// <param name="currentWidth">The real current width.</param>
|
||||
/// <returns>True if the width can be directly assigned, false otherwise.</returns>
|
||||
public bool SetWidth (int desiredWidth, out int resultWidth)
|
||||
public bool SetWidth (int desiredWidth, out int resultWidth, out int currentWidth)
|
||||
{
|
||||
int w = desiredWidth;
|
||||
currentWidth = Width != null ? Width.Anchor (0) : 0;
|
||||
bool canSetWidth;
|
||||
if (Width is Dim.DimCombine || Width is Dim.DimView || Width is Dim.DimFill) {
|
||||
// It's a Dim.DimCombine and so can't be assigned. Let it have it's width anchored.
|
||||
w = Width.Anchor (w);
|
||||
currentWidth = Width.Anchor (w);
|
||||
canSetWidth = false;
|
||||
} else if (Width is Dim.DimFactor factor) {
|
||||
// Tries to get the SuperView width otherwise the view width.
|
||||
@@ -2170,6 +2212,7 @@ namespace Terminal.Gui {
|
||||
sw -= Frame.X;
|
||||
}
|
||||
w = Width.Anchor (sw);
|
||||
currentWidth = Width.Anchor (sw);
|
||||
canSetWidth = false;
|
||||
} else {
|
||||
canSetWidth = true;
|
||||
@@ -2184,14 +2227,17 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
/// <param name="desiredHeight">The desired height.</param>
|
||||
/// <param name="resultHeight">The real result height.</param>
|
||||
/// <param name="currentHeight">The real current height.</param>
|
||||
/// <returns>True if the height can be directly assigned, false otherwise.</returns>
|
||||
public bool SetHeight (int desiredHeight, out int resultHeight)
|
||||
public bool SetHeight (int desiredHeight, out int resultHeight, out int currentHeight)
|
||||
{
|
||||
int h = desiredHeight;
|
||||
currentHeight = Height != null ? Height.Anchor (0) : 0;
|
||||
bool canSetHeight;
|
||||
if (Height is Dim.DimCombine || Height is Dim.DimView || Height is Dim.DimFill) {
|
||||
// It's a Dim.DimCombine and so can't be assigned. Let it have it's height anchored.
|
||||
h = Height.Anchor (h);
|
||||
currentHeight = Height.Anchor (h);
|
||||
canSetHeight = false;
|
||||
} else if (Height is Dim.DimFactor factor) {
|
||||
// Tries to get the SuperView height otherwise the view height.
|
||||
@@ -2200,6 +2246,7 @@ namespace Terminal.Gui {
|
||||
sh -= Frame.Y;
|
||||
}
|
||||
h = Height.Anchor (sh);
|
||||
currentHeight = Height.Anchor (sh);
|
||||
canSetHeight = false;
|
||||
} else {
|
||||
canSetHeight = true;
|
||||
|
||||
@@ -146,10 +146,13 @@ namespace Terminal.Gui {
|
||||
base.Text = ustring.Make (_leftBracket) + " " + text + " " + ustring.Make (_rightBracket);
|
||||
|
||||
int w = base.Text.RuneCount - (base.Text.Contains (HotKeySpecifier) ? 1 : 0);
|
||||
if (SetWidth (w, out int rWidth)) {
|
||||
var canSetWidth = SetWidth (w, out int rWidth, out int cWidth);
|
||||
if (canSetWidth && (cWidth < rWidth || AutoSize)) {
|
||||
Width = rWidth;
|
||||
w = rWidth;
|
||||
} else if (!canSetWidth || !AutoSize) {
|
||||
w = cWidth;
|
||||
}
|
||||
w = rWidth;
|
||||
var layout = LayoutStyle;
|
||||
bool layoutChanged = false;
|
||||
if (!(Height is Dim.DimAbsolute)) {
|
||||
|
||||
@@ -279,6 +279,184 @@ namespace Terminal.Gui {
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
(Point startPointToFind, Point currentPointToFind, bool found) toFind;
|
||||
|
||||
internal (Point current, bool found) FindNextText (ustring text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false)
|
||||
{
|
||||
if (text == null || lines.Count == 0) {
|
||||
gaveFullTurn = false;
|
||||
return (Point.Empty, false);
|
||||
}
|
||||
|
||||
if (toFind.found) {
|
||||
toFind.currentPointToFind.X++;
|
||||
}
|
||||
var foundPos = GetFoundNextTextPoint (text, lines.Count, matchCase, matchWholeWord, toFind.currentPointToFind);
|
||||
if (!foundPos.found && toFind.currentPointToFind != toFind.startPointToFind) {
|
||||
foundPos = GetFoundNextTextPoint (text, toFind.startPointToFind.Y + 1, matchCase, matchWholeWord, Point.Empty);
|
||||
}
|
||||
gaveFullTurn = ApplyToFind (foundPos);
|
||||
|
||||
return foundPos;
|
||||
}
|
||||
|
||||
internal (Point current, bool found) FindPreviousText (ustring text, out bool gaveFullTurn, bool matchCase = false, bool matchWholeWord = false)
|
||||
{
|
||||
if (text == null || lines.Count == 0) {
|
||||
gaveFullTurn = false;
|
||||
return (Point.Empty, false);
|
||||
}
|
||||
|
||||
if (toFind.found) {
|
||||
toFind.currentPointToFind.X++;
|
||||
}
|
||||
var foundPos = GetFoundPreviousTextPoint (text, toFind.currentPointToFind.Y, matchCase, matchWholeWord, toFind.currentPointToFind);
|
||||
if (!foundPos.found && toFind.currentPointToFind != toFind.startPointToFind) {
|
||||
foundPos = GetFoundPreviousTextPoint (text, lines.Count - 1, matchCase, matchWholeWord,
|
||||
new Point (lines [lines.Count - 1].Count, lines.Count));
|
||||
}
|
||||
gaveFullTurn = ApplyToFind (foundPos);
|
||||
|
||||
return foundPos;
|
||||
}
|
||||
|
||||
internal (Point current, bool found) ReplaceAllText (ustring text, bool matchCase = false, bool matchWholeWord = false, ustring textToReplace = null)
|
||||
{
|
||||
bool found = false;
|
||||
Point pos = Point.Empty;
|
||||
|
||||
for (int i = 0; i < lines.Count; i++) {
|
||||
var x = lines [i];
|
||||
var txt = ustring.Make (x).ToString ();
|
||||
if (!matchCase) {
|
||||
txt = txt.ToUpper ();
|
||||
}
|
||||
var matchText = !matchCase ? text.ToUpper ().ToString () : text.ToString ();
|
||||
var col = txt.IndexOf (matchText);
|
||||
if (col > -1 && matchWholeWord && !MatchWholeWord (txt, matchText, col)) {
|
||||
continue;
|
||||
}
|
||||
if (col > -1) {
|
||||
if (!found) {
|
||||
found = true;
|
||||
}
|
||||
pos = new Point (col, i);
|
||||
lines [i] = ReplaceText (x, textToReplace, matchText, col).ToRuneList ();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return (pos, found);
|
||||
}
|
||||
|
||||
ustring ReplaceText (List<Rune> source, ustring textToReplace, string matchText, int col)
|
||||
{
|
||||
var origTxt = ustring.Make (source);
|
||||
(int _, int len) = TextModel.DisplaySize (source, 0, col, false);
|
||||
(var _, var len2) = TextModel.DisplaySize (source, col, col + matchText.Length, false);
|
||||
(var _, var len3) = TextModel.DisplaySize (source, col + matchText.Length, origTxt.RuneCount, false);
|
||||
|
||||
return origTxt [0, len] +
|
||||
textToReplace.ToString () +
|
||||
origTxt [len + len2, len + len2 + len3];
|
||||
}
|
||||
|
||||
bool ApplyToFind ((Point current, bool found) foundPos)
|
||||
{
|
||||
bool gaveFullTurn = false;
|
||||
if (foundPos.found) {
|
||||
toFind.currentPointToFind = foundPos.current;
|
||||
if (toFind.found && toFind.currentPointToFind == toFind.startPointToFind) {
|
||||
gaveFullTurn = true;
|
||||
}
|
||||
if (!toFind.found) {
|
||||
toFind.startPointToFind = toFind.currentPointToFind = foundPos.current;
|
||||
toFind.found = foundPos.found;
|
||||
}
|
||||
}
|
||||
|
||||
return gaveFullTurn;
|
||||
}
|
||||
|
||||
(Point current, bool found) GetFoundNextTextPoint (ustring text, int linesCount, bool matchCase, bool matchWholeWord, Point start)
|
||||
{
|
||||
for (int i = start.Y; i < linesCount; i++) {
|
||||
var x = lines [i];
|
||||
var txt = ustring.Make (x).ToString ();
|
||||
if (!matchCase) {
|
||||
txt = txt.ToUpper ();
|
||||
}
|
||||
var matchText = !matchCase ? text.ToUpper ().ToString () : text.ToString ();
|
||||
var col = txt.IndexOf (matchText, Math.Min (start.X, txt.Length));
|
||||
if (col > -1 && matchWholeWord && !MatchWholeWord (txt, matchText, col)) {
|
||||
continue;
|
||||
}
|
||||
if (col > -1 && ((i == start.Y && col >= start.X)
|
||||
|| i > start.Y)
|
||||
&& txt.Contains (matchText)) {
|
||||
return (new Point (col, i), true);
|
||||
} else if (col == -1 && start.X > 0) {
|
||||
start.X = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (Point.Empty, false);
|
||||
}
|
||||
|
||||
(Point current, bool found) GetFoundPreviousTextPoint (ustring text, int linesCount, bool matchCase, bool matchWholeWord, Point start)
|
||||
{
|
||||
for (int i = linesCount; i >= 0; i--) {
|
||||
var x = lines [i];
|
||||
var txt = ustring.Make (x).ToString ();
|
||||
if (!matchCase) {
|
||||
txt = txt.ToUpper ();
|
||||
}
|
||||
if (start.Y != i) {
|
||||
start.X = Math.Max (x.Count - 1, 0);
|
||||
}
|
||||
var matchText = !matchCase ? text.ToUpper ().ToString () : text.ToString ();
|
||||
var col = txt.LastIndexOf (matchText, start.X);
|
||||
if (col > -1 && matchWholeWord && !MatchWholeWord (txt, matchText, col)) {
|
||||
continue;
|
||||
}
|
||||
if (col > -1 && ((i == linesCount && col <= start.X)
|
||||
|| i < start.Y)
|
||||
&& txt.Contains (matchText)) {
|
||||
return (new Point (col, i), true);
|
||||
}
|
||||
}
|
||||
|
||||
return (Point.Empty, false);
|
||||
}
|
||||
|
||||
bool MatchWholeWord (string source, string matchText, int index = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty (source) || string.IsNullOrEmpty (matchText)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var txt = matchText.Trim ();
|
||||
var start = index > 0 ? index - 1 : 0;
|
||||
var end = index + txt.Length;
|
||||
|
||||
if ((start == 0 || Rune.IsWhiteSpace (source [start]))
|
||||
&& (end == source.Length || Rune.IsWhiteSpace (source [end]))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Redefine column and line tracking.
|
||||
/// </summary>
|
||||
/// <param name="point">Contains the column and line.</param>
|
||||
internal void ResetContinuousFind (Point point)
|
||||
{
|
||||
toFind.startPointToFind = toFind.currentPointToFind = point;
|
||||
toFind.found = false;
|
||||
}
|
||||
}
|
||||
|
||||
class WordWrapManager {
|
||||
@@ -645,9 +823,9 @@ namespace Terminal.Gui {
|
||||
int currentColumn;
|
||||
int selectionStartColumn, selectionStartRow;
|
||||
bool selecting;
|
||||
//bool used;
|
||||
bool wordWrap;
|
||||
WordWrapManager wrapManager;
|
||||
bool continuousFind;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the <see cref="Text"/> of the <see cref="TextView"/> changes.
|
||||
@@ -671,7 +849,7 @@ namespace Terminal.Gui {
|
||||
/// </remarks>
|
||||
public TextView (Rect frame) : base (frame)
|
||||
{
|
||||
CanFocus = true;
|
||||
Initialize ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -680,9 +858,21 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
public TextView () : base ()
|
||||
{
|
||||
CanFocus = true;
|
||||
Initialize ();
|
||||
}
|
||||
|
||||
void Initialize ()
|
||||
{
|
||||
CanFocus = true;
|
||||
Used = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks whether the text view should be considered "used", that is, that the user has moved in the entry,
|
||||
/// so new input should be appended at the cursor position, rather than clearing the entry
|
||||
/// </summary>
|
||||
public bool Used { get; set; }
|
||||
|
||||
void ResetPosition ()
|
||||
{
|
||||
topRow = leftColumn = currentRow = currentColumn = 0;
|
||||
@@ -763,6 +953,79 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
public int Lines => model.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Sets or gets the current cursor position.
|
||||
/// </summary>
|
||||
public Point CursorPosition {
|
||||
get => new Point (currentColumn, currentRow);
|
||||
set {
|
||||
var line = model.GetLine (Math.Max (Math.Min (value.Y, model.Count - 1), 0));
|
||||
currentColumn = value.X < 0 ? 0 : value.X > line.Count ? line.Count : value.X;
|
||||
currentRow = value.Y < 0 ? 0 : value.Y > model.Count - 1
|
||||
? Math.Max (model.Count - 1, 0) : value.Y;
|
||||
SetNeedsDisplay ();
|
||||
Adjust ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start column position of the selected text.
|
||||
/// </summary>
|
||||
public int SelectionStartColumn {
|
||||
get => selectionStartColumn;
|
||||
set {
|
||||
var line = model.GetLine (currentRow);
|
||||
selectionStartColumn = value < 0 ? 0 : value > line.Count ? line.Count : value;
|
||||
selecting = true;
|
||||
SetNeedsDisplay ();
|
||||
Adjust ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start row position of the selected text.
|
||||
/// </summary>
|
||||
public int SelectionStartRow {
|
||||
get => selectionStartRow;
|
||||
set {
|
||||
selectionStartRow = value < 0 ? 0 : value > model.Count - 1
|
||||
? Math.Max (model.Count - 1, 0) : value;
|
||||
selecting = true;
|
||||
SetNeedsDisplay ();
|
||||
Adjust ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The selected text.
|
||||
/// </summary>
|
||||
public ustring SelectedText {
|
||||
get {
|
||||
if (!selecting || (model.Count == 1 && model.GetLine (0).Count == 0)) {
|
||||
return ustring.Empty;
|
||||
}
|
||||
|
||||
SetWrapModel ();
|
||||
var sel = GetRegion ();
|
||||
UpdateWrapModel ();
|
||||
Adjust ();
|
||||
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Length of the selected text.
|
||||
/// </summary>
|
||||
public int SelectedLength => GetSelectedLength ();
|
||||
|
||||
/// <summary>
|
||||
/// Get or sets the selecting.
|
||||
/// </summary>
|
||||
public bool Selecting {
|
||||
get => selecting;
|
||||
set => selecting = value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Allows word wrap the to fit the available container width.
|
||||
/// </summary>
|
||||
@@ -796,6 +1059,11 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
public int RightOffset { get; set; }
|
||||
|
||||
int GetSelectedLength ()
|
||||
{
|
||||
return SelectedText.Length;
|
||||
}
|
||||
|
||||
CursorVisibility savedCursorVisibility = CursorVisibility.Default;
|
||||
|
||||
void SaveCursorVisibility ()
|
||||
@@ -884,7 +1152,7 @@ namespace Terminal.Gui {
|
||||
var col = 0;
|
||||
if (line.Count > 0) {
|
||||
retreat = Math.Max (SpecialRune (line [Math.Min (Math.Max (currentColumn - leftColumn - 1, 0), line.Count - 1)])
|
||||
? 1 : 0, 0);
|
||||
? 1 : 0, 0);
|
||||
for (int idx = leftColumn < 0 ? 0 : leftColumn; idx < line.Count; idx++) {
|
||||
if (idx == currentColumn)
|
||||
break;
|
||||
@@ -892,7 +1160,7 @@ namespace Terminal.Gui {
|
||||
col += cols - 1;
|
||||
}
|
||||
}
|
||||
var ccol = currentColumn - leftColumn - retreat + col;
|
||||
var ccol = currentColumn - leftColumn + retreat + col;
|
||||
if (leftColumn <= currentColumn && ccol < Frame.Width
|
||||
&& topRow <= currentRow && currentRow - topRow < Frame.Height) {
|
||||
ResetCursorVisibility ();
|
||||
@@ -921,6 +1189,11 @@ namespace Terminal.Gui {
|
||||
Driver.SetAttribute (ColorScheme.Focus);
|
||||
}
|
||||
|
||||
void ColorUsed ()
|
||||
{
|
||||
Driver.SetAttribute (ColorScheme.HotFocus);
|
||||
}
|
||||
|
||||
bool isReadOnly = false;
|
||||
|
||||
/// <summary>
|
||||
@@ -1050,6 +1323,145 @@ namespace Terminal.Gui {
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Select all text.
|
||||
/// </summary>
|
||||
public void SelectAll ()
|
||||
{
|
||||
if (model.Count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
StartSelecting ();
|
||||
selectionStartColumn = 0;
|
||||
selectionStartRow = 0;
|
||||
currentColumn = model.GetLine (model.Count - 1).Count;
|
||||
currentRow = model.Count - 1;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the next text based on the match case with the option to replace it.
|
||||
/// </summary>
|
||||
/// <param name="textToFind">The text to find.</param>
|
||||
/// <param name="gaveFullTurn"><c>true</c>If all the text was forward searched.<c>false</c>otherwise.</param>
|
||||
/// <param name="matchCase">The match case setting.</param>
|
||||
/// <param name="matchWholeWord">The match whole word setting.</param>
|
||||
/// <param name="textToReplace">The text to replace.</param>
|
||||
/// <param name="replace"><c>true</c>If is replacing.<c>false</c>otherwise.</param>
|
||||
/// <returns><c>true</c>If the text was found.<c>false</c>otherwise.</returns>
|
||||
public bool FindNextText (ustring textToFind, out bool gaveFullTurn, bool matchCase = false,
|
||||
bool matchWholeWord = false, ustring textToReplace = null, bool replace = false)
|
||||
{
|
||||
if (model.Count == 0) {
|
||||
gaveFullTurn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetWrapModel ();
|
||||
ResetContinuousFind ();
|
||||
var foundPos = model.FindNextText (textToFind, out gaveFullTurn, matchCase, matchWholeWord);
|
||||
|
||||
return SetFoundText (textToFind, foundPos, textToReplace, replace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the previous text based on the match case with the option to replace it.
|
||||
/// </summary>
|
||||
/// <param name="textToFind">The text to find.</param>
|
||||
/// <param name="gaveFullTurn"><c>true</c>If all the text was backward searched.<c>false</c>otherwise.</param>
|
||||
/// <param name="matchCase">The match case setting.</param>
|
||||
/// <param name="matchWholeWord">The match whole word setting.</param>
|
||||
/// <param name="textToReplace">The text to replace.</param>
|
||||
/// <param name="replace"><c>true</c>If the text was found.<c>false</c>otherwise.</param>
|
||||
/// <returns><c>true</c>If the text was found.<c>false</c>otherwise.</returns>
|
||||
public bool FindPreviousText (ustring textToFind, out bool gaveFullTurn, bool matchCase = false,
|
||||
bool matchWholeWord = false, ustring textToReplace = null, bool replace = false)
|
||||
{
|
||||
if (model.Count == 0) {
|
||||
gaveFullTurn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetWrapModel ();
|
||||
ResetContinuousFind ();
|
||||
var foundPos = model.FindPreviousText (textToFind, out gaveFullTurn, matchCase, matchWholeWord);
|
||||
|
||||
return SetFoundText (textToFind, foundPos, textToReplace, replace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the flag to stop continuous find.
|
||||
/// </summary>
|
||||
public void FindTextChanged ()
|
||||
{
|
||||
continuousFind = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces all the text based on the match case.
|
||||
/// </summary>
|
||||
/// <param name="textToFind">The text to find.</param>
|
||||
/// <param name="matchCase">The match case setting.</param>
|
||||
/// <param name="matchWholeWord">The match whole word setting.</param>
|
||||
/// <param name="textToReplace">The text to replace.</param>
|
||||
/// <returns><c>true</c>If the text was found.<c>false</c>otherwise.</returns>
|
||||
public bool ReplaceAllText (ustring textToFind, bool matchCase = false, bool matchWholeWord = false,
|
||||
ustring textToReplace = null)
|
||||
{
|
||||
if (isReadOnly || model.Count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetWrapModel ();
|
||||
ResetContinuousFind ();
|
||||
var foundPos = model.ReplaceAllText (textToFind, matchCase, matchWholeWord, textToReplace);
|
||||
|
||||
return SetFoundText (textToFind, foundPos, textToReplace, false, true);
|
||||
}
|
||||
|
||||
bool SetFoundText (ustring text, (Point current, bool found) foundPos,
|
||||
ustring textToReplace = null, bool replace = false, bool replaceAll = false)
|
||||
{
|
||||
if (foundPos.found) {
|
||||
StartSelecting ();
|
||||
selectionStartColumn = foundPos.current.X;
|
||||
selectionStartRow = foundPos.current.Y;
|
||||
if (!replaceAll) {
|
||||
currentColumn = selectionStartColumn + text.RuneCount;
|
||||
} else {
|
||||
currentColumn = selectionStartColumn + textToReplace.RuneCount;
|
||||
}
|
||||
currentRow = foundPos.current.Y;
|
||||
if (!isReadOnly && replace) {
|
||||
Adjust ();
|
||||
ClearSelectedRegion ();
|
||||
InsertText (textToReplace);
|
||||
StartSelecting ();
|
||||
selectionStartColumn = currentColumn - textToReplace.RuneCount;
|
||||
} else {
|
||||
UpdateWrapModel ();
|
||||
SetNeedsDisplay ();
|
||||
Adjust ();
|
||||
}
|
||||
continuousFind = true;
|
||||
return foundPos.found;
|
||||
}
|
||||
UpdateWrapModel ();
|
||||
continuousFind = false;
|
||||
|
||||
return foundPos.found;
|
||||
}
|
||||
|
||||
void ResetContinuousFind ()
|
||||
{
|
||||
if (!continuousFind) {
|
||||
var col = selecting ? selectionStartColumn : currentColumn;
|
||||
var row = selecting ? selectionStartRow : currentRow;
|
||||
model.ResetContinuousFind (new Point (col, row));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restore from original model.
|
||||
/// </summary>
|
||||
@@ -1088,7 +1500,7 @@ namespace Terminal.Gui {
|
||||
ColorNormal ();
|
||||
|
||||
int bottom = bounds.Bottom;
|
||||
int right = bounds.Right + 1;
|
||||
int right = bounds.Right;
|
||||
for (int row = bounds.Top; row < bottom; row++) {
|
||||
int textLine = topRow + row;
|
||||
if (textLine >= model.Count) {
|
||||
@@ -1111,14 +1523,27 @@ namespace Terminal.Gui {
|
||||
var cols = Rune.ColumnWidth (rune);
|
||||
if (lineCol < line.Count && selecting && PointInSelection (idx + leftColumn, row + topRow)) {
|
||||
ColorSelection ();
|
||||
} else if (lineCol == currentColumn && textLine == currentRow && !selecting && !Used
|
||||
&& HasFocus && lineCol < lineRuneCount) {
|
||||
ColorUsed ();
|
||||
} else {
|
||||
ColorNormal ();
|
||||
}
|
||||
|
||||
if (!SpecialRune (rune)) {
|
||||
AddRune (col, row, rune);
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
col = TextModel.SetCol (col, bounds.Right, cols);
|
||||
if (idx + 1 < lineRuneCount && col + Rune.ColumnWidth (line [idx + 1]) > right) {
|
||||
break;
|
||||
} else if (idx == lineRuneCount - 1) {
|
||||
ColorNormal ();
|
||||
for (int i = col; i < right; i++) {
|
||||
Driver.AddRune (' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PositionCursor ();
|
||||
@@ -1156,9 +1581,21 @@ namespace Terminal.Gui {
|
||||
void Insert (Rune rune)
|
||||
{
|
||||
var line = GetCurrentLine ();
|
||||
line.Insert (Math.Min (currentColumn, line.Count), rune);
|
||||
if (Used) {
|
||||
line.Insert (Math.Min (currentColumn, line.Count), rune);
|
||||
} else {
|
||||
if (currentColumn < line.Count) {
|
||||
line.RemoveAt (currentColumn);
|
||||
}
|
||||
line.Insert (Math.Min (currentColumn, line.Count), rune);
|
||||
}
|
||||
if (wordWrap) {
|
||||
wrapNeeded = wrapManager.Insert (currentRow, currentColumn, rune);
|
||||
if (Used) {
|
||||
wrapNeeded = wrapManager.Insert (currentRow, currentColumn, rune);
|
||||
} else {
|
||||
wrapNeeded = wrapManager.RemoveAt (currentRow, currentColumn);
|
||||
wrapNeeded = wrapManager.Insert (currentRow, currentColumn, rune);
|
||||
}
|
||||
if (wrapNeeded) {
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
@@ -1211,7 +1648,7 @@ namespace Terminal.Gui {
|
||||
if (wordWrap) {
|
||||
SetNeedsDisplay ();
|
||||
} else {
|
||||
SetNeedsDisplay (new Rect (0, currentRow - topRow, Frame.Width, currentRow - topRow + 1));
|
||||
SetNeedsDisplay (new Rect (0, currentRow - topRow, Frame.Width, Math.Max (currentRow - topRow + 1, 0)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1348,9 +1785,35 @@ namespace Terminal.Gui {
|
||||
case Key.P | Key.CtrlMask:
|
||||
case Key.CursorUp:
|
||||
lastWasKill = false;
|
||||
continuousFind = false;
|
||||
break;
|
||||
case Key.K | Key.CtrlMask:
|
||||
break;
|
||||
case Key.F | Key.CtrlMask:
|
||||
case Key.B | Key.CtrlMask:
|
||||
case (Key)((int)'B' + Key.AltMask):
|
||||
case Key.A | Key.CtrlMask:
|
||||
case Key.E | Key.CtrlMask:
|
||||
case Key.CursorRight:
|
||||
case Key.CursorLeft:
|
||||
case Key.CursorRight | Key.CtrlMask:
|
||||
case Key.CursorLeft | Key.CtrlMask:
|
||||
case Key.CursorRight | Key.ShiftMask:
|
||||
case Key.CursorLeft | Key.ShiftMask:
|
||||
case Key.CursorRight | Key.CtrlMask | Key.ShiftMask:
|
||||
case Key.CursorLeft | Key.CtrlMask | Key.ShiftMask:
|
||||
case Key.Home:
|
||||
case Key.Home | Key.CtrlMask:
|
||||
case Key.Home | Key.ShiftMask:
|
||||
case Key.Home | Key.CtrlMask | Key.ShiftMask:
|
||||
case Key.End:
|
||||
case Key.End | Key.CtrlMask:
|
||||
case Key.End | Key.ShiftMask:
|
||||
case Key.End | Key.CtrlMask | Key.ShiftMask:
|
||||
lastWasKill = false;
|
||||
columnTrack = -1;
|
||||
continuousFind = false;
|
||||
break;
|
||||
default:
|
||||
lastWasKill = false;
|
||||
columnTrack = -1;
|
||||
@@ -1371,7 +1834,9 @@ namespace Terminal.Gui {
|
||||
if (currentRow < model.Count) {
|
||||
if (columnTrack == -1)
|
||||
columnTrack = currentColumn;
|
||||
currentRow = (currentRow + nPageDnShift) > model.Count ? model.Count : currentRow + nPageDnShift;
|
||||
currentRow = (currentRow + nPageDnShift) > model.Count
|
||||
? model.Count > 0 ? model.Count - 1 : 0
|
||||
: currentRow + nPageDnShift;
|
||||
if (topRow < currentRow - nPageDnShift) {
|
||||
topRow = currentRow >= model.Count ? currentRow - nPageDnShift : topRow + nPageDnShift;
|
||||
SetNeedsDisplay ();
|
||||
@@ -1478,7 +1943,7 @@ namespace Terminal.Gui {
|
||||
if (isReadOnly)
|
||||
break;
|
||||
if (selecting) {
|
||||
Cut ();
|
||||
ClearSelectedRegion ();
|
||||
return true;
|
||||
}
|
||||
if (currentColumn > 0) {
|
||||
@@ -1533,7 +1998,7 @@ namespace Terminal.Gui {
|
||||
if (isReadOnly)
|
||||
break;
|
||||
if (selecting) {
|
||||
Cut ();
|
||||
ClearSelectedRegion ();
|
||||
return true;
|
||||
}
|
||||
currentLine = GetCurrentLine ();
|
||||
@@ -1733,6 +2198,15 @@ namespace Terminal.Gui {
|
||||
MoveHome ();
|
||||
break;
|
||||
|
||||
case Key.T | Key.CtrlMask:
|
||||
SelectAll ();
|
||||
break;
|
||||
|
||||
case Key.InsertChar:
|
||||
Used = !Used;
|
||||
SetNeedsDisplay ();
|
||||
break;
|
||||
|
||||
default:
|
||||
// Ignore control characters and other special keys
|
||||
if (kb.Key < Key.Space || kb.Key > Key.CharMask)
|
||||
@@ -1741,13 +2215,18 @@ namespace Terminal.Gui {
|
||||
if (isReadOnly)
|
||||
return true;
|
||||
if (selecting) {
|
||||
Cut ();
|
||||
ClearSelectedRegion ();
|
||||
}
|
||||
Insert ((uint)kb.Key);
|
||||
currentColumn++;
|
||||
if (currentColumn >= leftColumn + Frame.Width) {
|
||||
leftColumn++;
|
||||
SetNeedsDisplay ();
|
||||
if (Used) {
|
||||
Insert ((uint)kb.Key);
|
||||
currentColumn++;
|
||||
if (currentColumn >= leftColumn + Frame.Width) {
|
||||
leftColumn++;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
} else {
|
||||
Insert ((uint)kb.Key);
|
||||
currentColumn++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1838,6 +2317,17 @@ namespace Terminal.Gui {
|
||||
selecting = false;
|
||||
}
|
||||
|
||||
void ClearSelectedRegion ()
|
||||
{
|
||||
SetWrapModel ();
|
||||
if (!isReadOnly) {
|
||||
ClearRegion ();
|
||||
}
|
||||
UpdateWrapModel ();
|
||||
selecting = false;
|
||||
DoNeededAction ();
|
||||
}
|
||||
|
||||
void MoveUp ()
|
||||
{
|
||||
if (currentRow > 0) {
|
||||
@@ -1895,7 +2385,11 @@ namespace Terminal.Gui {
|
||||
Rune RuneAt (int col, int row)
|
||||
{
|
||||
var line = model.GetLine (row);
|
||||
return line [col > line.Count - 1 ? line.Count - 1 : col];
|
||||
if (line.Count > 0) {
|
||||
return line [col > line.Count - 1 ? line.Count - 1 : col];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1927,6 +2421,9 @@ namespace Terminal.Gui {
|
||||
if (col + 1 < line.Count) {
|
||||
col++;
|
||||
rune = line [col];
|
||||
if (col + 1 == line.Count) {
|
||||
col++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
while (row + 1 < model.Count) {
|
||||
@@ -1975,27 +2472,45 @@ namespace Terminal.Gui {
|
||||
try {
|
||||
var rune = RuneAt (col, row);
|
||||
|
||||
var srow = row;
|
||||
if (Rune.IsPunctuation (rune) || Rune.IsWhiteSpace (rune)) {
|
||||
while (MoveNext (ref col, ref row, out rune)) {
|
||||
if (Rune.IsLetterOrDigit (rune))
|
||||
break;
|
||||
}
|
||||
if (row != fromRow && Rune.IsLetterOrDigit (rune)) {
|
||||
return (col, row);
|
||||
}
|
||||
while (MoveNext (ref col, ref row, out rune)) {
|
||||
if (!Rune.IsLetterOrDigit (rune))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while (MoveNext (ref col, ref row, out rune)) {
|
||||
if (!Rune.IsLetterOrDigit (rune))
|
||||
break;
|
||||
void ProcMoveNext (ref int nCol, ref int nRow, Rune nRune)
|
||||
{
|
||||
if (Rune.IsSymbol (nRune) || Rune.IsWhiteSpace (nRune)) {
|
||||
while (MoveNext (ref nCol, ref nRow, out nRune)) {
|
||||
if (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune))
|
||||
return;
|
||||
}
|
||||
if (nRow != fromRow && (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune))) {
|
||||
return;
|
||||
}
|
||||
while (MoveNext (ref nCol, ref nRow, out nRune)) {
|
||||
if (!Rune.IsLetterOrDigit (nRune) && !Rune.IsPunctuation (nRune))
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!MoveNext (ref nCol, ref nRow, out nRune)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var line = model.GetLine (fromRow);
|
||||
if ((nRow != fromRow && fromCol < line.Count)
|
||||
|| (nRow == fromRow && nCol == line.Count - 1)) {
|
||||
nCol = line.Count;
|
||||
nRow = fromRow;
|
||||
return;
|
||||
} else if (nRow != fromRow && fromCol == line.Count) {
|
||||
line = model.GetLine (nRow);
|
||||
if (Rune.IsLetterOrDigit (line [nCol]) || Rune.IsPunctuation (line [nCol])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ProcMoveNext (ref nCol, ref nRow, nRune);
|
||||
}
|
||||
}
|
||||
|
||||
ProcMoveNext (ref col, ref row, rune);
|
||||
|
||||
if (fromCol != col || fromRow != row)
|
||||
return (col + 1, row);
|
||||
return (col, row);
|
||||
return null;
|
||||
} catch (Exception) {
|
||||
return null;
|
||||
@@ -2011,36 +2526,54 @@ namespace Terminal.Gui {
|
||||
var row = fromRow;
|
||||
try {
|
||||
var rune = RuneAt (col, row);
|
||||
int lastValidCol = Rune.IsLetterOrDigit (rune) || Rune.IsPunctuation (rune) ? col : -1;
|
||||
|
||||
if (Rune.IsPunctuation (rune) || Rune.IsSymbol (rune) || Rune.IsWhiteSpace (rune)) {
|
||||
while (MovePrev (ref col, ref row, out rune)) {
|
||||
if (Rune.IsLetterOrDigit (rune))
|
||||
break;
|
||||
}
|
||||
int lastValidCol = -1;
|
||||
while (MovePrev (ref col, ref row, out rune)) {
|
||||
if (col == 0 && Rune.IsLetterOrDigit (rune)) {
|
||||
return (col, row);
|
||||
} else if (col == 0 && !Rune.IsLetterOrDigit (rune) && lastValidCol > -1) {
|
||||
col = lastValidCol;
|
||||
return (col, row);
|
||||
void ProcMovePrev (ref int nCol, ref int nRow, Rune nRune)
|
||||
{
|
||||
if (Rune.IsSymbol (nRune) || Rune.IsWhiteSpace (nRune)) {
|
||||
while (MovePrev (ref nCol, ref nRow, out nRune)) {
|
||||
if (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune)) {
|
||||
lastValidCol = nCol;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Rune.IsLetterOrDigit (rune)) {
|
||||
break;
|
||||
if (nRow != fromRow && (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune))) {
|
||||
return;
|
||||
}
|
||||
lastValidCol = Rune.IsLetterOrDigit (rune) ? col : -1;
|
||||
}
|
||||
} else {
|
||||
while (MovePrev (ref col, ref row, out rune)) {
|
||||
if (!Rune.IsLetterOrDigit (rune))
|
||||
break;
|
||||
while (MovePrev (ref nCol, ref nRow, out nRune)) {
|
||||
if (!Rune.IsLetterOrDigit (nRune) && !Rune.IsPunctuation (nRune))
|
||||
break;
|
||||
lastValidCol = nCol;
|
||||
}
|
||||
if (lastValidCol > -1) {
|
||||
nCol = lastValidCol;
|
||||
}
|
||||
} else {
|
||||
if (!MovePrev (ref nCol, ref nRow, out nRune)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var line = model.GetLine (nRow);
|
||||
if (nCol == 0 && nRow == fromRow && (Rune.IsLetterOrDigit (line [0]) || Rune.IsPunctuation (line [0]))) {
|
||||
return;
|
||||
}
|
||||
lastValidCol = Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune) ? nCol : lastValidCol;
|
||||
if (lastValidCol > -1 && (Rune.IsSymbol (nRune) || Rune.IsWhiteSpace (nRune))) {
|
||||
nCol = lastValidCol;
|
||||
return;
|
||||
}
|
||||
if (fromRow != nRow) {
|
||||
nCol = line.Count;
|
||||
return;
|
||||
}
|
||||
ProcMovePrev (ref nCol, ref nRow, nRune);
|
||||
}
|
||||
}
|
||||
if (fromCol != col && fromRow == row) {
|
||||
return (col == 0 ? col : col + 1, row);
|
||||
} else if (fromCol != col && fromRow != row) {
|
||||
return (col + 1, row);
|
||||
}
|
||||
|
||||
ProcMovePrev (ref col, ref row, rune);
|
||||
|
||||
if (fromCol != col || fromRow != row)
|
||||
return (col, row);
|
||||
return null;
|
||||
} catch (Exception) {
|
||||
return null;
|
||||
@@ -2054,7 +2587,9 @@ namespace Terminal.Gui {
|
||||
&& !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition)
|
||||
&& !ev.Flags.HasFlag (MouseFlags.Button1Released)
|
||||
&& !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ButtonShift)
|
||||
&& !ev.Flags.HasFlag (MouseFlags.WheeledDown) && !ev.Flags.HasFlag (MouseFlags.WheeledUp)) {
|
||||
&& !ev.Flags.HasFlag (MouseFlags.WheeledDown) && !ev.Flags.HasFlag (MouseFlags.WheeledUp)
|
||||
&& !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked)
|
||||
&& !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked | MouseFlags.ButtonShift)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2066,6 +2601,8 @@ namespace Terminal.Gui {
|
||||
SetFocus ();
|
||||
}
|
||||
|
||||
continuousFind = false;
|
||||
|
||||
if (ev.Flags == MouseFlags.Button1Clicked) {
|
||||
if (shiftSelecting) {
|
||||
shiftSelecting = false;
|
||||
@@ -2143,6 +2680,40 @@ namespace Terminal.Gui {
|
||||
}
|
||||
} else if (ev.Flags.HasFlag (MouseFlags.Button1Released)) {
|
||||
Application.UngrabMouse ();
|
||||
} else if (ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked)) {
|
||||
if (ev.Flags.HasFlag (MouseFlags.ButtonShift)) {
|
||||
if (!selecting) {
|
||||
StartSelecting ();
|
||||
}
|
||||
} else if (selecting) {
|
||||
StopSelecting ();
|
||||
}
|
||||
ProcessMouseClick (ev, out List<Rune> line);
|
||||
(int col, int row)? newPos = null;
|
||||
if (currentColumn > 0 && line [currentColumn - 1] != ' ') {
|
||||
newPos = WordBackward (currentColumn, currentRow);
|
||||
if (newPos.HasValue) {
|
||||
currentColumn = newPos.Value.col;
|
||||
currentRow = newPos.Value.row;
|
||||
}
|
||||
}
|
||||
if (!selecting) {
|
||||
StartSelecting ();
|
||||
}
|
||||
if (currentRow < selectionStartRow || currentRow == selectionStartRow && currentColumn < selectionStartColumn) {
|
||||
if (currentColumn > 0 && line [currentColumn - 1] != ' ') {
|
||||
newPos = WordBackward (currentColumn, currentRow);
|
||||
}
|
||||
} else {
|
||||
newPos = WordForward (currentColumn, currentRow);
|
||||
}
|
||||
if (newPos != null && newPos.HasValue) {
|
||||
currentColumn = newPos.Value.col;
|
||||
currentRow = newPos.Value.row;
|
||||
}
|
||||
PositionCursor ();
|
||||
lastWasKill = false;
|
||||
columnTrack = currentColumn;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -93,13 +93,8 @@ namespace UICatalog {
|
||||
};
|
||||
frame.Add (numButtonsEdit);
|
||||
|
||||
void Top_Loaded ()
|
||||
{
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit)
|
||||
+ Dim.Height (numButtonsEdit) + 2;
|
||||
Top.Loaded -= Top_Loaded;
|
||||
}
|
||||
Top.Loaded += Top_Loaded;
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit)
|
||||
+ Dim.Height (numButtonsEdit) + 2;
|
||||
|
||||
label = new Label ("Button Pressed:") {
|
||||
X = Pos.Center (),
|
||||
|
||||
@@ -15,6 +15,11 @@ namespace UICatalog {
|
||||
private bool _saved = true;
|
||||
private ScrollBarView _scrollBar;
|
||||
private byte [] _originalText;
|
||||
private string _textToFind;
|
||||
private string _textToReplace;
|
||||
private bool _matchCase;
|
||||
private bool _matchWholeWord;
|
||||
Window winDialog;
|
||||
|
||||
public override void Init (Toplevel top, ColorScheme colorScheme)
|
||||
{
|
||||
@@ -36,7 +41,17 @@ namespace UICatalog {
|
||||
new MenuBarItem ("_Edit", new MenuItem [] {
|
||||
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 MenuItem ("_Paste", "", () => Paste(),null,null, Key.CtrlMask | Key.Y),
|
||||
null,
|
||||
new MenuItem ("_Find", "", () => Find(),null,null, Key.CtrlMask | Key.S),
|
||||
new MenuItem ("Find _Next", "", () => FindNext(),null,null, Key.CtrlMask | Key.ShiftMask | Key.S),
|
||||
new MenuItem ("Find P_revious", "", () => FindPrevious(),null,null, Key.CtrlMask | Key.ShiftMask | Key.AltMask | Key.S),
|
||||
new MenuItem ("_Replace", "", () => Replace(),null,null, Key.CtrlMask | Key.R),
|
||||
new MenuItem ("Replace Ne_xt", "", () => ReplaceNext(),null,null, Key.CtrlMask | Key.ShiftMask | Key.R),
|
||||
new MenuItem ("Replace Pre_vious", "", () => ReplacePrevious(),null,null, Key.CtrlMask | Key.ShiftMask | Key.AltMask | Key.R),
|
||||
new MenuItem ("Replace _All", "", () => ReplaceAll(),null,null, Key.CtrlMask | Key.ShiftMask | Key.AltMask | Key.A),
|
||||
null,
|
||||
new MenuItem ("_Select All", "", () => SelectAll(),null,null, Key.CtrlMask | Key.T)
|
||||
}),
|
||||
new MenuBarItem ("_ScrollBarView", CreateKeepChecked ()),
|
||||
new MenuBarItem ("_Cursor", new MenuItem [] {
|
||||
@@ -115,6 +130,20 @@ namespace UICatalog {
|
||||
_scrollBar.LayoutSubviews ();
|
||||
_scrollBar.Refresh ();
|
||||
};
|
||||
|
||||
Win.KeyPress += (e) => {
|
||||
if (winDialog != null && (e.KeyEvent.Key == Key.Esc
|
||||
|| e.KeyEvent.Key.HasFlag (Key.Q | Key.CtrlMask))) {
|
||||
DisposeWinDialog ();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void DisposeWinDialog ()
|
||||
{
|
||||
winDialog.Dispose ();
|
||||
Win.Remove (winDialog);
|
||||
winDialog = null;
|
||||
}
|
||||
|
||||
public override void Setup ()
|
||||
@@ -166,6 +195,91 @@ namespace UICatalog {
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectAll ()
|
||||
{
|
||||
_textView.SelectAll ();
|
||||
}
|
||||
|
||||
private void Find ()
|
||||
{
|
||||
CreateFindReplace ();
|
||||
}
|
||||
|
||||
private void FindNext ()
|
||||
{
|
||||
ContinueFind ();
|
||||
}
|
||||
|
||||
private void FindPrevious ()
|
||||
{
|
||||
ContinueFind (false);
|
||||
}
|
||||
|
||||
private void ContinueFind (bool next = true, bool replace = false)
|
||||
{
|
||||
if (!replace && string.IsNullOrEmpty (_textToFind)) {
|
||||
Find ();
|
||||
return;
|
||||
} else if (replace && (string.IsNullOrEmpty (_textToFind)
|
||||
|| (winDialog == null && string.IsNullOrEmpty (_textToReplace)))) {
|
||||
Replace ();
|
||||
return;
|
||||
}
|
||||
|
||||
bool found;
|
||||
bool gaveFullTurn;
|
||||
|
||||
if (next) {
|
||||
if (!replace) {
|
||||
found = _textView.FindNextText (_textToFind, out gaveFullTurn, _matchCase, _matchWholeWord);
|
||||
} else {
|
||||
found = _textView.FindNextText (_textToFind, out gaveFullTurn, _matchCase, _matchWholeWord,
|
||||
_textToReplace, true);
|
||||
}
|
||||
} else {
|
||||
if (!replace) {
|
||||
found = _textView.FindPreviousText (_textToFind, out gaveFullTurn, _matchCase, _matchWholeWord);
|
||||
} else {
|
||||
found = _textView.FindPreviousText (_textToFind, out gaveFullTurn, _matchCase, _matchWholeWord,
|
||||
_textToReplace, true);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
MessageBox.Query ("Find", $"The following specified text was not found: '{_textToFind}'", "Ok");
|
||||
} else if (gaveFullTurn) {
|
||||
MessageBox.Query ("Find", $"No more occurrences were found for the following specified text: '{_textToFind}'", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
private void Replace ()
|
||||
{
|
||||
CreateFindReplace (false);
|
||||
}
|
||||
|
||||
private void ReplaceNext ()
|
||||
{
|
||||
ContinueFind (true, true);
|
||||
}
|
||||
|
||||
private void ReplacePrevious ()
|
||||
{
|
||||
ContinueFind (false, true);
|
||||
}
|
||||
|
||||
private void ReplaceAll ()
|
||||
{
|
||||
if (string.IsNullOrEmpty (_textToFind) || (string.IsNullOrEmpty (_textToReplace) && winDialog == null)) {
|
||||
Replace ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_textView.ReplaceAllText (_textToFind, _matchCase, _matchWholeWord, _textToReplace)) {
|
||||
MessageBox.Query ("Replace All", $"All occurrences were replaced for the following specified text: '{_textToReplace}'", "Ok");
|
||||
} else {
|
||||
MessageBox.Query ("Replace All", $"None of the following specified text was found: '{_textToFind}'", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetCursor (CursorVisibility visibility)
|
||||
{
|
||||
_textView.DesiredCursorVisibility = visibility;
|
||||
@@ -307,6 +421,259 @@ namespace UICatalog {
|
||||
return new MenuItem [] { item };
|
||||
}
|
||||
|
||||
private void CreateFindReplace (bool isFind = true)
|
||||
{
|
||||
winDialog = new Window (isFind ? "Find" : "Replace") {
|
||||
X = Win.Bounds.Width / 2 - 30,
|
||||
Y = Win.Bounds.Height / 2 - 10,
|
||||
ColorScheme = Colors.Menu
|
||||
};
|
||||
|
||||
var tabView = new TabView () {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
|
||||
tabView.AddTab (new Tab ("Find", FindTab ()), isFind);
|
||||
var replace = ReplaceTab ();
|
||||
tabView.AddTab (new Tab ("Replace", replace), !isFind);
|
||||
tabView.SelectedTabChanged += (s, e) => tabView.SelectedTab.View.FocusFirst ();
|
||||
winDialog.Add (tabView);
|
||||
|
||||
Win.Add (winDialog);
|
||||
|
||||
winDialog.Width = replace.Width + 4;
|
||||
winDialog.Height = replace.Height + 4;
|
||||
|
||||
winDialog.SuperView.BringSubviewToFront (winDialog);
|
||||
winDialog.SetFocus ();
|
||||
}
|
||||
|
||||
private void SetFindText ()
|
||||
{
|
||||
_textToFind = !_textView.SelectedText.IsEmpty
|
||||
? _textView.SelectedText.ToString ()
|
||||
: string.IsNullOrEmpty (_textToFind) ? "" : _textToFind;
|
||||
|
||||
_textToReplace = string.IsNullOrEmpty (_textToReplace) ? "" : _textToReplace;
|
||||
}
|
||||
|
||||
private View FindTab ()
|
||||
{
|
||||
var d = new View () {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
d.DrawContent += (e) => {
|
||||
foreach (var v in d.Subviews) {
|
||||
v.SetNeedsDisplay ();
|
||||
}
|
||||
};
|
||||
|
||||
var lblWidth = "Replace:".Length;
|
||||
|
||||
var label = new Label (0, 1, "Find:") {
|
||||
Width = lblWidth,
|
||||
TextAlignment = TextAlignment.Right,
|
||||
LayoutStyle = LayoutStyle.Computed
|
||||
};
|
||||
d.Add (label);
|
||||
|
||||
SetFindText ();
|
||||
var txtToFind = new TextField (_textToFind) {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 20
|
||||
};
|
||||
txtToFind.Enter += (_) => txtToFind.Text = _textToFind;
|
||||
d.Add (txtToFind);
|
||||
|
||||
var btnFindNext = new Button ("Find _Next") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 20,
|
||||
CanFocus = !txtToFind.Text.IsEmpty,
|
||||
TextAlignment = TextAlignment.Centered,
|
||||
IsDefault = true
|
||||
};
|
||||
btnFindNext.Clicked += () => FindNext ();
|
||||
d.Add (btnFindNext);
|
||||
|
||||
var btnFindPrevious = new Button ("Find _Previous") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (btnFindNext) + 1,
|
||||
Width = 20,
|
||||
CanFocus = !txtToFind.Text.IsEmpty,
|
||||
TextAlignment = TextAlignment.Centered
|
||||
};
|
||||
btnFindPrevious.Clicked += () => FindPrevious ();
|
||||
d.Add (btnFindPrevious);
|
||||
|
||||
txtToFind.TextChanged += (e) => {
|
||||
_textToFind = txtToFind.Text.ToString ();
|
||||
_textView.FindTextChanged ();
|
||||
btnFindNext.CanFocus = !txtToFind.Text.IsEmpty;
|
||||
btnFindPrevious.CanFocus = !txtToFind.Text.IsEmpty;
|
||||
};
|
||||
|
||||
var btnCancel = new Button ("Cancel") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (btnFindPrevious) + 2,
|
||||
Width = 20,
|
||||
TextAlignment = TextAlignment.Centered
|
||||
};
|
||||
btnCancel.Clicked += () => {
|
||||
DisposeWinDialog ();
|
||||
};
|
||||
d.Add (btnCancel);
|
||||
|
||||
var ckbMatchCase = new CheckBox ("Match c_ase") {
|
||||
X = 0,
|
||||
Y = Pos.Top (txtToFind) + 2,
|
||||
Checked = _matchCase
|
||||
};
|
||||
ckbMatchCase.Toggled += (e) => _matchCase = ckbMatchCase.Checked;
|
||||
d.Add (ckbMatchCase);
|
||||
|
||||
var ckbMatchWholeWord = new CheckBox ("Match _whole word") {
|
||||
X = 0,
|
||||
Y = Pos.Top (ckbMatchCase) + 1,
|
||||
Checked = _matchWholeWord
|
||||
};
|
||||
ckbMatchWholeWord.Toggled += (e) => _matchWholeWord = 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;
|
||||
}
|
||||
|
||||
private View ReplaceTab ()
|
||||
{
|
||||
var d = new View () {
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Width = Dim.Fill (),
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
d.DrawContent += (e) => {
|
||||
foreach (var v in d.Subviews) {
|
||||
v.SetNeedsDisplay ();
|
||||
}
|
||||
};
|
||||
|
||||
var lblWidth = "Replace:".Length;
|
||||
|
||||
var label = new Label (0, 1, "Find:") {
|
||||
Width = lblWidth,
|
||||
TextAlignment = TextAlignment.Right,
|
||||
LayoutStyle = LayoutStyle.Computed
|
||||
};
|
||||
d.Add (label);
|
||||
|
||||
SetFindText ();
|
||||
var txtToFind = new TextField (_textToFind) {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 20
|
||||
};
|
||||
txtToFind.Enter += (_) => txtToFind.Text = _textToFind;
|
||||
d.Add (txtToFind);
|
||||
|
||||
var btnFindNext = new Button ("Replace _Next") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 20,
|
||||
CanFocus = !txtToFind.Text.IsEmpty,
|
||||
TextAlignment = TextAlignment.Centered,
|
||||
IsDefault = true
|
||||
};
|
||||
btnFindNext.Clicked += () => ReplaceNext ();
|
||||
d.Add (btnFindNext);
|
||||
|
||||
label = new Label ("Replace:") {
|
||||
X = Pos.Left (label),
|
||||
Y = Pos.Top (label) + 1,
|
||||
Width = lblWidth,
|
||||
TextAlignment = TextAlignment.Right
|
||||
};
|
||||
d.Add (label);
|
||||
|
||||
SetFindText ();
|
||||
var txtToReplace = new TextField (_textToReplace) {
|
||||
X = Pos.Right (label) + 1,
|
||||
Y = Pos.Top (label),
|
||||
Width = 20
|
||||
};
|
||||
txtToReplace.TextChanged += (e) => _textToReplace = txtToReplace.Text.ToString ();
|
||||
d.Add (txtToReplace);
|
||||
|
||||
var btnFindPrevious = new Button ("Replace _Previous") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (btnFindNext) + 1,
|
||||
Width = 20,
|
||||
CanFocus = !txtToFind.Text.IsEmpty,
|
||||
TextAlignment = TextAlignment.Centered
|
||||
};
|
||||
btnFindPrevious.Clicked += () => ReplacePrevious ();
|
||||
d.Add (btnFindPrevious);
|
||||
|
||||
var btnReplaceAll = new Button ("Replace _All") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (btnFindPrevious) + 1,
|
||||
Width = 20,
|
||||
CanFocus = !txtToFind.Text.IsEmpty,
|
||||
TextAlignment = TextAlignment.Centered
|
||||
};
|
||||
btnReplaceAll.Clicked += () => ReplaceAll ();
|
||||
d.Add (btnReplaceAll);
|
||||
|
||||
txtToFind.TextChanged += (e) => {
|
||||
_textToFind = txtToFind.Text.ToString ();
|
||||
_textView.FindTextChanged ();
|
||||
btnFindNext.CanFocus = !txtToFind.Text.IsEmpty;
|
||||
btnFindPrevious.CanFocus = !txtToFind.Text.IsEmpty;
|
||||
btnReplaceAll.CanFocus = !txtToFind.Text.IsEmpty;
|
||||
};
|
||||
|
||||
var btnCancel = new Button ("Cancel") {
|
||||
X = Pos.Right (txtToFind) + 1,
|
||||
Y = Pos.Top (btnReplaceAll) + 1,
|
||||
Width = 20,
|
||||
TextAlignment = TextAlignment.Centered
|
||||
};
|
||||
btnCancel.Clicked += () => {
|
||||
DisposeWinDialog ();
|
||||
};
|
||||
d.Add (btnCancel);
|
||||
|
||||
var ckbMatchCase = new CheckBox ("Match c_ase") {
|
||||
X = 0,
|
||||
Y = Pos.Top (txtToFind) + 2,
|
||||
Checked = _matchCase
|
||||
};
|
||||
ckbMatchCase.Toggled += (e) => _matchCase = ckbMatchCase.Checked;
|
||||
d.Add (ckbMatchCase);
|
||||
|
||||
var ckbMatchWholeWord = new CheckBox ("Match _whole word") {
|
||||
X = 0,
|
||||
Y = Pos.Top (ckbMatchCase) + 1,
|
||||
Checked = _matchWholeWord
|
||||
};
|
||||
ckbMatchWholeWord.Toggled += (e) => _matchWholeWord = ckbMatchWholeWord.Checked;
|
||||
d.Add (ckbMatchWholeWord);
|
||||
|
||||
d.Width = lblWidth + txtToFind.Width + btnFindNext.Width + 2;
|
||||
d.Height = btnFindNext.Height + btnFindPrevious.Height + btnCancel.Height + 4;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
base.Run ();
|
||||
|
||||
@@ -140,13 +140,8 @@ namespace UICatalog {
|
||||
};
|
||||
frame.Add (styleRadioGroup);
|
||||
|
||||
void Top_Loaded ()
|
||||
{
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + Dim.Height (messageEdit)
|
||||
+ Dim.Height (numButtonsEdit) + Dim.Height (defaultButtonEdit) + Dim.Height (styleRadioGroup) + 2;
|
||||
Top.Loaded -= Top_Loaded;
|
||||
}
|
||||
Top.Loaded += Top_Loaded;
|
||||
frame.Height = Dim.Height (widthEdit) + Dim.Height (heightEdit) + Dim.Height (titleEdit) + Dim.Height (messageEdit)
|
||||
+ Dim.Height (numButtonsEdit) + Dim.Height(defaultButtonEdit) + Dim.Height (styleRadioGroup) + 2;
|
||||
|
||||
label = new Label ("Button Pressed:") {
|
||||
X = Pos.Center (),
|
||||
|
||||
@@ -483,6 +483,10 @@ namespace Terminal.Gui {
|
||||
Assert.Equal (1, v3.Frame.Height); // 1 because is Dim.DimAbsolute
|
||||
|
||||
v4.Text = "Button4";
|
||||
v4.AutoSize = false;
|
||||
Assert.Equal ("Dim.Absolute(50)", v4.Width.ToString ());
|
||||
Assert.Equal ("Dim.Absolute(1)", v4.Height.ToString ());
|
||||
v4.AutoSize = true;
|
||||
Assert.Equal ("Dim.Absolute(11)", v4.Width.ToString ());
|
||||
Assert.Equal ("Dim.Absolute(1)", v4.Height.ToString ());
|
||||
Assert.Equal (11, v4.Frame.Width); // 11 is the text length and because is Dim.DimAbsolute
|
||||
@@ -507,6 +511,84 @@ namespace Terminal.Gui {
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
// TODO: Test operators
|
||||
// DONE: Test operators
|
||||
[Fact]
|
||||
public void DimCombine_Do_Not_Throws ()
|
||||
{
|
||||
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
|
||||
|
||||
var t = Application.Top;
|
||||
|
||||
var w = new Window ("w") {
|
||||
Width = Dim.Width (t) - 2,
|
||||
Height = Dim.Height (t) - 2
|
||||
};
|
||||
var f = new FrameView ("f");
|
||||
var v1 = new View ("v1") {
|
||||
Width = Dim.Width (w) - 2,
|
||||
Height = Dim.Height (w) - 2
|
||||
};
|
||||
var v2 = new View ("v2") {
|
||||
Width = Dim.Width (v1) - 2,
|
||||
Height = Dim.Height (v1) - 2
|
||||
};
|
||||
|
||||
f.Add (v1, v2);
|
||||
w.Add (f);
|
||||
t.Add (w);
|
||||
|
||||
f.Width = Dim.Width (t) - Dim.Width (v2);
|
||||
f.Height = Dim.Height (t) - Dim.Height (v2);
|
||||
|
||||
t.Ready += () => {
|
||||
Assert.Equal (80, t.Frame.Width);
|
||||
Assert.Equal (25, t.Frame.Height);
|
||||
Assert.Equal (78, w.Frame.Width);
|
||||
Assert.Equal (23, w.Frame.Height);
|
||||
Assert.Equal (6, f.Frame.Width);
|
||||
Assert.Equal (6, f.Frame.Height);
|
||||
Assert.Equal (76, v1.Frame.Width);
|
||||
Assert.Equal (21, v1.Frame.Height);
|
||||
Assert.Equal (74, v2.Frame.Width);
|
||||
Assert.Equal (19, v2.Frame.Height);
|
||||
};
|
||||
|
||||
Application.Iteration += () => Application.RequestStop ();
|
||||
|
||||
Application.Run ();
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PosCombine_Will_Throws ()
|
||||
{
|
||||
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
|
||||
|
||||
var t = Application.Top;
|
||||
|
||||
var w = new Window ("w") {
|
||||
Width = Dim.Width (t) - 2,
|
||||
Height = Dim.Height (t) - 2
|
||||
};
|
||||
var f = new FrameView ("f");
|
||||
var v1 = new View ("v1") {
|
||||
Width = Dim.Width (w) - 2,
|
||||
Height = Dim.Height (w) - 2
|
||||
};
|
||||
var v2 = new View ("v2") {
|
||||
Width = Dim.Width (v1) - 2,
|
||||
Height = Dim.Height (v1) - 2
|
||||
};
|
||||
|
||||
f.Add (v1); // v2 not added
|
||||
w.Add (f);
|
||||
t.Add (w);
|
||||
|
||||
f.Width = Dim.Width (t) - Dim.Width (v2);
|
||||
f.Height = Dim.Height (t) - Dim.Height (v2);
|
||||
|
||||
Assert.Throws<InvalidOperationException> (() => Application.Run ());
|
||||
Application.Shutdown ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Terminal.Gui {
|
||||
Assert.Equal (pos1, pos2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact]
|
||||
public void SetSide_Null_Throws ()
|
||||
{
|
||||
var pos = Pos.Left (null);
|
||||
@@ -91,7 +91,7 @@ namespace Terminal.Gui {
|
||||
pos = Pos.Top (null);
|
||||
Assert.Throws<NullReferenceException> (() => pos.ToString ());
|
||||
|
||||
pos = Pos.Y(null);
|
||||
pos = Pos.Y (null);
|
||||
Assert.Throws<NullReferenceException> (() => pos.ToString ());
|
||||
|
||||
pos = Pos.Bottom (null);
|
||||
@@ -112,7 +112,7 @@ namespace Terminal.Gui {
|
||||
string side; // used in format string
|
||||
var testRect = Rect.Empty;
|
||||
var testInt = 0;
|
||||
Pos pos;
|
||||
Pos pos;
|
||||
|
||||
// Pos.Left
|
||||
side = "x";
|
||||
@@ -456,9 +456,85 @@ namespace Terminal.Gui {
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
// TODO: Test PosCombine
|
||||
// DONE: Test PosCombine
|
||||
// DONE: Test operators
|
||||
[Fact]
|
||||
public void PosCombine_Do_Not_Throws ()
|
||||
{
|
||||
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
|
||||
|
||||
var t = Application.Top;
|
||||
|
||||
// TODO: Test operators
|
||||
var w = new Window ("w") {
|
||||
X = Pos.Left (t) + 2,
|
||||
Y = Pos.Top (t) + 2
|
||||
};
|
||||
var f = new FrameView ("f");
|
||||
var v1 = new View ("v1") {
|
||||
X = Pos.Left (w) + 2,
|
||||
Y = Pos.Top (w) + 2
|
||||
};
|
||||
var v2 = new View ("v2") {
|
||||
X = Pos.Left (v1) + 2,
|
||||
Y = Pos.Top (v1) + 2
|
||||
};
|
||||
|
||||
f.Add (v1, v2);
|
||||
w.Add (f);
|
||||
t.Add (w);
|
||||
|
||||
f.X = Pos.X (t) + Pos.X (v2) - Pos.X (v1);
|
||||
f.Y = Pos.Y (t) + Pos.Y (v2) - Pos.Y (v1);
|
||||
|
||||
t.Ready += () => {
|
||||
Assert.Equal (0, t.Frame.X);
|
||||
Assert.Equal (0, t.Frame.Y);
|
||||
Assert.Equal (2, w.Frame.X);
|
||||
Assert.Equal (2, w.Frame.Y);
|
||||
Assert.Equal (2, f.Frame.X);
|
||||
Assert.Equal (2, f.Frame.Y);
|
||||
Assert.Equal (4, v1.Frame.X);
|
||||
Assert.Equal (4, v1.Frame.Y);
|
||||
Assert.Equal (6, v2.Frame.X);
|
||||
Assert.Equal (6, v2.Frame.Y);
|
||||
};
|
||||
|
||||
Application.Iteration += () => Application.RequestStop ();
|
||||
|
||||
Application.Run ();
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PosCombine_Will_Throws ()
|
||||
{
|
||||
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
|
||||
|
||||
var t = Application.Top;
|
||||
|
||||
var w = new Window ("w") {
|
||||
X = Pos.Left (t) + 2,
|
||||
Y = Pos.Top (t) + 2
|
||||
};
|
||||
var f = new FrameView ("f");
|
||||
var v1 = new View ("v1") {
|
||||
X = Pos.Left (w) + 2,
|
||||
Y = Pos.Top (w) + 2
|
||||
};
|
||||
var v2 = new View ("v2") {
|
||||
X = Pos.Left (v1) + 2,
|
||||
Y = Pos.Top (v1) + 2
|
||||
};
|
||||
|
||||
f.Add (v1); // v2 not added
|
||||
w.Add (f);
|
||||
t.Add (w);
|
||||
|
||||
f.X = Pos.X (v2) - Pos.X (v1);
|
||||
f.Y = Pos.Y (v2) - Pos.Y (v1);
|
||||
|
||||
Assert.Throws<InvalidOperationException> (() => Application.Run ());
|
||||
Application.Shutdown ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
797
UnitTests/TextViewTests.cs
Normal file
797
UnitTests/TextViewTests.cs
Normal file
@@ -0,0 +1,797 @@
|
||||
using Xunit;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
public class TextViewTests {
|
||||
private TextView _textView;
|
||||
|
||||
public TextViewTests ()
|
||||
{
|
||||
Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
|
||||
|
||||
// 1 2 3
|
||||
// 01234567890123456789012345678901=32 (Length)
|
||||
var txt = "TAB to jump between text fields.";
|
||||
var buff = new byte [txt.Length];
|
||||
for (int i = 0; i < txt.Length; i++) {
|
||||
buff [i] = (byte)txt [i];
|
||||
}
|
||||
var ms = new System.IO.MemoryStream (buff).ToArray ();
|
||||
_textView = new TextView () { Width = 30, Height = 10 };
|
||||
_textView.Text = ms;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Changing_Selection_Or_CursorPosition_Update_SelectedLength_And_SelectedText ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 2;
|
||||
_textView.SelectionStartRow = 0;
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (2, _textView.SelectedLength);
|
||||
Assert.Equal ("TA", _textView.SelectedText);
|
||||
_textView.CursorPosition = new Point (20, 0);
|
||||
Assert.Equal (2, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (18, _textView.SelectedLength);
|
||||
Assert.Equal ("B to jump between ", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Selection_With_Value_Less_Than_Zero_Changes_To_Zero ()
|
||||
{
|
||||
_textView.SelectionStartColumn = -2;
|
||||
_textView.SelectionStartRow = -2;
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Selection_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (2, 0);
|
||||
_textView.SelectionStartColumn = 33;
|
||||
_textView.SelectionStartRow = 1;
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (30, _textView.SelectedLength);
|
||||
Assert.Equal ("B to jump between text fields.", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Selection_With_Empty_Text ()
|
||||
{
|
||||
_textView = new TextView ();
|
||||
_textView.CursorPosition = new Point (2, 0);
|
||||
_textView.SelectionStartColumn = 33;
|
||||
_textView.SelectionStartRow = 1;
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Selection_And_CursorPosition_With_Value_Greater_Than_Text_Length_Changes_Both_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (33, 2);
|
||||
_textView.SelectionStartColumn = 33;
|
||||
_textView.SelectionStartRow = 33;
|
||||
Assert.Equal (32, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CursorPosition_With_Value_Less_Than_Zero_Changes_To_Zero ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (-1, -1);
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CursorPosition_With_Value_Greater_Than_Text_Length_Changes_To_Text_Length ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (33, 1);
|
||||
Assert.Equal (32, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordForward_With_No_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (0, 0);
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X < _textView.Text.Length) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (4, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (7, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (20, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (32, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordBackward_With_No_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (_textView.Text.Length, 0);
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X > 0) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (20, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (7, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (4, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordForward_With_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (0, 0);
|
||||
_textView.SelectionStartColumn = 0;
|
||||
_textView.SelectionStartRow = 0;
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X < _textView.Text.Length) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (4, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (4, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB ", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (7, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (7, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to ", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (12, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jump ", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (20, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (20, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jump between ", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (25, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jump between text ", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (32, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (32, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordBackward_With_Selection ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (_textView.Text.Length, 0);
|
||||
_textView.SelectionStartColumn = _textView.Text.Length;
|
||||
_textView.SelectionStartRow = 0;
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X > 0) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (7, _textView.SelectedLength);
|
||||
Assert.Equal ("fields.", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (20, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (12, _textView.SelectedLength);
|
||||
Assert.Equal ("text fields.", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (20, _textView.SelectedLength);
|
||||
Assert.Equal ("between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (7, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (25, _textView.SelectedLength);
|
||||
Assert.Equal ("jump between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (4, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (28, _textView.SelectedLength);
|
||||
Assert.Equal ("to jump between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (32, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (32, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordForward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
_textView.SelectionStartColumn = 10;
|
||||
_textView.SelectionStartRow = 0;
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X < _textView.Text.Length) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (2, _textView.SelectedLength);
|
||||
Assert.Equal ("p ", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (20, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (10, _textView.SelectedLength);
|
||||
Assert.Equal ("p between ", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (15, _textView.SelectedLength);
|
||||
Assert.Equal ("p between text ", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (32, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (22, _textView.SelectedLength);
|
||||
Assert.Equal ("p between text fields.", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordBackward_With_The_Same_Values_For_SelectedStart_And_CursorPosition_And_Not_Starting_At_Beginning_Of_The_Text ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
_textView.SelectionStartColumn = 10;
|
||||
_textView.SelectionStartRow = 0;
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X > 0) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask | Key.ShiftMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (7, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (3, _textView.SelectedLength);
|
||||
Assert.Equal ("jum", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (4, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (6, _textView.SelectedLength);
|
||||
Assert.Equal ("to jum", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (10, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (10, _textView.SelectedLength);
|
||||
Assert.Equal ("TAB to jum", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordForward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
|
||||
{
|
||||
// 1 2 3 4 5
|
||||
// 0123456789012345678901234567890123456789012345678901234=55 (Length)
|
||||
_textView.Text = "TAB t o jump b etween t ext f ields .";
|
||||
_textView.CursorPosition = new Point (0, 0);
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X < _textView.Text.Length) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorRight | Key.CtrlMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (6, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (9, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (28, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (38, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 6:
|
||||
Assert.Equal (40, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 7:
|
||||
Assert.Equal (46, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 8:
|
||||
Assert.Equal (48, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 9:
|
||||
Assert.Equal (55, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WordBackward_With_No_Selection_And_With_More_Than_Only_One_Whitespace_And_With_Only_One_Letter ()
|
||||
{
|
||||
// 1 2 3 4 5
|
||||
// 0123456789012345678901234567890123456789012345678901234=55 (Length)
|
||||
_textView.Text = "TAB t o jump b etween t ext f ields .";
|
||||
_textView.CursorPosition = new Point (_textView.Text.Length, 0);
|
||||
var iteration = 0;
|
||||
|
||||
while (_textView.CursorPosition.X > 0) {
|
||||
_textView.ProcessKey (new KeyEvent (Key.CursorLeft | Key.CtrlMask, new KeyModifiers ()));
|
||||
switch (iteration) {
|
||||
case 0:
|
||||
Assert.Equal (54, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 1:
|
||||
Assert.Equal (48, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 2:
|
||||
Assert.Equal (46, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 3:
|
||||
Assert.Equal (40, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 4:
|
||||
Assert.Equal (38, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 5:
|
||||
Assert.Equal (28, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 6:
|
||||
Assert.Equal (25, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 7:
|
||||
Assert.Equal (12, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 8:
|
||||
Assert.Equal (9, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 9:
|
||||
Assert.Equal (6, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
case 10:
|
||||
Assert.Equal (0, _textView.CursorPosition.X);
|
||||
Assert.Equal (0, _textView.CursorPosition.Y);
|
||||
Assert.Equal (0, _textView.SelectionStartColumn);
|
||||
Assert.Equal (0, _textView.SelectionStartRow);
|
||||
Assert.Equal (0, _textView.SelectedLength);
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
break;
|
||||
}
|
||||
iteration++;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Copy_Or_Cut_Null_If_No_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 0;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
_textView.Cut ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Copy_Or_Cut_Not_Null_If_Has_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.CursorPosition = new Point (24, 0);
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
_textView.Cut ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Copy_Or_Cut_And_Paste_With_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.CursorPosition = new Point (24, 0);
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.Paste ();
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.Cut ();
|
||||
_textView.Paste ();
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Copy_Or_Cut_And_Paste_With_No_Selection ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.CursorPosition = new Point (24, 0);
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.SelectionStartColumn = 0;
|
||||
_textView.SelectionStartRow = 0;
|
||||
Assert.True (_textView.Selecting);
|
||||
_textView.Selecting = false;
|
||||
_textView.Paste ();
|
||||
Assert.Equal ("TAB to jump between texttext fields.", _textView.Text);
|
||||
_textView.SelectionStartColumn = 24;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.Cut ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.SelectionStartColumn = 0;
|
||||
_textView.SelectionStartRow = 0;
|
||||
Assert.True (_textView.Selecting);
|
||||
_textView.Selecting = false;
|
||||
_textView.Paste ();
|
||||
Assert.Equal ("TAB to jump between texttext fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Cut_Not_Allowed_If_ReadOnly_Is_True ()
|
||||
{
|
||||
_textView.ReadOnly = true;
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.CursorPosition = new Point (24, 0);
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
_textView.Cut (); // Selecting is set to false after Cut.
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
_textView.ReadOnly = false;
|
||||
Assert.False (_textView.Selecting);
|
||||
_textView.Selecting = true; // Needed to set Selecting to true.
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
_textView.Cut ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Paste_Always_Clear_The_SelectedText ()
|
||||
{
|
||||
_textView.SelectionStartColumn = 20;
|
||||
_textView.SelectionStartRow = 0;
|
||||
_textView.CursorPosition = new Point (24, 0);
|
||||
_textView.Copy ();
|
||||
Assert.Equal ("text", _textView.SelectedText);
|
||||
_textView.Paste ();
|
||||
Assert.Equal ("", _textView.SelectedText);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TextChanged_Event ()
|
||||
{
|
||||
_textView.TextChanged += () => {
|
||||
if (_textView.Text == "changing") {
|
||||
Assert.Equal ("changing", _textView.Text);
|
||||
_textView.Text = "changed";
|
||||
}
|
||||
};
|
||||
|
||||
_textView.Text = "changing";
|
||||
Assert.Equal ("changed", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Used_Is_True_By_Default ()
|
||||
{
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u
|
||||
Assert.Equal ("TAB to jumup between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s
|
||||
Assert.Equal ("TAB to jumusp between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e
|
||||
Assert.Equal ("TAB to jumusep between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d
|
||||
Assert.Equal ("TAB to jumusedp between text fields.", _textView.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Used_Is_False ()
|
||||
{
|
||||
_textView.Used = false;
|
||||
_textView.CursorPosition = new Point (10, 0);
|
||||
Assert.Equal ("TAB to jump between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x75, new KeyModifiers ())); // u
|
||||
Assert.Equal ("TAB to jumu between text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x73, new KeyModifiers ())); // s
|
||||
Assert.Equal ("TAB to jumusbetween text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x65, new KeyModifiers ())); // e
|
||||
Assert.Equal ("TAB to jumuseetween text fields.", _textView.Text);
|
||||
_textView.ProcessKey (new KeyEvent ((Key)0x64, new KeyModifiers ())); // d
|
||||
Assert.Equal ("TAB to jumusedtween text fields.", _textView.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user