Text boxes now scroll to their cursor position

This commit is contained in:
Sasha Koshka 2023-01-18 15:56:36 -05:00
parent 873336e029
commit 89881247d0

View File

@ -16,10 +16,13 @@ type TextBox struct {
selected bool selected bool
cursor int cursor int
scroll int
placeholder string placeholder string
text []rune text []rune
placeholderDrawer artist.TextDrawer placeholderDrawer artist.TextDrawer
valueDrawer artist.TextDrawer valueDrawer artist.TextDrawer
onKeyDown func (tomo.Key, tomo.Modifiers, bool) (bool) onKeyDown func (tomo.Key, tomo.Modifiers, bool) (bool)
onChange func () onChange func ()
} }
@ -41,6 +44,7 @@ func NewTextBox (placeholder, value string) (element *TextBox) {
func (element *TextBox) Resize (width, height int) { func (element *TextBox) Resize (width, height int) {
element.core.AllocateCanvas(width, height) element.core.AllocateCanvas(width, height)
element.scrollToCursor()
element.draw() element.draw()
} }
@ -63,6 +67,7 @@ func (element *TextBox) HandleKeyDown (
} }
altered := true altered := true
textChanged := false
switch { switch {
case key == tomo.KeyBackspace: case key == tomo.KeyBackspace:
if len(element.text) < 1 { break } if len(element.text) < 1 { break }
@ -70,7 +75,7 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
modifiers.Control) modifiers.Control)
element.runOnChange() textChanged = true
case key == tomo.KeyDelete: case key == tomo.KeyDelete:
if len(element.text) < 1 { break } if len(element.text) < 1 { break }
@ -78,7 +83,7 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
modifiers.Control) modifiers.Control)
element.runOnChange() textChanged = true
case key == tomo.KeyLeft: case key == tomo.KeyLeft:
element.cursor = textmanip.MoveLeft ( element.cursor = textmanip.MoveLeft (
@ -97,16 +102,21 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
rune(key)) rune(key))
element.runOnChange() textChanged = true
default: default:
altered = false altered = false
} }
if altered { if textChanged {
element.runOnChange()
element.valueDrawer.SetText(element.text) element.valueDrawer.SetText(element.text)
} }
if altered {
element.scrollToCursor()
}
if altered && element.core.HasImage () { if altered && element.core.HasImage () {
element.draw() element.draw()
element.core.PushAll() element.core.PushAll()
@ -190,6 +200,7 @@ func (element *TextBox) SetValue (text string) {
if element.cursor > element.valueDrawer.Length() { if element.cursor > element.valueDrawer.Length() {
element.cursor = element.valueDrawer.Length() element.cursor = element.valueDrawer.Length()
} }
element.scrollToCursor()
if element.core.HasImage () { if element.core.HasImage () {
element.draw() element.draw()
@ -225,6 +236,23 @@ func (element *TextBox) runOnChange () {
} }
} }
func (element *TextBox) scrollToCursor () {
if !element.core.HasImage() { return }
bounds := element.core.Bounds().Inset(theme.Padding())
bounds.Max.X -= element.valueDrawer.Em().Round()
cursorPosition := element.valueDrawer.PositionOf(element.cursor)
cursorPosition.X -= element.scroll
maxX := bounds.Max.X
minX := bounds.Min.X + bounds.Dx() / 2
if cursorPosition.X > maxX {
element.scroll += cursorPosition.X - maxX
} else if cursorPosition.X < minX {
element.scroll -= minX - cursorPosition.X
if element.scroll < 0 { element.scroll = 0 }
}
}
func (element *TextBox) draw () { func (element *TextBox) draw () {
bounds := element.core.Bounds() bounds := element.core.Bounds()
@ -235,12 +263,6 @@ func (element *TextBox) draw () {
element.Selected()), element.Selected()),
bounds) bounds)
innerBounds := bounds
innerBounds.Min.X += theme.Padding()
innerBounds.Min.Y += theme.Padding()
innerBounds.Max.X -= theme.Padding()
innerBounds.Max.Y -= theme.Padding()
if len(element.text) == 0 && !element.selected { if len(element.text) == 0 && !element.selected {
// draw placeholder // draw placeholder
textBounds := element.placeholderDrawer.LayoutBounds() textBounds := element.placeholderDrawer.LayoutBounds()
@ -257,7 +279,7 @@ func (element *TextBox) draw () {
// draw input value // draw input value
textBounds := element.valueDrawer.LayoutBounds() textBounds := element.valueDrawer.LayoutBounds()
offset := image.Point { offset := image.Point {
X: theme.Padding(), X: theme.Padding() - element.scroll,
Y: theme.Padding(), Y: theme.Padding(),
} }
foreground := theme.ForegroundPattern(element.enabled) foreground := theme.ForegroundPattern(element.enabled)