diff --git a/lib/libdlangui.a b/lib/libdlangui.a new file mode 100644 index 00000000..88319797 Binary files /dev/null and b/lib/libdlangui.a differ diff --git a/src/dlangui/widgets/lists.d b/src/dlangui/widgets/lists.d index 5fcb083a..3cff394f 100644 --- a/src/dlangui/widgets/lists.d +++ b/src/dlangui/widgets/lists.d @@ -24,6 +24,7 @@ import dlangui.widgets.scrollbar; import dlangui.widgets.layouts; import dlangui.core.signals; + /** interface - slot for onAdapterChangeListener */ interface OnAdapterChangeHandler { void onAdapterChange(ListAdapter source); @@ -1400,6 +1401,11 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler { } class StringListWidget : ListWidget { + import std.conv : to; + import std.datetime : dto = to, StopWatch; + private dstring _searchString; + private StopWatch _stopWatch; + this(string ID = null) { super(ID); styleId = STYLE_EDIT_BOX; @@ -1465,6 +1471,74 @@ class StringListWidget : ListWidget { return ""; return (cast(StringListAdapter)adapter).items.get(_selectedItemIndex); } + + override bool onKeyEvent(KeyEvent event) { + if (itemCount == 0) return false; + + // Accept user input and try to find a match in the list. + if (event.action == KeyAction.Text) { + if ( !_stopWatch.running) { _stopWatch.start; } + + auto timePassed = _stopWatch.peek.dto!("seconds", float)(); // dtop is std.datetime.to + + if (timePassed > 0.5) _searchString = ""d; + _searchString ~= to!dchar(event.text.toUTF8); + _stopWatch.reset; + + if ( selectClosestMatch(_searchString) ) { + invalidate(); + return true; + } + } + + return super.onKeyEvent(event); + } + + + private bool selectClosestMatch(dstring term) { + import std.uni : toLower; + if (term.length == 0) return false; + auto myItems = (cast(StringListAdapter)adapter).items; + + // Perfect match or best match + int[] indexes; + foreach(int itemIndex; 0 .. myItems.length) { + dstring item = myItems.get(itemIndex); + + if (item == term) { + // Perfect match + indexes ~= itemIndex; + break; + } else { + // Term approximate to something + bool addItem = true; + foreach(int termIndex; 0 .. cast(int)term.length) { + if (termIndex < item.length) { + if ( toLower(term[termIndex]) != toLower(item[termIndex]) ) { + addItem = false; + break; + } + } + } + + if (addItem) { indexes ~= itemIndex; } + + } + } + + // Return best match + if (indexes.length > 0) { + selectItem(indexes[0]); + itemSelected(this, indexes[0]); + return true; + } + + return false; // Did not find term + + } + + + } //import dlangui.widgets.metadata;