Added event callbacks to text box

This commit is contained in:
Sasha Koshka 2023-01-18 11:56:14 -05:00
parent 48db645f9f
commit 36c5ed40e9
2 changed files with 61 additions and 10 deletions

View File

@ -7,6 +7,7 @@ import "git.tebibyte.media/sashakoshka/tomo/artist"
import "git.tebibyte.media/sashakoshka/tomo/textmanip" import "git.tebibyte.media/sashakoshka/tomo/textmanip"
import "git.tebibyte.media/sashakoshka/tomo/elements/core" import "git.tebibyte.media/sashakoshka/tomo/elements/core"
// TextBox is a single-line text input.
type TextBox struct { type TextBox struct {
*core.Core *core.Core
core core.CoreControl core core.CoreControl
@ -19,9 +20,14 @@ type TextBox struct {
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 ()
} }
func NewTextBox (placeholder, text string) (element *TextBox) { // NewTextBox creates a new text box with the specified placeholder text, and
// a value. When the value is empty, the placeholder will be displayed in gray
// text.
func NewTextBox (placeholder, value string) (element *TextBox) {
element = &TextBox { enabled: true } element = &TextBox { enabled: true }
element.Core, element.core = core.NewCore(element) element.Core, element.core = core.NewCore(element)
element.placeholderDrawer.SetFace(theme.FontFaceRegular()) element.placeholderDrawer.SetFace(theme.FontFaceRegular())
@ -29,7 +35,7 @@ func NewTextBox (placeholder, text string) (element *TextBox) {
element.placeholder = placeholder element.placeholder = placeholder
element.placeholderDrawer.SetText([]rune(placeholder)) element.placeholderDrawer.SetText([]rune(placeholder))
element.updateMinimumSize() element.updateMinimumSize()
element.SetText(text) element.SetValue(value)
return return
} }
@ -52,6 +58,10 @@ func (element *TextBox) HandleKeyDown (
modifiers tomo.Modifiers, modifiers tomo.Modifiers,
repeated bool, repeated bool,
) { ) {
if element.onKeyDown != nil && element.onKeyDown(key, modifiers, repeated) {
return
}
altered := true altered := true
switch { switch {
case key == tomo.KeyBackspace: case key == tomo.KeyBackspace:
@ -60,6 +70,7 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
modifiers.Control) modifiers.Control)
element.runOnChange()
case key == tomo.KeyDelete: case key == tomo.KeyDelete:
if len(element.text) < 1 { break } if len(element.text) < 1 { break }
@ -67,6 +78,7 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
modifiers.Control) modifiers.Control)
element.runOnChange()
case key == tomo.KeyLeft: case key == tomo.KeyLeft:
element.cursor = textmanip.MoveLeft ( element.cursor = textmanip.MoveLeft (
@ -85,6 +97,7 @@ func (element *TextBox) HandleKeyDown (
element.text, element.text,
element.cursor, element.cursor,
rune(key)) rune(key))
element.runOnChange()
default: default:
altered = false altered = false
@ -168,10 +181,11 @@ func (element *TextBox) updateMinimumSize () {
theme.Padding() * 2) theme.Padding() * 2)
} }
func (element *TextBox) SetText (text string) { func (element *TextBox) SetValue (text string) {
// if element.text == text { return } // if element.text == text { return }
element.text = []rune(text) element.text = []rune(text)
element.runOnChange()
element.valueDrawer.SetText(element.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()
@ -187,6 +201,30 @@ func (element *TextBox) Value () (value string) {
return string(element.text) return string(element.text)
} }
func (element *TextBox) Filled () (filled bool) {
return len(element.text) > 0
}
func (element *TextBox) OnKeyDown (
callback func (
key tomo.Key, modifiers tomo.Modifiers, repeated bool,
) (
handled bool,
),
) {
element.onKeyDown = callback
}
func (element *TextBox) OnChange (callback func ()) {
element.onChange = callback
}
func (element *TextBox) runOnChange () {
if element.onChange != nil {
element.onChange()
}
}
func (element *TextBox) draw () { func (element *TextBox) draw () {
bounds := element.core.Bounds() bounds := element.core.Bounds()

View File

@ -12,24 +12,39 @@ func main () {
func run () { func run () {
window, _ := tomo.NewWindow(2, 2) window, _ := tomo.NewWindow(2, 2)
window.SetTitle("Approaching") window.SetTitle("Enter Details")
container := basic.NewContainer(layouts.Vertical { true, true }) container := basic.NewContainer(layouts.Vertical { true, true })
window.Adopt(container) window.Adopt(container)
// create inputs
firstName := basic.NewTextBox("First name", "") firstName := basic.NewTextBox("First name", "")
lastName := basic.NewTextBox("Last name", "") lastName := basic.NewTextBox("Last name", "")
fingerLength := basic.NewTextBox("Length of fingers", "") fingerLength := basic.NewTextBox("Length of fingers", "")
button := basic.NewButton("Ok") button := basic.NewButton("Ok")
lastName.SetEnabled(false) button.SetEnabled(false)
button.OnClick (func () { button.OnClick (func () {
// create a dialog displaying the results
popups.NewDialog ( popups.NewDialog (
popups.DialogKindInfo, popups.DialogKindInfo,
"Profile", "Profile",
firstName.Value() + " [REDACTED]'s fingers\n" + firstName.Value() + " " + lastName.Value() +
"measure in at " + fingerLength.Value() + " feet.") "'s fingers\nmeasure in at " + fingerLength.Value() +
" feet.")
}) })
// enable the Ok button if all three inputs have text in them
check := func () {
button.SetEnabled (
firstName.Filled() &&
lastName.Filled() &&
fingerLength.Filled())
}
firstName.OnChange(check)
lastName.OnChange(check)
fingerLength.OnChange(check)
// add elements to container
container.Adopt(basic.NewLabel("Choose your words carefully.", false), true) container.Adopt(basic.NewLabel("Choose your words carefully.", false), true)
container.Adopt(firstName, false) container.Adopt(firstName, false)
container.Adopt(lastName, false) container.Adopt(lastName, false)
@ -37,8 +52,6 @@ func run () {
container.Adopt(basic.NewSpacer(true), false) container.Adopt(basic.NewSpacer(true), false)
container.Adopt(button, false) container.Adopt(button, false)
firstName.Select()
window.OnClose(tomo.Stop) window.OnClose(tomo.Stop)
window.Show() window.Show()
} }