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;
|
||||
FileDialog dlg = new FileDialog(caption, window);
|
||||
dlg.onDialogResult = delegate(Dialog dlg, Action result) {
|
||||
//
|
||||
Log.d("FileDialog.onDialogResult");
|
||||
};
|
||||
dlg.show();
|
||||
return true;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue