From 53290919c873f319ce8eb0a40147c62fdfd147f6 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Sat, 26 Mar 2016 16:32:19 -0400 Subject: [PATCH] Detect double and triple clicks --- src/cursor.go | 19 +++++++++++++++++++ src/micro.go | 5 +++-- src/view.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/cursor.go b/src/cursor.go index c7435b62..cdfcafe4 100644 --- a/src/cursor.go +++ b/src/cursor.go @@ -90,6 +90,25 @@ func (c *Cursor) GetSelection() string { return string([]rune(c.v.buf.text)[c.selectionStart : c.selectionEnd+1]) } +// SelectLine selects the current line +func (c *Cursor) SelectLine() { + c.Start() + c.selectionStart = c.Loc() + c.End() + c.selectionEnd = c.Loc() +} + +// AddLineToSelection adds the current line to the selection +func (c *Cursor) AddLineToSelection() { + if c.loc < c.selectionStart { + c.Start() + c.selectionStart = c.Loc() + } else if c.loc > c.selectionEnd { + c.End() + c.selectionEnd = c.Loc() + } +} + // RuneUnder returns the rune under the cursor func (c *Cursor) RuneUnder() rune { line := c.v.buf.lines[c.y] diff --git a/src/micro.go b/src/micro.go index 6c5abe0a..e3df3c7a 100644 --- a/src/micro.go +++ b/src/micro.go @@ -10,8 +10,9 @@ import ( ) const ( - synLinesUp = 75 // How many lines up to look to do syntax highlighting - synLinesDown = 75 // How many lines down to look to do syntax highlighting + synLinesUp = 75 // How many lines up to look to do syntax highlighting + synLinesDown = 75 // How many lines down to look to do syntax highlighting + doubleClickThreshold = 400 // How many milliseconds to wait before a second click is not a double click ) // The main screen diff --git a/src/view.go b/src/view.go index 2884d0cc..c0272d5b 100644 --- a/src/view.go +++ b/src/view.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "strconv" "strings" + "time" ) // The View struct stores information about a view into a buffer. @@ -44,6 +45,17 @@ type View struct { // mouse release events mouseReleased bool + // This stores when the last click was + // This is useful for detecting double and triple clicks + lastClickTime time.Time + + // Was the last mouse event actually a double click? + // Useful for detecting triple clicks -- if a double click is detected + // but the last mouse event was actually a double click, it's a triple click + doubleClick bool + // Same here, just to keep track for mouse move events + tripleClick bool + // Syntax highlighting matches matches SyntaxMatches // The matches from the last frame @@ -90,6 +102,7 @@ func NewViewWidthHeight(buf *Buffer, w, h int) *View { // Set mouseReleased to true because we assume the mouse is not being pressed when // the editor is opened v.mouseReleased = true + v.lastClickTime = time.Time{} return v } @@ -432,14 +445,47 @@ func (v *View) HandleEvent(event tcell.Event) { switch button { case tcell.Button1: // Left click + origX, origY := v.cursor.x, v.cursor.y v.MoveToMouseClick(x, y) - loc := v.cursor.Loc() if v.mouseReleased { - v.cursor.selectionStart = loc + if (time.Since(v.lastClickTime)/time.Millisecond < doubleClickThreshold) && + (origX == v.cursor.x && origY == v.cursor.y) { + if v.doubleClick { + // Triple click + v.lastClickTime = time.Now() + v.tripleClick = true + v.doubleClick = false + messenger.Error("Triple click") + v.cursor.SelectLine() + } else { + // Double click + v.doubleClick = true + v.tripleClick = false + v.lastClickTime = time.Now() + messenger.Error("Double click") + } + } else { + messenger.Error("Single click") + v.doubleClick = false + v.tripleClick = false + v.lastClickTime = time.Now() + + loc := v.cursor.Loc() + v.cursor.selectionStart = loc + v.cursor.selectionEnd = loc + } + } else { + if v.tripleClick { + v.cursor.AddLineToSelection() + } else if v.doubleClick { + + } else { + v.cursor.selectionEnd = v.cursor.Loc() + } } - v.cursor.selectionEnd = loc v.mouseReleased = false + case tcell.ButtonNone: // Mouse event with no click if !v.mouseReleased {