-
-
Notifications
You must be signed in to change notification settings - Fork 119
Patterns
This page describes some of the patterns that have been emerging in the projects that are using tui-go.
By embedding an existing widget, you can make it implement other interfaces, like the io.Writer in this example.
type labelWriter struct {
buf bytes.Buffer
ui tui.UI
tui.Label
}
func (w *labelWriter) OnKeyEvent(ev tui.KeyEvent) {
if ev.Key == tui.KeyCtrlL {
w.buf.Reset()
w.Label.SetText("")
go w.ui.Update(func() {})
}
}
func (w *labelWriter) Write(p []byte) (n int, err error) {
n, err = w.buf.Write(p)
w.Label.SetText(w.buf.String())
go w.ui.Update(func() {})
return
}
func main() {
root := tui.NewVBox()
ui := tui.New(root)
ui.SetKeybinding("Esc", func() { ui.Quit() })
w := &labelWriter{ui: ui}
root.Append(w)
fmt.Fprintln(w, "hej")
if err := ui.Run(); err != nil {
panic(err)
}
}Views allow you to group multiple related widgets together.
type scorecardView struct {
player *tui.Label
score *tui.Label
*tui.Box
}
func newScorecardView(name string) *scorecardView {
v := &scorecardView{
player: tui.NewLabel(name),
score: tui.NewLabel("0"),
}
v.Box = tui.NewHBox(
v.player,
v.score,
)
return v
}
func (v *scorecardView) updateScore(s int) {
v.score.SetText(fmt.Sprintf("%d", s))
}
func main() {
var (
playerName = "highlander56"
score = 0
)
v := newScorecardView(playerName)
ui := tui.New(v)
ui.SetKeybinding("Esc", func() { ui.Quit() })
ui.SetKeybinding("Ctrl+A", func() {
score++
v.updateScore(score)
go ui.Update(func() {})
})
if err := ui.Run(); err != nil {
panic(err)
}
}If none of the provided widgets suits your use case, you can implement you own by implementing the Widget interface. The easiest way is to embed WidgetBase that provides default functionality for you widget.
For most purposes, you'll only have to implement the Draw and SizeHint methods for your custom widget. In the Draw method, you have access to the Painter which lets you draw lines, text or runes within your widget. You'll also implement SizeHint that will return the preferred size of your widget.
type customWidget struct {
text string
tui.WidgetBase
}
func (w *customWidget) Draw(p *tui.Painter) {
p.DrawText(0, 0, w.text)
}
func (w *customWidget) SizeHint() image.Point {
return image.Pt(len(w.text), 1)
}