mirror of https://github.com/buggins/dlangui.git
Grid: add cell selection and activation listeners; File Dialog - navigation by directories
This commit is contained in:
parent
a51c058696
commit
5e30aee4fc
|
@ -294,7 +294,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
caption = "Open Text File"d;
|
caption = "Open Text File"d;
|
||||||
FileDialog dlg = new FileDialog(caption, window);
|
FileDialog dlg = new FileDialog(caption, window);
|
||||||
dlg.onDialogResult = delegate(Dialog dlg, Action result) {
|
dlg.onDialogResult = delegate(Dialog dlg, Action result) {
|
||||||
//
|
Log.d("FileDialog.onDialogResult");
|
||||||
};
|
};
|
||||||
dlg.show();
|
dlg.show();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -309,25 +309,42 @@ enum MouseButton : ubyte {
|
||||||
/// Mouse button state details for MouseEvent
|
/// Mouse button state details for MouseEvent
|
||||||
struct ButtonDetails {
|
struct ButtonDetails {
|
||||||
/// Clock.currStdTime() for down event of this button (0 if button is up).
|
/// 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).
|
/// Clock.currStdTime() for up event of this button (0 if button is still down).
|
||||||
long _upTs;
|
protected long _upTs;
|
||||||
/// x coordinates of down event
|
/// x coordinates of down event
|
||||||
short _downX;
|
protected short _downX;
|
||||||
/// y coordinates of down event
|
/// y coordinates of down event
|
||||||
short _downY;
|
protected short _downY;
|
||||||
/// mouse button flags when down event occured
|
/// 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
|
/// update for button down
|
||||||
void down(short x, short y, ushort flags) {
|
void down(short x, short y, ushort flags) {
|
||||||
|
//Log.d("Button down ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs);
|
||||||
|
long oldDownTs = _downTs;
|
||||||
_downX = x;
|
_downX = x;
|
||||||
_downY = y;
|
_downY = y;
|
||||||
_downFlags = flags;
|
_downFlags = flags;
|
||||||
_upTs = 0;
|
_upTs = 0;
|
||||||
_downTs = std.datetime.Clock.currStdTime;
|
_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
|
/// update for button up
|
||||||
void up(short x, short y, ushort flags) {
|
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;
|
_upTs = std.datetime.Clock.currStdTime;
|
||||||
}
|
}
|
||||||
/// returns true if button is currently pressed
|
/// returns true if button is currently pressed
|
||||||
|
@ -383,6 +400,14 @@ class MouseEvent {
|
||||||
@property ref ButtonDetails rbutton() { return _rbutton; }
|
@property ref ButtonDetails rbutton() { return _rbutton; }
|
||||||
/// middle button state details
|
/// middle button state details
|
||||||
@property ref ButtonDetails mbutton() { return _mbutton; }
|
@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
|
/// button which caused ButtonUp or ButtonDown action
|
||||||
@property MouseButton button() { return _button; }
|
@property MouseButton button() { return _button; }
|
||||||
/// action
|
/// action
|
||||||
|
@ -397,6 +422,14 @@ class MouseEvent {
|
||||||
@property short x() { return _x; }
|
@property short x() { return _x; }
|
||||||
/// y coordinate of mouse pointer (relative to window client area)
|
/// y coordinate of mouse pointer (relative to window client area)
|
||||||
@property short y() { return _y; }
|
@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
|
/// get event tracking widget to override
|
||||||
@property Widget trackingWidget() { return _trackingWidget; }
|
@property Widget trackingWidget() { return _trackingWidget; }
|
||||||
/// returns mouse button tracking flag
|
/// returns mouse button tracking flag
|
||||||
|
|
|
@ -69,11 +69,13 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
protected DirEntry[] _entries;
|
protected DirEntry[] _entries;
|
||||||
protected bool _isRoot;
|
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);
|
super(caption, parent, fileDialogFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool openDirectory(string dir) {
|
protected bool openDirectory(string dir) {
|
||||||
|
dir = buildNormalizedPath(dir);
|
||||||
|
Log.d("FileDialog.openDirectory(", dir, ")");
|
||||||
list.rows = 0;
|
list.rows = 0;
|
||||||
string[] filters;
|
string[] filters;
|
||||||
if (!listDirectory(dir, true, true, filters, _entries))
|
if (!listDirectory(dir, true, true, filters, _entries))
|
||||||
|
@ -146,18 +148,27 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
btn.orientation = Orientation.Vertical;
|
btn.orientation = Orientation.Vertical;
|
||||||
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
|
btn.styleId = "TRANSPARENT_BUTTON_BACKGROUND";
|
||||||
btn.focusable = false;
|
btn.focusable = false;
|
||||||
btn.onClickListener = delegate(Widget source) {
|
|
||||||
openDirectory(root.path);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
adapter.widgets.add(btn);
|
adapter.widgets.add(btn);
|
||||||
}
|
}
|
||||||
list.ownAdapter = adapter;
|
list.ownAdapter = adapter;
|
||||||
list.layoutWidth = WRAP_CONTENT;
|
list.layoutWidth = WRAP_CONTENT;
|
||||||
list.layoutHeight = FILL_PARENT;
|
list.layoutHeight = FILL_PARENT;
|
||||||
|
list.onItemClickListener = delegate(Widget source, int itemIndex) {
|
||||||
|
openDirectory(_roots[itemIndex].path);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
return list;
|
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 to implement creation of dialog controls
|
||||||
override void init() {
|
override void init() {
|
||||||
_roots = getRootPaths;
|
_roots = getRootPaths;
|
||||||
|
@ -204,7 +215,15 @@ class FileDialog : Dialog, CustomGridCellAdapter {
|
||||||
//Log.d("path: ", path);
|
//Log.d("path: ", path);
|
||||||
|
|
||||||
list.customCellAdapter = this;
|
list.customCellAdapter = this;
|
||||||
|
list.onCellActivated = delegate(GridWidgetBase source, int col, int row) {
|
||||||
|
onItemActivated(row);
|
||||||
|
};
|
||||||
|
|
||||||
openDirectory(currentDir);
|
openDirectory(currentDir);
|
||||||
|
minWidth = 600;
|
||||||
|
minHeight = 400;
|
||||||
|
layoutWidth = FILL_PARENT;
|
||||||
|
list.layoutHeight = FILL_PARENT;
|
||||||
|
layoutHeight = FILL_PARENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -406,6 +406,23 @@ class SDLWindow : Window {
|
||||||
event = new MouseEvent(action, btn, lastFlags, lastx, lasty);
|
event = new MouseEvent(action, btn, lastFlags, lastx, lasty);
|
||||||
}
|
}
|
||||||
if (event) {
|
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);
|
bool res = dispatchMouseEvent(event);
|
||||||
if (res) {
|
if (res) {
|
||||||
debug(mouse) Log.d("Calling update() after mouse event");
|
debug(mouse) Log.d("Calling update() after mouse event");
|
||||||
|
|
|
@ -202,6 +202,7 @@ enum GridActions : int {
|
||||||
SelectDocumentEnd,
|
SelectDocumentEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adapter for custom drawing of some cells in grid widgets
|
||||||
interface CustomGridCellAdapter {
|
interface CustomGridCellAdapter {
|
||||||
/// return true for custom drawn cell
|
/// return true for custom drawn cell
|
||||||
bool isCustomCell(int col, int row);
|
bool isCustomCell(int col, int row);
|
||||||
|
@ -211,8 +212,23 @@ interface CustomGridCellAdapter {
|
||||||
void drawCell(DrawBuf buf, Rect rc, int col, int row);
|
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
|
/// Abstract grid widget
|
||||||
class GridWidgetBase : ScrollWidgetBase {
|
class GridWidgetBase : ScrollWidgetBase {
|
||||||
|
/// Callback to handle selection change
|
||||||
|
Listener!CellSelectedHandler onCellSelected;
|
||||||
|
/// Callback to handle cell double click
|
||||||
|
Listener!CellActivatedHandler onCellActivated;
|
||||||
|
|
||||||
protected CustomGridCellAdapter _customCellAdapter;
|
protected CustomGridCellAdapter _customCellAdapter;
|
||||||
|
|
||||||
/// Get adapter to override drawing of some particular cells
|
/// Get adapter to override drawing of some particular cells
|
||||||
|
@ -589,6 +605,18 @@ class GridWidgetBase : ScrollWidgetBase {
|
||||||
calcScrollableAreaPos();
|
calcScrollableAreaPos();
|
||||||
if (makeVisible)
|
if (makeVisible)
|
||||||
makeCellVisible(_col, _row);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,8 +639,12 @@ class GridWidgetBase : ScrollWidgetBase {
|
||||||
}
|
}
|
||||||
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
||||||
if (cellFound && normalCell) {
|
if (cellFound && normalCell) {
|
||||||
|
if (c == _col && r == _row && event.doubleClick) {
|
||||||
|
activateCell(c, r);
|
||||||
|
} else {
|
||||||
selectCell(c, r);
|
selectCell(c, r);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (event.action == MouseAction.Move && (event.flags & MouseFlag.LButton)) {
|
if (event.action == MouseAction.Move && (event.flags & MouseFlag.LButton)) {
|
||||||
|
|
Loading…
Reference in New Issue