More intelligent text editing with new textmanip system
This commit is contained in:
parent
b03cba57e1
commit
2bf2baf69e
@ -4,6 +4,7 @@ import "image"
|
|||||||
import "git.tebibyte.media/sashakoshka/tomo"
|
import "git.tebibyte.media/sashakoshka/tomo"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
import "git.tebibyte.media/sashakoshka/tomo/artist"
|
||||||
|
import "git.tebibyte.media/sashakoshka/tomo/textmanip"
|
||||||
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
import "git.tebibyte.media/sashakoshka/tomo/elements/core"
|
||||||
|
|
||||||
type TextBox struct {
|
type TextBox struct {
|
||||||
@ -15,7 +16,7 @@ type TextBox struct {
|
|||||||
|
|
||||||
cursor int
|
cursor int
|
||||||
placeholder string
|
placeholder string
|
||||||
text string
|
text []rune
|
||||||
placeholderDrawer artist.TextDrawer
|
placeholderDrawer artist.TextDrawer
|
||||||
valueDrawer artist.TextDrawer
|
valueDrawer artist.TextDrawer
|
||||||
}
|
}
|
||||||
@ -50,14 +51,51 @@ func (element *TextBox) HandleKeyDown (
|
|||||||
modifiers tomo.Modifiers,
|
modifiers tomo.Modifiers,
|
||||||
repeated bool,
|
repeated bool,
|
||||||
) {
|
) {
|
||||||
|
altered := true
|
||||||
switch {
|
switch {
|
||||||
case key == tomo.KeyBackspace:
|
case key == tomo.KeyBackspace:
|
||||||
if len(element.text) < 1 { break }
|
if len(element.text) < 1 { break }
|
||||||
element.cursor --
|
element.text, element.cursor = textmanip.Backspace (
|
||||||
element.SetText(element.text[:len(element.text) - 1])
|
element.text,
|
||||||
|
element.cursor,
|
||||||
|
modifiers.Control)
|
||||||
|
|
||||||
|
case key == tomo.KeyDelete:
|
||||||
|
if len(element.text) < 1 { break }
|
||||||
|
element.text, element.cursor = textmanip.Delete (
|
||||||
|
element.text,
|
||||||
|
element.cursor,
|
||||||
|
modifiers.Control)
|
||||||
|
|
||||||
|
case key == tomo.KeyLeft:
|
||||||
|
element.cursor = textmanip.MoveLeft (
|
||||||
|
element.text,
|
||||||
|
element.cursor,
|
||||||
|
modifiers.Control)
|
||||||
|
|
||||||
|
case key == tomo.KeyRight:
|
||||||
|
element.cursor = textmanip.MoveRight (
|
||||||
|
element.text,
|
||||||
|
element.cursor,
|
||||||
|
modifiers.Control)
|
||||||
|
|
||||||
case key.Printable():
|
case key.Printable():
|
||||||
element.cursor ++
|
element.text, element.cursor = textmanip.Type (
|
||||||
element.SetText(element.text + string(rune(key)))
|
element.text,
|
||||||
|
element.cursor,
|
||||||
|
rune(key))
|
||||||
|
|
||||||
|
default:
|
||||||
|
altered = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if altered {
|
||||||
|
element.valueDrawer.SetText(element.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
if altered && element.core.HasImage () {
|
||||||
|
element.draw()
|
||||||
|
element.core.PushAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,10 +168,10 @@ func (element *TextBox) updateMinimumSize () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (element *TextBox) SetText (text string) {
|
func (element *TextBox) SetText (text string) {
|
||||||
if element.text == text { return }
|
// if element.text == text { return }
|
||||||
|
|
||||||
element.text = text
|
element.text = []rune(text)
|
||||||
element.valueDrawer.SetText([]rune(text))
|
element.valueDrawer.SetText(element.text)
|
||||||
if element.cursor > element.valueDrawer.Length() {
|
if element.cursor > element.valueDrawer.Length() {
|
||||||
element.cursor = element.valueDrawer.Length()
|
element.cursor = element.valueDrawer.Length()
|
||||||
}
|
}
|
||||||
@ -160,7 +198,7 @@ func (element *TextBox) draw () {
|
|||||||
innerBounds.Max.X -= theme.Padding()
|
innerBounds.Max.X -= theme.Padding()
|
||||||
innerBounds.Max.Y -= theme.Padding()
|
innerBounds.Max.Y -= theme.Padding()
|
||||||
|
|
||||||
if element.text == "" && !element.selected {
|
if element.text == nil && !element.selected {
|
||||||
// draw placeholder
|
// draw placeholder
|
||||||
textBounds := element.placeholderDrawer.LayoutBounds()
|
textBounds := element.placeholderDrawer.LayoutBounds()
|
||||||
offset := image.Point {
|
offset := image.Point {
|
||||||
|
99
textmanip/textmanip.go
Normal file
99
textmanip/textmanip.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package textmanip
|
||||||
|
|
||||||
|
import "unicode"
|
||||||
|
|
||||||
|
func WordToLeft (text []rune, cursor int) (length int) {
|
||||||
|
if cursor < 1 { return }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
index := cursor - 1
|
||||||
|
for index >= 0 && unicode.IsSpace(text[index]) {
|
||||||
|
length ++
|
||||||
|
index --
|
||||||
|
}
|
||||||
|
for index >= 0 && !unicode.IsSpace(text[index]) {
|
||||||
|
length ++
|
||||||
|
index --
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func WordToRight (text []rune, cursor int) (length int) {
|
||||||
|
if cursor < 0 { return }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
index := cursor
|
||||||
|
for index < len(text) && unicode.IsSpace(text[index]) {
|
||||||
|
length ++
|
||||||
|
index ++
|
||||||
|
}
|
||||||
|
for index < len(text) && !unicode.IsSpace(text[index]) {
|
||||||
|
length ++
|
||||||
|
index ++
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Backspace (text []rune, cursor int, word bool) (result []rune, moved int) {
|
||||||
|
if cursor < 1 { return text, cursor }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
moved = 1
|
||||||
|
if word {
|
||||||
|
moved = WordToLeft(text, cursor)
|
||||||
|
}
|
||||||
|
result = append(result, text[:cursor - moved]...)
|
||||||
|
result = append(result, text[cursor:]...)
|
||||||
|
moved = cursor - moved
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Delete (text []rune, cursor int, word bool) (result []rune, moved int) {
|
||||||
|
if cursor < 0 { return text, cursor }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
moved = 1
|
||||||
|
if word {
|
||||||
|
moved = WordToRight(text, cursor)
|
||||||
|
}
|
||||||
|
result = append(result, text[:cursor]...)
|
||||||
|
result = append(result, text[cursor + moved:]...)
|
||||||
|
moved = cursor
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Type (text []rune, cursor int, character rune) (result []rune, moved int) {
|
||||||
|
if cursor < 0 { cursor = 0 }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
result = append(result, text[:cursor]...)
|
||||||
|
result = append(result, character)
|
||||||
|
if cursor < len(text) {
|
||||||
|
result = append(result, text[cursor:]...)
|
||||||
|
}
|
||||||
|
moved = cursor + 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func MoveLeft (text []rune, cursor int, word bool) (moved int) {
|
||||||
|
if cursor < 1 { return cursor }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
moved = 1
|
||||||
|
if word {
|
||||||
|
moved = WordToLeft(text, cursor)
|
||||||
|
}
|
||||||
|
moved = cursor - moved
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func MoveRight (text []rune, cursor int, word bool) (moved int) {
|
||||||
|
if cursor < 0 { return cursor }
|
||||||
|
if cursor > len(text) { cursor = len(text) }
|
||||||
|
|
||||||
|
moved = 1
|
||||||
|
if word {
|
||||||
|
moved = WordToRight(text, cursor)
|
||||||
|
}
|
||||||
|
moved = cursor + moved
|
||||||
|
return
|
||||||
|
}
|
Reference in New Issue
Block a user