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/elements/core"
// TextBox is a single-line text input.
type TextBox struct {
*core.Core
core core.CoreControl
@ -19,9 +20,14 @@ type TextBox struct {
text []rune
placeholderDrawer 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.Core, element.core = core.NewCore(element)
element.placeholderDrawer.SetFace(theme.FontFaceRegular())
@ -29,7 +35,7 @@ func NewTextBox (placeholder, text string) (element *TextBox) {
element.placeholder = placeholder
element.placeholderDrawer.SetText([]rune(placeholder))
element.updateMinimumSize()
element.SetText(text)
element.SetValue(value)
return
}
@ -52,6 +58,10 @@ func (element *TextBox) HandleKeyDown (
modifiers tomo.Modifiers,
repeated bool,
) {
if element.onKeyDown != nil && element.onKeyDown(key, modifiers, repeated) {
return
}
altered := true
switch {
case key == tomo.KeyBackspace:
@ -60,6 +70,7 @@ func (element *TextBox) HandleKeyDown (
element.text,
element.cursor,
modifiers.Control)
element.runOnChange()
case key == tomo.KeyDelete:
if len(element.text) < 1 { break }
@ -67,6 +78,7 @@ func (element *TextBox) HandleKeyDown (
element.text,
element.cursor,
modifiers.Control)
element.runOnChange()
case key == tomo.KeyLeft:
element.cursor = textmanip.MoveLeft (
@ -85,6 +97,7 @@ func (element *TextBox) HandleKeyDown (
element.text,
element.cursor,
rune(key))
element.runOnChange()
default:
altered = false
@ -168,10 +181,11 @@ func (element *TextBox) updateMinimumSize () {
theme.Padding() * 2)
}
func (element *TextBox) SetText (text string) {
func (element *TextBox) SetValue (text string) {
// if element.text == text { return }
element.text = []rune(text)
element.runOnChange()
element.valueDrawer.SetText(element.text)
if element.cursor > element.valueDrawer.Length() {
element.cursor = element.valueDrawer.Length()
@ -187,6 +201,30 @@ func (element *TextBox) Value () (value string) {
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 () {
bounds := element.core.Bounds()

View File

@ -12,32 +12,45 @@ func main () {
func run () {
window, _ := tomo.NewWindow(2, 2)
window.SetTitle("Approaching")
window.SetTitle("Enter Details")
container := basic.NewContainer(layouts.Vertical { true, true })
window.Adopt(container)
// create inputs
firstName := basic.NewTextBox("First name", "")
lastName := basic.NewTextBox("Last name", "")
fingerLength := basic.NewTextBox("Length of fingers", "")
button := basic.NewButton("Ok")
lastName.SetEnabled(false)
button.SetEnabled(false)
button.OnClick (func () {
// create a dialog displaying the results
popups.NewDialog (
popups.DialogKindInfo,
"Profile",
firstName.Value() + " [REDACTED]'s fingers\n" +
"measure in at " + fingerLength.Value() + " feet.")
firstName.Value() + " " + lastName.Value() +
"'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(firstName, false)
container.Adopt(lastName, false)
container.Adopt(fingerLength, false)
container.Adopt(basic.NewSpacer(true), false)
container.Adopt(button, false)
firstName.Select()
window.OnClose(tomo.Stop)
window.Show()