mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-29 01:07:58 +01:00
integrated tznind's stuff
This commit is contained in:
@@ -10,54 +10,54 @@ namespace Terminal.Gui {
|
||||
public enum Command {
|
||||
|
||||
/// <summary>
|
||||
/// Moves the caret down one line.
|
||||
/// Moves down one item (cell, line, etc...).
|
||||
/// </summary>
|
||||
LineDown,
|
||||
|
||||
/// <summary>
|
||||
/// Extends the selection down one line.
|
||||
/// Extends the selection down one (cell, line, etc...).
|
||||
/// </summary>
|
||||
LineDownExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the caret down to the last child node of the branch that holds the current selection
|
||||
/// Moves down to the last child node of the branch that holds the current selection.
|
||||
/// </summary>
|
||||
LineDownToLastBranch,
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls down one line (without changing the selection).
|
||||
/// Scrolls down one (cell, line, etc...) (without changing the selection).
|
||||
/// </summary>
|
||||
ScrollDown,
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Moves the caret up one line.
|
||||
/// Moves up one (cell, line, etc...).
|
||||
/// </summary>
|
||||
LineUp,
|
||||
|
||||
/// <summary>
|
||||
/// Extends the selection up one line.
|
||||
/// Extends the selection up one item (cell, line, etc...).
|
||||
/// </summary>
|
||||
LineUpExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the caret up to the first child node of the branch that holds the current selection
|
||||
/// Moves up to the first child node of the branch that holds the current selection.
|
||||
/// </summary>
|
||||
LineUpToFirstBranch,
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls up one line (without changing the selection).
|
||||
/// Scrolls up one item (cell, line, etc...) (without changing the selection).
|
||||
/// </summary>
|
||||
ScrollUp,
|
||||
|
||||
/// <summary>
|
||||
/// Moves the selection left one by the minimum increment supported by the view e.g. single character, cell, item etc.
|
||||
/// Moves the selection left one by the minimum increment supported by the <see cref="View"/> e.g. single character, cell, item etc.
|
||||
/// </summary>
|
||||
Left,
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls one character to the left
|
||||
/// Scrolls one item (cell, character, etc...) to the left
|
||||
/// </summary>
|
||||
ScrollLeft,
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Terminal.Gui {
|
||||
Right,
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls one character to the right.
|
||||
/// Scrolls one item (cell, character, etc...) to the right.
|
||||
/// </summary>
|
||||
ScrollRight,
|
||||
|
||||
@@ -102,12 +102,12 @@ namespace Terminal.Gui {
|
||||
WordRightExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Deletes and copies to the clipboard the characters from the current position to the end of the line.
|
||||
/// Cuts to the clipboard the characters from the current position to the end of the line.
|
||||
/// </summary>
|
||||
CutToEndLine,
|
||||
|
||||
/// <summary>
|
||||
/// Deletes and copies to the clipboard the characters from the current position to the start of the line.
|
||||
/// Cuts to the clipboard the characters from the current position to the start of the line.
|
||||
/// </summary>
|
||||
CutToStartLine,
|
||||
|
||||
@@ -140,47 +140,47 @@ namespace Terminal.Gui {
|
||||
DisableOverwrite,
|
||||
|
||||
/// <summary>
|
||||
/// Move the page down.
|
||||
/// Move one page down.
|
||||
/// </summary>
|
||||
PageDown,
|
||||
|
||||
/// <summary>
|
||||
/// Move the page down increase selection area to cover revealed objects/characters.
|
||||
/// Move one page page extending the selection to cover revealed objects/characters.
|
||||
/// </summary>
|
||||
PageDownExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Move the page up.
|
||||
/// Move one page up.
|
||||
/// </summary>
|
||||
PageUp,
|
||||
|
||||
/// <summary>
|
||||
/// Move the page up increase selection area to cover revealed objects/characters.
|
||||
/// Move one page up extending the selection to cover revealed objects/characters.
|
||||
/// </summary>
|
||||
PageUpExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Moves to top begin.
|
||||
/// Moves to the top/home.
|
||||
/// </summary>
|
||||
TopHome,
|
||||
|
||||
/// <summary>
|
||||
/// Extends the selection to the top begin.
|
||||
/// Extends the selection to the top/home.
|
||||
/// </summary>
|
||||
TopHomeExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Moves to bottom end.
|
||||
/// Moves to the bottom/end.
|
||||
/// </summary>
|
||||
BottomEnd,
|
||||
|
||||
/// <summary>
|
||||
/// Extends the selection to the bottom end.
|
||||
/// Extends the selection to the bottom/end.
|
||||
/// </summary>
|
||||
BottomEndExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Open selected item.
|
||||
/// Open the selected item.
|
||||
/// </summary>
|
||||
OpenSelectedItem,
|
||||
|
||||
@@ -190,43 +190,43 @@ namespace Terminal.Gui {
|
||||
ToggleChecked,
|
||||
|
||||
/// <summary>
|
||||
/// Accepts the current state (e.g. selection, button press etc)
|
||||
/// Accepts the current state (e.g. selection, button press etc).
|
||||
/// </summary>
|
||||
Accept,
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the Expanded or collapsed state of a a list or item (with subitems)
|
||||
/// Toggles the Expanded or collapsed state of a a list or item (with subitems).
|
||||
/// </summary>
|
||||
ToggleExpandCollapse,
|
||||
|
||||
/// <summary>
|
||||
/// Expands a list or item (with subitems)
|
||||
/// Expands a list or item (with subitems).
|
||||
/// </summary>
|
||||
Expand,
|
||||
|
||||
/// <summary>
|
||||
/// Recursively Expands all child items and their child items (if any)
|
||||
/// Recursively Expands all child items and their child items (if any).
|
||||
/// </summary>
|
||||
ExpandAll,
|
||||
|
||||
/// <summary>
|
||||
/// Collapses a list or item (with subitems)
|
||||
/// Collapses a list or item (with subitems).
|
||||
/// </summary>
|
||||
Collapse,
|
||||
|
||||
/// <summary>
|
||||
/// Recursively collapses a list items of their children (if any)
|
||||
/// Recursively collapses a list items of their children (if any).
|
||||
/// </summary>
|
||||
CollapseAll,
|
||||
|
||||
/// <summary>
|
||||
/// Cancels any current temporary states on the control e.g. expanding
|
||||
/// a combo list
|
||||
/// Cancels an action or any temporary states on the control e.g. expanding
|
||||
/// a combo list.
|
||||
/// </summary>
|
||||
Cancel,
|
||||
|
||||
/// <summary>
|
||||
/// Unix emulation
|
||||
/// Unix emulation.
|
||||
/// </summary>
|
||||
UnixEmulation,
|
||||
|
||||
@@ -241,12 +241,12 @@ namespace Terminal.Gui {
|
||||
DeleteCharLeft,
|
||||
|
||||
/// <summary>
|
||||
/// Selects all objects in the control.
|
||||
/// Selects all objects.
|
||||
/// </summary>
|
||||
SelectAll,
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all objects in the control.
|
||||
/// Deletes all objects.
|
||||
/// </summary>
|
||||
DeleteAll,
|
||||
|
||||
@@ -336,7 +336,7 @@ namespace Terminal.Gui {
|
||||
Paste,
|
||||
|
||||
/// <summary>
|
||||
/// Quit a toplevel.
|
||||
/// Quit a <see cref="Toplevel"/>.
|
||||
/// </summary>
|
||||
QuitToplevel,
|
||||
|
||||
@@ -356,37 +356,37 @@ namespace Terminal.Gui {
|
||||
PreviousView,
|
||||
|
||||
/// <summary>
|
||||
/// Moves focus to the next view or toplevel (case of Mdi).
|
||||
/// Moves focus to the next view or toplevel (case of MDI).
|
||||
/// </summary>
|
||||
NextViewOrTop,
|
||||
|
||||
/// <summary>
|
||||
/// Moves focus to the next previous or toplevel (case of Mdi).
|
||||
/// Moves focus to the next previous or toplevel (case of MDI).
|
||||
/// </summary>
|
||||
PreviousViewOrTop,
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the application.
|
||||
/// Refresh.
|
||||
/// </summary>
|
||||
Refresh,
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the extended selection.
|
||||
/// Toggles the selection.
|
||||
/// </summary>
|
||||
ToggleExtend,
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new line.
|
||||
/// Inserts a new item.
|
||||
/// </summary>
|
||||
NewLine,
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a tab.
|
||||
/// Tabs to the next item.
|
||||
/// </summary>
|
||||
Tab,
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a shift tab.
|
||||
/// Tabs back to the previous item.
|
||||
/// </summary>
|
||||
BackTab
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Terminal.Gui {
|
||||
@@ -11,11 +12,17 @@ namespace Terminal.Gui {
|
||||
DateTime lastKeystroke = DateTime.MinValue;
|
||||
const int TypingDelay = 250;
|
||||
public StringComparer Comparer { get; set; } = StringComparer.InvariantCultureIgnoreCase;
|
||||
private IEnumerable<string> Collection { get => _collection; set => _collection = value; }
|
||||
|
||||
public int CalculateNewIndex (string [] collection, int currentIndex, char keyStruck)
|
||||
private IEnumerable<string> _collection;
|
||||
|
||||
public SearchCollectionNavigator (IEnumerable<string> collection) { _collection = collection; }
|
||||
|
||||
|
||||
public int CalculateNewIndex (IEnumerable<string> collection, int currentIndex, char keyStruck)
|
||||
{
|
||||
// if user presses a letter key
|
||||
if (char.IsLetterOrDigit (keyStruck) || char.IsPunctuation (keyStruck)) {
|
||||
// if user presses a key
|
||||
if (true) {//char.IsLetterOrDigit (keyStruck) || char.IsPunctuation (keyStruck) || char.IsSymbol(keyStruck)) {
|
||||
|
||||
// maybe user pressed 'd' and now presses 'd' again.
|
||||
// a candidate search is things that begin with "dd"
|
||||
@@ -73,7 +80,12 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
private int GetNextIndexMatching (string [] collection, int currentIndex, string search, bool preferNotToMoveToNewIndexes = false)
|
||||
public int CalculateNewIndex (int currentIndex, char keyStruck)
|
||||
{
|
||||
return CalculateNewIndex (Collection, currentIndex, keyStruck);
|
||||
}
|
||||
|
||||
private int GetNextIndexMatching (IEnumerable<string> collection, int currentIndex, string search, bool preferNotToMoveToNewIndexes = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty (search)) {
|
||||
return -1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NStack;
|
||||
@@ -179,6 +180,12 @@ namespace Terminal.Gui {
|
||||
get => allowsMarking;
|
||||
set {
|
||||
allowsMarking = value;
|
||||
if (allowsMarking) {
|
||||
AddKeyBinding (Key.Space, Command.ToggleChecked);
|
||||
} else {
|
||||
ClearKeybinding (Key.Space);
|
||||
}
|
||||
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
}
|
||||
@@ -353,8 +360,6 @@ namespace Terminal.Gui {
|
||||
AddKeyBinding (Key.End, Command.BottomEnd);
|
||||
|
||||
AddKeyBinding (Key.Enter, Command.OpenSelectedItem);
|
||||
|
||||
AddKeyBinding (Key.Space, Command.ToggleChecked);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
@@ -416,39 +421,30 @@ namespace Terminal.Gui {
|
||||
/// </summary>
|
||||
public event Action<ListViewRowEventArgs> RowRender;
|
||||
|
||||
private string search { get; set; }
|
||||
private SearchCollectionNavigator navigator;
|
||||
|
||||
///<inheritdoc/>
|
||||
public override bool ProcessKey (KeyEvent kb)
|
||||
{
|
||||
if (source == null)
|
||||
if (source == null) {
|
||||
return base.ProcessKey (kb);
|
||||
}
|
||||
|
||||
var result = InvokeKeybindings (kb);
|
||||
if (result != null)
|
||||
if (result != null) {
|
||||
return (bool)result;
|
||||
}
|
||||
|
||||
// Enable user to find & select an item by typing text
|
||||
if (source is IListDataSourceSearchable &&
|
||||
!(kb.IsCapslock && kb.IsCtrl && kb.IsAlt && kb.IsScrolllock && kb.IsNumlock && kb.IsCapslock)) {
|
||||
if (kb.KeyValue >= 32 && kb.KeyValue < 127) {
|
||||
if (searchTimer == null) {
|
||||
searchTimer = new System.Timers.Timer (500);
|
||||
searchTimer.Elapsed += (o, e) => {
|
||||
searchTimer.Stop ();
|
||||
searchTimer = null;
|
||||
search = "";
|
||||
};
|
||||
searchTimer.Start ();
|
||||
}
|
||||
search += (char)kb.KeyValue;
|
||||
var found = ((IListDataSourceSearchable)source).StartsWith (search);
|
||||
if (found != -1) {
|
||||
SelectedItem = found;
|
||||
SetNeedsDisplay ();
|
||||
}
|
||||
return true;
|
||||
if (!kb.IsAlt && !kb.IsCapslock && !kb.IsCtrl && !kb.IsScrolllock && !kb.IsNumlock) {
|
||||
if (navigator == null) {
|
||||
// BUGBUG: If items change this needs to be recreated.
|
||||
navigator = new SearchCollectionNavigator (source.ToList().Cast<string>());
|
||||
}
|
||||
SelectedItem = navigator.CalculateNewIndex (SelectedItem, (char)kb.KeyValue);
|
||||
EnsuresVisibilitySelectedItem ();
|
||||
SetNeedsDisplay ();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
"Issue1719Repro": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"ProgressBar Styles\""
|
||||
},
|
||||
"SearchCollectionNavTester": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"Search Collection Nav\""
|
||||
}
|
||||
}
|
||||
}
|
||||
218
UICatalog/Scenarios/SearchCollectionNavigatorTester.cs
Normal file
218
UICatalog/Scenarios/SearchCollectionNavigatorTester.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Terminal.Gui;
|
||||
using Terminal.Gui.Trees;
|
||||
|
||||
namespace UICatalog.Scenarios {
|
||||
|
||||
[ScenarioMetadata (Name: "Search Collection Nav", Description: "Demonstrates & tests SearchCollectionNavigator.")]
|
||||
[ScenarioCategory ("Controls"), ScenarioCategory ("ListView")]
|
||||
public class SearchCollectionNavigatorTester : Scenario {
|
||||
TabView tabView;
|
||||
|
||||
private int numbeOfNewTabs = 1;
|
||||
|
||||
// Don't create a Window, just return the top-level view
|
||||
public override void Init (Toplevel top, ColorScheme colorScheme)
|
||||
{
|
||||
Application.Init ();
|
||||
Top = top != null ? top : Application.Top;
|
||||
Top.ColorScheme = Colors.Base;
|
||||
}
|
||||
|
||||
public override void Setup ()
|
||||
{
|
||||
var allowMarking = new MenuItem ("Allow _Marking", "", null) {
|
||||
CheckType = MenuItemCheckStyle.Checked,
|
||||
Checked = false
|
||||
};
|
||||
allowMarking.Action = () => allowMarking.Checked = _listView.AllowsMarking = !_listView.AllowsMarking;
|
||||
|
||||
var allowMultiSelection = new MenuItem ("Allow Multi _Selection", "", null) {
|
||||
CheckType = MenuItemCheckStyle.Checked,
|
||||
Checked = false
|
||||
};
|
||||
allowMultiSelection.Action = () => allowMultiSelection.Checked = _listView.AllowsMultipleSelection = !_listView.AllowsMultipleSelection;
|
||||
allowMultiSelection.CanExecute = () => allowMarking.Checked;
|
||||
|
||||
var menu = new MenuBar (new MenuBarItem [] {
|
||||
new MenuBarItem ("_Configure", new MenuItem [] {
|
||||
allowMarking,
|
||||
allowMultiSelection,
|
||||
null,
|
||||
new MenuItem ("_Quit", "", () => Quit(), null, null, Key.Q | Key.CtrlMask),
|
||||
}),
|
||||
new MenuBarItem("_Quit", "CTRL-Q", () => Quit())
|
||||
});
|
||||
|
||||
Top.Add (menu);
|
||||
|
||||
CreateListView ();
|
||||
var vsep = new LineView (Terminal.Gui.Graphs.Orientation.Vertical) {
|
||||
X = Pos.Right (_listView),
|
||||
Y = 1,
|
||||
Height = Dim.Fill ()
|
||||
};
|
||||
Top.Add (vsep);
|
||||
|
||||
}
|
||||
|
||||
ListView _listView = null;
|
||||
|
||||
private void CreateListView ()
|
||||
{
|
||||
var label = new Label () {
|
||||
Text = "ListView",
|
||||
TextAlignment = TextAlignment.Centered,
|
||||
X = 0,
|
||||
Y = 1, // for menu
|
||||
Width = Dim.Percent (50),
|
||||
Height = 1,
|
||||
};
|
||||
Top.Add (label);
|
||||
|
||||
_listView = new ListView () {
|
||||
X = 0,
|
||||
Y = Pos.Bottom(label),
|
||||
Width = Dim.Percent (50) - 1,
|
||||
Height = Dim.Fill (),
|
||||
AllowsMarking = false,
|
||||
AllowsMultipleSelection = false,
|
||||
ColorScheme = Colors.TopLevel
|
||||
};
|
||||
Top.Add (_listView);
|
||||
|
||||
System.Collections.Generic.List<string> items = new string [] {
|
||||
"a",
|
||||
"b",
|
||||
"bb",
|
||||
"c",
|
||||
"ccc",
|
||||
"ccc",
|
||||
"cccc",
|
||||
"ddd",
|
||||
"dddd",
|
||||
"dddd",
|
||||
"ddddd",
|
||||
"dddddd",
|
||||
"ddddddd",
|
||||
"this",
|
||||
"this is a test",
|
||||
"this was a test",
|
||||
"this and",
|
||||
"that and that",
|
||||
"the",
|
||||
"think",
|
||||
"thunk",
|
||||
"thunks",
|
||||
"zip",
|
||||
"zap",
|
||||
"zoo",
|
||||
"@jack",
|
||||
"@sign",
|
||||
"@at",
|
||||
"@ateme",
|
||||
"n@",
|
||||
"n@brown",
|
||||
".net",
|
||||
"$100.00",
|
||||
"$101.00",
|
||||
"$101.10",
|
||||
"$101.11",
|
||||
"appricot",
|
||||
"arm",
|
||||
"丗丙业丞",
|
||||
"丗丙丛",
|
||||
"text",
|
||||
"egg",
|
||||
"candle",
|
||||
" <- space",
|
||||
"q",
|
||||
"quit",
|
||||
"quitter"
|
||||
}.ToList<string> ();
|
||||
items.Sort (StringComparer.OrdinalIgnoreCase);
|
||||
_listView.SetSource (items);
|
||||
}
|
||||
|
||||
TreeView<string> _treeView = null;
|
||||
|
||||
private void CreateTreeView ()
|
||||
{
|
||||
var label = new Label () {
|
||||
Text = "TreeView",
|
||||
TextAlignment = TextAlignment.Centered,
|
||||
X = Pos.Right(_listView) + 2,
|
||||
Y = 1, // for menu
|
||||
Width = Dim.Percent (50),
|
||||
Height = 1,
|
||||
};
|
||||
Top.Add (label);
|
||||
|
||||
_treeView = new TreeView<string> () {
|
||||
X = Pos.Right (_listView) + 2,
|
||||
Y = Pos.Bottom (label),
|
||||
Width = Dim.Percent (50) - 1,
|
||||
Height = Dim.Fill (),
|
||||
ColorScheme = Colors.TopLevel
|
||||
};
|
||||
Top.Add (_treeView);
|
||||
|
||||
System.Collections.Generic.List<string> items = new string [] { "a",
|
||||
"b",
|
||||
"bb",
|
||||
"c",
|
||||
"ccc",
|
||||
"ccc",
|
||||
"cccc",
|
||||
"ddd",
|
||||
"dddd",
|
||||
"dddd",
|
||||
"ddddd",
|
||||
"dddddd",
|
||||
"ddddddd",
|
||||
"this",
|
||||
"this is a test",
|
||||
"this was a test",
|
||||
"this and",
|
||||
"that and that",
|
||||
"the",
|
||||
"think",
|
||||
"thunk",
|
||||
"thunks",
|
||||
"zip",
|
||||
"zap",
|
||||
"zoo",
|
||||
"@jack",
|
||||
"@sign",
|
||||
"@at",
|
||||
"@ateme",
|
||||
"n@",
|
||||
"n@brown",
|
||||
".net",
|
||||
"$100.00",
|
||||
"$101.00",
|
||||
"$101.10",
|
||||
"$101.11",
|
||||
"appricot",
|
||||
"arm",
|
||||
"丗丙业丞",
|
||||
"丗丙丛",
|
||||
"text",
|
||||
"egg",
|
||||
"candle",
|
||||
" <- space",
|
||||
"q",
|
||||
"quit",
|
||||
"quitter"
|
||||
}.ToList<string> ();
|
||||
items.Sort (StringComparer.OrdinalIgnoreCase);
|
||||
_treeView.AddObjects (items);
|
||||
}
|
||||
private void Quit ()
|
||||
{
|
||||
Application.RequestStop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
using Terminal.Gui;
|
||||
using Xunit;
|
||||
|
||||
namespace UnitTests {
|
||||
namespace Terminal.Gui.Core {
|
||||
public class SearchCollectionNavigatorTests {
|
||||
|
||||
[Fact]
|
||||
public void TestSearchCollectionNavigator_Cycling ()
|
||||
{
|
||||
var s = new string []{
|
||||
var strings = new string []{
|
||||
"appricot",
|
||||
"arm",
|
||||
"bat",
|
||||
@@ -15,12 +15,12 @@ namespace UnitTests {
|
||||
"candle"
|
||||
};
|
||||
|
||||
var n = new SearchCollectionNavigator ();
|
||||
Assert.Equal (2, n.CalculateNewIndex (s, 0, 'b'));
|
||||
Assert.Equal (3, n.CalculateNewIndex (s, 2, 'b'));
|
||||
var n = new SearchCollectionNavigator (strings);
|
||||
Assert.Equal (2, n.CalculateNewIndex ( 0, 'b'));
|
||||
Assert.Equal (3, n.CalculateNewIndex ( 2, 'b'));
|
||||
|
||||
// if 4 (candle) is selected it should loop back to bat
|
||||
Assert.Equal (2, n.CalculateNewIndex (s, 4, 'b'));
|
||||
Assert.Equal (2, n.CalculateNewIndex ( 4, 'b'));
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace UnitTests {
|
||||
[Fact]
|
||||
public void TestSearchCollectionNavigator_ToSearchText ()
|
||||
{
|
||||
var s = new string []{
|
||||
var strings = new string []{
|
||||
"appricot",
|
||||
"arm",
|
||||
"bat",
|
||||
@@ -37,19 +37,19 @@ namespace UnitTests {
|
||||
"candle"
|
||||
};
|
||||
|
||||
var n = new SearchCollectionNavigator ();
|
||||
Assert.Equal (2, n.CalculateNewIndex (s, 0, 'b'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 2, 'b'));
|
||||
var n = new SearchCollectionNavigator (strings);
|
||||
Assert.Equal (2, n.CalculateNewIndex (0, 'b'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (2, 'b'));
|
||||
|
||||
// another 'b' means searching for "bbb" which does not exist
|
||||
// so we go back to looking for "b" as a fresh key strike
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 2, 'b'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (2, 'b'));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSearchCollectionNavigator_FullText ()
|
||||
{
|
||||
var s = new string []{
|
||||
var strings = new string []{
|
||||
"appricot",
|
||||
"arm",
|
||||
"ta",
|
||||
@@ -59,23 +59,23 @@ namespace UnitTests {
|
||||
"candle"
|
||||
};
|
||||
|
||||
var n = new SearchCollectionNavigator ();
|
||||
Assert.Equal (2, n.CalculateNewIndex (s, 0, 't'));
|
||||
var n = new SearchCollectionNavigator (strings);
|
||||
Assert.Equal (2, n.CalculateNewIndex (0, 't'));
|
||||
|
||||
// should match "te" in "text"
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 2, 'e'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (2, 'e'));
|
||||
|
||||
// still matches text
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 4, 'x'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (4, 'x'));
|
||||
|
||||
// nothing starts texa so it jumps to a for appricot
|
||||
Assert.Equal (0, n.CalculateNewIndex (s, 4, 'a'));
|
||||
Assert.Equal (0, n.CalculateNewIndex (4, 'a'));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSearchCollectionNavigator_Unicode ()
|
||||
{
|
||||
var s = new string []{
|
||||
var strings = new string []{
|
||||
"appricot",
|
||||
"arm",
|
||||
"ta",
|
||||
@@ -86,27 +86,27 @@ namespace UnitTests {
|
||||
"candle"
|
||||
};
|
||||
|
||||
var n = new SearchCollectionNavigator ();
|
||||
Assert.Equal (3, n.CalculateNewIndex (s, 0, '丗'));
|
||||
var n = new SearchCollectionNavigator (strings);
|
||||
Assert.Equal (3, n.CalculateNewIndex (0, '丗'));
|
||||
|
||||
// 丗丙业丞 is as good a match as 丗丙丛
|
||||
// so when doing multi character searches we should
|
||||
// prefer to stay on the same index unless we invalidate
|
||||
// our typed text
|
||||
Assert.Equal (3, n.CalculateNewIndex (s, 3, '丙'));
|
||||
Assert.Equal (3, n.CalculateNewIndex (3, '丙'));
|
||||
|
||||
// No longer matches 丗丙业丞 and now only matches 丗丙丛
|
||||
// so we should move to the new match
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 3, '丛'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (3, '丛'));
|
||||
|
||||
// nothing starts "丗丙丛a" so it jumps to a for appricot
|
||||
Assert.Equal (0, n.CalculateNewIndex (s, 4, 'a'));
|
||||
Assert.Equal (0, n.CalculateNewIndex (4, 'a'));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSearchCollectionNavigator_AtSymbol ()
|
||||
{
|
||||
var s = new string []{
|
||||
var strings = new string []{
|
||||
"appricot",
|
||||
"arm",
|
||||
"ta",
|
||||
@@ -117,10 +117,10 @@ namespace UnitTests {
|
||||
"candle"
|
||||
};
|
||||
|
||||
var n = new SearchCollectionNavigator ();
|
||||
Assert.Equal (3, n.CalculateNewIndex (s, 0, '@'));
|
||||
Assert.Equal (3, n.CalculateNewIndex (s, 3, 'b'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (s, 3, 'b'));
|
||||
var n = new SearchCollectionNavigator (strings);
|
||||
Assert.Equal (3, n.CalculateNewIndex (0, '@'));
|
||||
Assert.Equal (3, n.CalculateNewIndex (3, 'b'));
|
||||
Assert.Equal (4, n.CalculateNewIndex (3, 'b'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user