Text boxes now scroll to their cursor position
This commit is contained in:
parent
873336e029
commit
89881247d0
@ -16,12 +16,15 @@ 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)
|
|
||||||
onChange func ()
|
onKeyDown func (tomo.Key, tomo.Modifiers, bool) (bool)
|
||||||
|
onChange func ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTextBox creates a new text box with the specified placeholder text, and
|
// NewTextBox creates a new text box with the specified placeholder text, and
|
||||||
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +66,8 @@ func (element *TextBox) HandleKeyDown (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
Reference in New Issue
Block a user