Grid: add cell selection and activation listeners; File Dialog - navigation by directories

This commit is contained in:
Vadim Lopatin 2014-12-17 17:40:11 +03:00
parent a51c058696
commit 5e30aee4fc
5 changed files with 113 additions and 12 deletions

View File

@ -294,7 +294,7 @@ extern (C) int UIAppMain(string[] args) {
caption = "Open Text File"d;
FileDialog dlg = new FileDialog(caption, window);
dlg.onDialogResult = delegate(Dialog dlg, Action result) {
//
Log.d("FileDialog.onDialogResult");
};
dlg.show();
return true;

View File

@ -309,25 +309,42 @@ enum MouseButton : ubyte {
/// Mouse button state details for MouseEvent
struct ButtonDetails {
/// Clock.currStdTime() for down event of this button (0 if button is up).
long _downTs;
protected long _downTs;
/// Clock.currStdTime() for up event of this button (0 if button is still down).
long _upTs;
protected long _upTs;
/// x coordinates of down event
short _downX;
protected short _downX;
/// y coordinates of down event
short _downY;
protected short _downY;
/// mouse button flags when down event occured
ushort _downFlags;
protected ushort _downFlags;
/// true if button is made down shortly after up - valid if button is down
protected bool _doubleClick;
/// Returns true if button is made down shortly after up
@property bool doubleClick() {
return _doubleClick;
}
static final long DOUBLE_CLICK_THRESHOLD_MS = 200;
/// update for button down
void down(short x, short y, ushort flags) {
//Log.d("Button down ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs);
long oldDownTs = _downTs;
_downX = x;
_downY = y;
_downFlags = flags;
_upTs = 0;
_downTs = std.datetime.Clock.currStdTime;
long downIntervalMs = (_downTs - oldDownTs) / 10000;
//Log.d("Button down ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs, " downInterval=", downIntervalMs);
_doubleClick = (oldDownTs && downIntervalMs < DOUBLE_CLICK_THRESHOLD_MS);
}
/// update for button up
void up(short x, short y, ushort flags) {
//Log.d("Button up ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs);
_doubleClick = false;
_upTs = std.datetime.Clock.currStdTime;
}
/// returns true if button is currently pressed
@ -383,6 +400,14 @@ class MouseEvent {
@property ref ButtonDetails rbutton() { return _rbutton; }
/// middle button state details
@property ref ButtonDetails mbutton() { return _mbutton; }
/// button state details for event's button
@property ref ButtonDetails buttonDetails() {
if (_button == MouseButton.Right)
return _rbutton;
if (_button == MouseButton.Middle)
return _mbutton;
return _lbutton;
}
/// button which caused ButtonUp or ButtonDown action
@property MouseButton button() { return _button; }
/// action
@ -397,6 +422,14 @@ class MouseEvent {
@property short x() { return _x; }
/// y coordinate of mouse pointer (relative to window client area)
@property short y() { return _y; }
/// Returns true for ButtonDown event when button is pressed second time in short interval after pressing first time
@property bool doubleClick() {
if (_action != MouseAction.ButtonDown)
return false;
return buttonDetails.doubleClick;
}
/// get event tracking widget to override
@property Widget trackingWidget() { return _trackingWidget; }
/// returns mouse button tracking flag

View File

@ -69,11 +69,13 @@ class FileDialog : Dialog, CustomGridCellAdapter {
protected DirEntry[] _entries;
protected bool _isRoot;
this(UIString caption, Window parent, uint fileDialogFlags = DialogFlag.Modal | FileDialogFlag.FileMustExist) {
this(UIString caption, Window parent, uint fileDialogFlags = DialogFlag.Modal | DialogFlag.Resizable | FileDialogFlag.FileMustExist) {
super(caption, parent, fileDialogFlags);
}
protected bool openDirectory(string dir) {
dir = buildNormalizedPath(dir);
Log.d("FileDialog.openDirectory(", dir, ")");
list.rows = 0;
string[] filters;
if (!listDirectory(dir, true, true, filters, _entries))
@ -146,18 +148,27 @@ class FileDialog : Dialog, CustomGridCellAdapter {
btn.orientation = Orientation.Vertical;
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
btn.focusable = false;
btn.onClickListener = delegate(Widget source) {
openDirectory(root.path);
return true;
};
adapter.widgets.add(btn);
}
list.ownAdapter = adapter;
list.layoutWidth = WRAP_CONTENT;
list.layoutHeight = FILL_PARENT;
list.onItemClickListener = delegate(Widget source, int itemIndex) {
openDirectory(_roots[itemIndex].path);
return true;
};
return list;
}
protected void onItemActivated(int index) {
DirEntry e = _entries[index];
if (e.isDir) {
openDirectory(e.name);
} else if (e.isFile) {
}
}
/// override to implement creation of dialog controls
override void init() {
_roots = getRootPaths;
@ -204,7 +215,15 @@ class FileDialog : Dialog, CustomGridCellAdapter {
//Log.d("path: ", path);
list.customCellAdapter = this;
list.onCellActivated = delegate(GridWidgetBase source, int col, int row) {
onItemActivated(row);
};
openDirectory(currentDir);
minWidth = 600;
minHeight = 400;
layoutWidth = FILL_PARENT;
list.layoutHeight = FILL_PARENT;
layoutHeight = FILL_PARENT;
}
}

View File

@ -406,6 +406,23 @@ class SDLWindow : Window {
event = new MouseEvent(action, btn, lastFlags, lastx, lasty);
}
if (event) {
ButtonDetails * pbuttonDetails = null;
if (button == MouseButton.Left)
pbuttonDetails = &_lbutton;
else if (button == MouseButton.Right)
pbuttonDetails = &_rbutton;
else if (button == MouseButton.Middle)
pbuttonDetails = &_mbutton;
if (pbuttonDetails) {
if (action == MouseAction.ButtonDown) {
pbuttonDetails.down(cast(short)x, cast(short)y, lastFlags);
} else if (action == MouseAction.ButtonUp) {
pbuttonDetails.up(cast(short)x, cast(short)y, lastFlags);
}
}
event.lbutton = _lbutton;
event.rbutton = _rbutton;
event.mbutton = _mbutton;
bool res = dispatchMouseEvent(event);
if (res) {
debug(mouse) Log.d("Calling update() after mouse event");

View File

@ -202,6 +202,7 @@ enum GridActions : int {
SelectDocumentEnd,
}
/// Adapter for custom drawing of some cells in grid widgets
interface CustomGridCellAdapter {
/// return true for custom drawn cell
bool isCustomCell(int col, int row);
@ -211,8 +212,23 @@ interface CustomGridCellAdapter {
void drawCell(DrawBuf buf, Rect rc, int col, int row);
}
/// Callback for handling of cell selection
interface CellSelectedHandler {
void onCellSelected(GridWidgetBase source, int col, int row);
}
/// Callback for handling of cell double click or Enter key press
interface CellActivatedHandler {
void onCellActivated(GridWidgetBase source, int col, int row);
}
/// Abstract grid widget
class GridWidgetBase : ScrollWidgetBase {
/// Callback to handle selection change
Listener!CellSelectedHandler onCellSelected;
/// Callback to handle cell double click
Listener!CellActivatedHandler onCellActivated;
protected CustomGridCellAdapter _customCellAdapter;
/// Get adapter to override drawing of some particular cells
@ -589,6 +605,18 @@ class GridWidgetBase : ScrollWidgetBase {
calcScrollableAreaPos();
if (makeVisible)
makeCellVisible(_col, _row);
if (onCellSelected.assigned)
onCellSelected(this, _col, _row);
return true;
}
/// Select cell and call onCellActivated handler
bool activateCell(int col, int row) {
if (_col != col || _row != row) {
selectCell(col, row, true);
}
if (onCellActivated.assigned)
onCellActivated(this, this.col, this.row);
return true;
}
@ -611,7 +639,11 @@ class GridWidgetBase : ScrollWidgetBase {
}
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
if (cellFound && normalCell) {
selectCell(c, r);
if (c == _col && r == _row && event.doubleClick) {
activateCell(c, r);
} else {
selectCell(c, r);
}
}
return true;
}