2021-01-10 21:52:29 +01:00
|
|
|
package tui
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
2022-04-01 20:10:51 +02:00
|
|
|
"git.tordarus.net/Tordarus/buf2d"
|
2021-01-10 21:52:29 +01:00
|
|
|
"github.com/gdamore/tcell"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Screen struct {
|
|
|
|
scr tcell.Screen
|
|
|
|
stopCh chan error
|
|
|
|
Root View
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewScreen(root View) (*Screen, error) {
|
|
|
|
scr, err := tcell.NewScreen()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
s := &Screen{
|
|
|
|
Root: root,
|
|
|
|
scr: scr,
|
|
|
|
stopCh: make(chan error, 1),
|
|
|
|
}
|
|
|
|
|
|
|
|
go s.eventloop()
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Screen) eventloop() {
|
|
|
|
for evt := s.scr.PollEvent(); evt != nil; evt = s.scr.PollEvent() {
|
|
|
|
switch event := evt.(type) {
|
|
|
|
case *tcell.EventResize:
|
|
|
|
go s.Redraw()
|
|
|
|
case *tcell.EventKey:
|
|
|
|
go func() {
|
2022-04-01 20:10:51 +02:00
|
|
|
s.Root.OnKeyPressed(event)
|
2021-01-10 21:52:29 +01:00
|
|
|
s.Redraw()
|
|
|
|
}()
|
|
|
|
default:
|
|
|
|
s.StopWithError(errors.New(fmt.Sprintf("%#v", event)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s.StopWithError(errors.New("unknown error occured"))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Screen) Start() error {
|
|
|
|
err := s.scr.Init()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-04-01 20:10:51 +02:00
|
|
|
defer s.scr.Fini()
|
|
|
|
|
2021-01-10 21:52:29 +01:00
|
|
|
s.Redraw()
|
|
|
|
return <-s.stopCh
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Screen) Stop() {
|
|
|
|
s.StopWithError(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Screen) StopWithError(err error) {
|
|
|
|
s.stopCh <- err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Screen) Redraw() {
|
|
|
|
w, h := s.scr.Size()
|
2022-04-01 20:10:51 +02:00
|
|
|
buf := buf2d.NewBuffer(w, h, DefaultRune)
|
2021-01-10 21:52:29 +01:00
|
|
|
s.Root.Draw(buf)
|
|
|
|
drawBuffer(s.scr, buf)
|
|
|
|
}
|