From 8c03b516e3d5a6919c0d92abe843873f7d1a0e5a Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Fri, 31 Mar 2023 20:28:53 -0400 Subject: [PATCH] TextBox has double-click to select word --- elements/file/file.go | 3 +-- elements/textbox.go | 45 ++++++++++++++++++++++++++++++++++-------- textmanip/textmanip.go | 8 ++++---- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/elements/file/file.go b/elements/file/file.go index 9c6a743..62e6e4d 100644 --- a/elements/file/file.go +++ b/elements/file/file.go @@ -130,8 +130,7 @@ func (element *File) HandleMouseDown (x, y int, button input.Button) { func (element *File) HandleMouseUp (x, y int, button input.Button) { if button != input.ButtonLeft { return } element.pressed = false - within := image.Point { x, y }. - In(element.Bounds()) + within := image.Point { x, y }.In(element.Bounds()) if time.Since(element.lastClick) < element.config.DoubleClickDelay() { if element.Enabled() && within && element.onChoose != nil { element.onChoose() diff --git a/elements/textbox.go b/elements/textbox.go index fd8c054..1903686 100644 --- a/elements/textbox.go +++ b/elements/textbox.go @@ -1,6 +1,7 @@ package elements import "io" +import "time" import "image" import "git.tebibyte.media/sashakoshka/tomo" import "git.tebibyte.media/sashakoshka/tomo/data" @@ -22,9 +23,10 @@ type TextBox struct { core core.CoreControl focusableControl core.FocusableCoreControl - dragging bool - dot textmanip.Dot - scroll int + lastClick time.Time + dragging int + dot textmanip.Dot + scroll int placeholder string text []rune @@ -81,23 +83,50 @@ func (element *TextBox) HandleMouseDown (x, y int, button input.Button) { if button == input.ButtonLeft { runeIndex := element.atPosition(image.Pt(x, y)) - element.dragging = true - if runeIndex > -1 { + if runeIndex == -1 { return } + + if time.Since(element.lastClick) < element.config.DoubleClickDelay() { + element.dragging = 2 + element.dot = textmanip.WordAround(element.text, runeIndex) + } else { + element.dragging = 1 element.dot = textmanip.EmptyDot(runeIndex) - element.redo() + element.lastClick = time.Now() } + + element.redo() } } func (element *TextBox) HandleMotion (x, y int) { if !element.Enabled() { return } - if element.dragging { + switch element.dragging { + case 1: runeIndex := element.atPosition(image.Pt(x, y)) if runeIndex > -1 { element.dot.End = runeIndex element.redo() } + + case 2: + runeIndex := element.atPosition(image.Pt(x, y)) + if runeIndex > -1 { + if runeIndex < element.dot.Start { + element.dot.End = + runeIndex - + textmanip.WordToLeft ( + element.text, + runeIndex) + } else { + element.dot.End = + runeIndex + + textmanip.WordToRight ( + element.text, + runeIndex) + } + element.redo() + } } } @@ -120,7 +149,7 @@ func (element *TextBox) atPosition (position image.Point) int { func (element *TextBox) HandleMouseUp (x, y int, button input.Button) { if button == input.ButtonLeft { - element.dragging = false + element.dragging = 0 } } diff --git a/textmanip/textmanip.go b/textmanip/textmanip.go index 2fdb462..e057a9e 100644 --- a/textmanip/textmanip.go +++ b/textmanip/textmanip.go @@ -13,7 +13,7 @@ func EmptyDot (position int) Dot { // Canon places the lesser value at the start, and the greater value at the end. // Note that a canonized dot does not in all cases correspond directly to the -// original. +// original, because there is a semantic value to the start and end positions. func (dot Dot) Canon () Dot { if dot.Start > dot.End { return Dot { dot.End, dot.Start } @@ -35,7 +35,7 @@ func (dot Dot) Add (delta int) Dot { } } -// Add shifts the dot to the left by the specified amount. +// Sub shifts the dot to the left by the specified amount. func (dot Dot) Sub (delta int) Dot { return Dot { dot.Start - delta, @@ -103,8 +103,8 @@ func WordToRight (text []rune, position int) (length int) { // WordAround returns a dot that surrounds the word at the specified position. func WordAround (text []rune, position int) (around Dot) { return Dot { - WordToLeft(text, position), - WordToRight(text, position), + position - WordToLeft(text, position), + position + WordToRight(text, position), } }