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,32 +12,45 @@ 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)
container.Adopt(fingerLength, false) container.Adopt(fingerLength, false)
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()