-
-
Notifications
You must be signed in to change notification settings - Fork 124
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)
}