triple mouse click support; select whole line on mouse triple click - close #193

This commit is contained in:
Vadim Lopatin 2016-06-28 15:47:34 +03:00
parent 543259fe88
commit f68cce12b1
2 changed files with 41 additions and 2 deletions

View File

@ -722,6 +722,8 @@ __gshared long DOUBLE_CLICK_THRESHOLD_MS = 400;
/// 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) set after double click to time when first click occured.
protected long _prevDownTs;
/// 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).
protected 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).
@ -734,12 +736,19 @@ struct ButtonDetails {
protected ushort _downFlags; protected ushort _downFlags;
/// true if button is made down shortly after up - valid if button is down /// true if button is made down shortly after up - valid if button is down
protected bool _doubleClick; protected bool _doubleClick;
/// true if button is made down twice shortly after up - valid if button is down
protected bool _tripleClick;
/// Returns true if button is made down shortly after up /// Returns true if button is made down shortly after up
@property bool doubleClick() { @property bool doubleClick() {
return _doubleClick; return _doubleClick;
} }
/// Returns true if button is made down twice shortly after up
@property bool tripleClick() {
return _tripleClick;
}
void reset() { void reset() {
@ -759,14 +768,18 @@ struct ButtonDetails {
_upTs = 0; _upTs = 0;
_downTs = std.datetime.Clock.currStdTime; _downTs = std.datetime.Clock.currStdTime;
long downIntervalMs = (_downTs - oldDownTs) / 10000; long downIntervalMs = (_downTs - oldDownTs) / 10000;
long prevDownIntervalMs = (_downTs - _prevDownTs) / 10000;
//Log.d("Button down ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs, " downInterval=", downIntervalMs); //Log.d("Button down ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs, " downInterval=", downIntervalMs);
_doubleClick = (oldDownTs && downIntervalMs < DOUBLE_CLICK_THRESHOLD_MS); _tripleClick = (prevDownIntervalMs && prevDownIntervalMs < DOUBLE_CLICK_THRESHOLD_MS * 2);
_doubleClick = !_tripleClick && (oldDownTs && downIntervalMs < DOUBLE_CLICK_THRESHOLD_MS);
_prevDownTs = _doubleClick ? oldDownTs : 0;
} }
/// update for button up /// update for button up
void up(short x, short y, ushort flags) { void up(short x, short y, ushort flags) {
static import std.datetime; static import std.datetime;
//Log.d("Button up ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs); //Log.d("Button up ", x, ",", y, " _downTs=", _downTs, " _upTs=", _upTs);
_doubleClick = false; _doubleClick = false;
_tripleClick = 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
@ -860,6 +873,13 @@ class MouseEvent {
return buttonDetails.doubleClick; return buttonDetails.doubleClick;
} }
/// Returns true for ButtonDown event when button is pressed third time in short interval after pressing first time
@property bool tripleClick() {
if (_action != MouseAction.ButtonDown)
return false;
return buttonDetails.tripleClick;
}
/// 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

View File

@ -1116,6 +1116,23 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
} }
} }
protected void selectLineByMouse(int x, int y, bool onSameLineOnly = true) {
TextPosition oldCaretPos = _caretPos;
TextPosition newPos = clientToTextPos(Point(x,y));
if (onSameLineOnly && newPos.line != oldCaretPos.line)
return; // different lines
TextRange r = content.lineRange(newPos.line);
if (r.start < r.end) {
_selectionRange = r;
_caretPos = r.end;
invalidate();
requestActionsUpdate();
} else {
_caretPos = newPos;
updateSelectionAfterCursorMovement(oldCaretPos, false);
}
}
protected void updateCaretPositionByMouse(int x, int y, bool selecting) { protected void updateCaretPositionByMouse(int x, int y, bool selecting) {
TextPosition oldCaretPos = _caretPos; TextPosition oldCaretPos = _caretPos;
TextPosition newPos = clientToTextPos(Point(x,y)); TextPosition newPos = clientToTextPos(Point(x,y));
@ -1709,7 +1726,9 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
setFocus(); setFocus();
startCaretBlinking(); startCaretBlinking();
cancelHoverTimer(); cancelHoverTimer();
if (event.doubleClick) { if (event.tripleClick) {
selectLineByMouse(event.x - _clientRect.left, event.y - _clientRect.top);
} else if (event.doubleClick) {
selectWordByMouse(event.x - _clientRect.left, event.y - _clientRect.top); selectWordByMouse(event.x - _clientRect.left, event.y - _clientRect.top);
} else { } else {
auto doSelect = cast(bool)(event.keyFlags & MouseFlag.Shift); auto doSelect = cast(bool)(event.keyFlags & MouseFlag.Shift);