mirror of https://github.com/buggins/dlangui.git
FileDialog - move to file in list by typing first letters of its name - fix #312
This commit is contained in:
parent
a112994a4f
commit
a60b65a338
|
@ -212,6 +212,39 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
|||
return openDirectory(_path, null);
|
||||
}
|
||||
|
||||
protected void locateFileInList(dstring pattern) {
|
||||
if (!pattern.length)
|
||||
return;
|
||||
int selection = _fileList.row;
|
||||
if (selection < 0)
|
||||
selection = 0;
|
||||
int index = -1; // first matched item
|
||||
string mask = pattern.toUTF8;
|
||||
// search forward from current row to end of list
|
||||
for(int i = selection; i < _entries.length; i++) {
|
||||
string fname = baseName(_entries[i].name);
|
||||
if (fname.startsWith(mask)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < 0) {
|
||||
// search from beginning of list to current position
|
||||
for(int i = 0; i < selection && i < _entries.length; i++) {
|
||||
string fname = baseName(_entries[i].name);
|
||||
if (fname.startsWith(mask)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
// move selection
|
||||
_fileList.selectCell(1, index + 1);
|
||||
window.update();
|
||||
}
|
||||
}
|
||||
|
||||
protected bool openDirectory(string dir, string selectedItemPath) {
|
||||
dir = buildNormalizedPath(dir);
|
||||
Log.d("FileDialog.openDirectory(", dir, ")");
|
||||
|
@ -502,6 +535,12 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
|||
_fileList.cellPopupMenu = &getCellPopupMenu;
|
||||
_fileList.menuItemAction = &handleAction;
|
||||
|
||||
_fileList.keyEvent = delegate(Widget source, KeyEvent event) {
|
||||
if (_shortcutHelper.onKeyEvent(event))
|
||||
locateFileInList(_shortcutHelper.text);
|
||||
return false;
|
||||
};
|
||||
|
||||
rightPanel.addChild(_edPath);
|
||||
rightPanel.addChild(_fileList);
|
||||
rightPanel.addChild(fnlayout);
|
||||
|
@ -530,6 +569,8 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
|||
|
||||
}
|
||||
|
||||
protected TextTypingShortcutHelper _shortcutHelper;
|
||||
|
||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||
override void layout(Rect rc) {
|
||||
super.layout(rc);
|
||||
|
|
|
@ -1792,6 +1792,57 @@ class WidgetGroupDefaultDrawing : WidgetGroup {
|
|||
}
|
||||
}
|
||||
|
||||
/// helper for locating items in list, tree, table or other controls by typing their name
|
||||
struct TextTypingShortcutHelper {
|
||||
int timeoutMillis = 800; // expiration time for entered text; after timeout collected text will be cleared
|
||||
private long _lastUpdateTimeStamp;
|
||||
private dchar[] _text;
|
||||
/// cancel text collection (next typed text will be collected from scratch)
|
||||
void cancel() {
|
||||
_text.length = 0;
|
||||
_lastUpdateTimeStamp = 0;
|
||||
}
|
||||
/// returns collected text string - use it for lookup
|
||||
@property dstring text() { return _text.dup; }
|
||||
/// pass key event here; returns true if search text is updated and you can move selection using it
|
||||
bool onKeyEvent(KeyEvent event) {
|
||||
long ts = currentTimeMillis;
|
||||
if (_lastUpdateTimeStamp && ts - _lastUpdateTimeStamp > timeoutMillis)
|
||||
cancel();
|
||||
if (event.action == KeyAction.Text) {
|
||||
_text ~= event.text;
|
||||
_lastUpdateTimeStamp = ts;
|
||||
return _text.length > 0;
|
||||
}
|
||||
if (event.action == KeyAction.KeyDown || event.action == KeyAction.KeyUp) {
|
||||
switch (event.keyCode) with (KeyCode) {
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
case UP:
|
||||
case DOWN:
|
||||
case HOME:
|
||||
case END:
|
||||
case TAB:
|
||||
case PAGEUP:
|
||||
case PAGEDOWN:
|
||||
case BACK:
|
||||
cancel();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// cancel text typing on some mouse events, if necessary
|
||||
void onMouseEvent(MouseEvent event) {
|
||||
if (event.action == MouseAction.ButtonUp || event.action == MouseAction.ButtonDown)
|
||||
cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum ONE_SECOND = 10_000_000L;
|
||||
|
||||
/// Helper to handle animation progress
|
||||
|
|
Loading…
Reference in New Issue