From 92e4eb970d4af5278839f2a7892af3a11667df73 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 25 Aug 2024 02:47:23 -0400 Subject: [PATCH] Add multi-line text inputs --- textinput.go | 60 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/textinput.go b/textinput.go index 19954d5..4af7851 100644 --- a/textinput.go +++ b/textinput.go @@ -10,27 +10,47 @@ var _ tomo.ContentObject = new(TextInput) // TextInput is a single-line editable text box. type TextInput struct { - box tomo.TextBox - text []rune + box tomo.TextBox + text []rune + multiline bool on struct { valueChange event.FuncBroadcaster confirm event.FuncBroadcaster } } -// NewTextInput creates a new text input containing the specified text. -func NewTextInput (text string) *TextInput { - textInput := &TextInput { box: tomo.NewTextBox() } +func newTextInput (text string, multiline bool) *TextInput { + textInput := &TextInput { + box: tomo.NewTextBox(), + multiline: multiline, + } textInput.box.SetRole(tomo.R("objects", "TextInput")) - textInput.box.SetAttr(tomo.AAlign(tomo.AlignStart, tomo.AlignMiddle)) - textInput.box.SetAttr(tomo.AOverflow(true, false)) + textInput.box.SetTag("multiline", multiline) + if multiline { + textInput.box.SetAttr(tomo.AOverflow(false, true)) + textInput.box.SetAttr(tomo.AAlign(tomo.AlignStart, tomo.AlignStart)) + } else { + textInput.box.SetAttr(tomo.AOverflow(true, false)) + textInput.box.SetAttr(tomo.AAlign(tomo.AlignStart, tomo.AlignMiddle)) + } textInput.SetValue(text) textInput.box.SetFocusable(true) textInput.box.SetSelectable(true) textInput.box.OnKeyDown(textInput.handleKeyDown) textInput.box.OnKeyUp(textInput.handleKeyUp) textInput.box.OnScroll(textInput.handleScroll) - return textInput + return textInput +} + +// NewTextInput creates a new text input containing the specified text. +func NewTextInput (text string) *TextInput { + return newTextInput(text, false) +} + +// NewMultilineTextInput creates a new multiline text input containing the +// specified text. +func NewMultilineTextInput (text string) *TextInput { + return newTextInput(text, true) } // GetBox returns the underlying box. @@ -123,6 +143,19 @@ func (this *TextInput) handleKeyDown (key input.Key, numpad bool) bool { } } () + typ := func () { + this.text, dot = text.Type(this.text, dot, rune(key)) + changed = true + } + + if this.multiline && !modifiers.Control { + switch { + case key == '\n', key == '\t': + typ() + return true + } + } + switch { case isConfirmationKey(key): this.on.confirm.Broadcast() @@ -136,8 +169,7 @@ func (this *TextInput) handleKeyDown (key input.Key, numpad bool) bool { changed = true return true case key.Printable() && !modifiers.Control: - this.text, dot = text.Type(this.text, dot, rune(key)) - changed = true + typ() return true default: return false @@ -146,6 +178,14 @@ func (this *TextInput) handleKeyDown (key input.Key, numpad bool) bool { func (this *TextInput) handleKeyUp (key input.Key, numpad bool) bool { modifiers := this.box.Window().Modifiers() + + if this.multiline && !modifiers.Control { + switch { + case key == '\n', key == '\t': + return true + } + } + switch { case isConfirmationKey(key): return true