func (tb *TextBox) SetTextChanged(callback TextChangeCallback) {
	tb.textChangeCallback = callback
}
SetTextChanged sets the text change callback.
package components
import (
	"sync"
	"github.com/BigJk/ramen/console"
	"github.com/BigJk/ramen/consolecolor"
	"github.com/BigJk/ramen/t"
	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/inpututil"
)
type TextChangeCallback func(text string)
type EnterCallback func()
type TextBox struct {
	*console.ComponentBase
	mtx  sync.RWMutex
	text string
	textChangeCallback TextChangeCallback
	enterCallback      EnterCallback
	background        consolecolor.Color
	backgroundHover   consolecolor.Color
	backgroundClicked consolecolor.Color
	foreground         consolecolor.Color
	foregroundInactive consolecolor.Color
	blink float64
	state ComponentState
}
func NewTextbox(x, y, width, height int) *TextBox {
	tb := TextBox{
		ComponentBase:      console.NewComponentBase(x, y, width, height),
		background:         colorBg,
		backgroundHover:    colorBgHover,
		backgroundClicked:  colorBgClicked,
		foreground:         colorFg,
		foregroundInactive: colorFgInactive,
	}
	return &tb
}
func (tb *TextBox) FocusOnClick() bool {
	return true
}
func (tb *TextBox) Update(con *console.Console, timeElapsed float64) bool {
	tb.state = CalculateComponentState(con, tb.X, tb.Y, tb.Width, tb.Height)
	if !tb.IsFocused() {
		return true
	}
	textChanged := false
	tb.mtx.Lock()
	if len(ebiten.InputChars()) > 0 {
		textChanged = true
	}
	tb.text += string(ebiten.InputChars())
	if tb.repeatingKeyPressed(ebiten.KeyBackspace) {
		if len(tb.text) >= 1 {
			tb.text = tb.text[:len(tb.text)-1]
			textChanged = true
		}
	}
	if textChanged && tb.textChangeCallback != nil {
		tb.textChangeCallback(tb.text)
	}
	tb.mtx.Unlock()
	if tb.enterCallback != nil && inpututil.IsKeyJustPressed(ebiten.KeyEnter) {
		tb.enterCallback()
	}
	return true
}
func (tb *TextBox) Draw(con *console.Console, timeElapsed float64) {
	tb.blink += timeElapsed
	tb.mtx.RLock()
	text := tb.text
	tb.mtx.RUnlock()
	var bgColor consolecolor.Color
	var fColor consolecolor.Color
	switch tb.state {
	case ComponentIdle:
		bgColor = tb.background
		if tb.IsFocused() {
			fColor = tb.foreground
		} else {
			fColor = tb.foregroundInactive
		}
	case ComponentHovered:
		bgColor = tb.backgroundHover
		fColor = tb.foreground
	case ComponentClicked:
		bgColor = tb.backgroundClicked
		fColor = tb.foreground
	}
	if tb.IsFocused() {
		bgColor = tb.backgroundHover
		fColor = tb.foreground
	}
	con.Clear(tb.X, tb.Y, tb.Width, tb.Height, t.Background(bgColor))
	if tb.blink < 0.5 && tb.IsFocused() {
		text += "_"
	} else {
		text += " "
	}
	if tb.Height == 1 && len(text) >= tb.Width {
		text = text[len(text)-tb.Width:]
	}
	con.Print(tb.X, tb.Y, text, t.Foreground(fColor))
	if tb.blink > 1 {
		tb.blink = 0
	}
}