commit c48904b98a6cd8c95fe3834ba853226ed52b3779 Author: Tordarus Date: Sun Jan 10 21:52:29 2021 +0100 initial commit diff --git a/draw_buffer.go b/draw_buffer.go new file mode 100644 index 0000000..adb890c --- /dev/null +++ b/draw_buffer.go @@ -0,0 +1,13 @@ +package tui + +import ( + "git.tordarus.net/tordarus/buf2d" + "github.com/gdamore/tcell" +) + +func drawBuffer(scr tcell.Screen, buf *buf2d.Buffer) { + buf.Draw(func(x, y int, cn rune) { + scr.SetContent(x, y, cn, nil, tcell.StyleDefault) + }) + scr.Show() +} diff --git a/events.go b/events.go new file mode 100644 index 0000000..38588f3 --- /dev/null +++ b/events.go @@ -0,0 +1,7 @@ +package tui + +import "github.com/gdamore/tcell" + +type Events interface { + OnKeyPressed(key tcell.Key) +} diff --git a/screen.go b/screen.go new file mode 100644 index 0000000..d4f68a2 --- /dev/null +++ b/screen.go @@ -0,0 +1,73 @@ +package tui + +import ( + "errors" + "fmt" + + "git.tordarus.net/tordarus/buf2d" + "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() { + s.Root.OnKeyPressed(event.Key()) + 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 + } + 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() + buf := buf2d.NewBuffer(w, h) + s.Root.Draw(buf) + drawBuffer(s.scr, buf) +} diff --git a/tests/screen_test.go b/tests/screen_test.go new file mode 100644 index 0000000..aa1b092 --- /dev/null +++ b/tests/screen_test.go @@ -0,0 +1,27 @@ +package tui + +import ( + "errors" + "fmt" + "testing" + "tui" + "tui/views" + + "github.com/gdamore/tcell" +) + +func TestScreen(t *testing.T) { + eventView := views.NewEventView() + screen, err := tui.NewScreen(eventView) + if err != nil { + t.Error(err) + return + } + + eventView.KeyPressed = func(key tcell.Key) { + screen.StopWithError(errors.New(fmt.Sprintf("%#v", key))) + } + + err = screen.Start() + fmt.Println(err) +} diff --git a/view.go b/view.go new file mode 100644 index 0000000..fb14a68 --- /dev/null +++ b/view.go @@ -0,0 +1,18 @@ +package tui + +import ( + "git.tordarus.net/tordarus/buf2d" + "github.com/gdamore/tcell" +) + +type View interface { + Events + + SetForeground(color tcell.Color) + Foreground() tcell.Color + + SetBackground(color tcell.Color) + Background() tcell.Color + + Draw(*buf2d.Buffer) +} diff --git a/viewgroup.go b/viewgroup.go new file mode 100644 index 0000000..6637a12 --- /dev/null +++ b/viewgroup.go @@ -0,0 +1,6 @@ +package tui + +type ViewGroup interface { + View + Children() []*View +} diff --git a/views/eventview.go b/views/eventview.go new file mode 100644 index 0000000..aa95bad --- /dev/null +++ b/views/eventview.go @@ -0,0 +1,22 @@ +package views + +import ( + "tui" + + "github.com/gdamore/tcell" +) + +type EventView struct { + tui.ViewTmpl + KeyPressed func(key tcell.Key) +} + +func (v *EventView) OnKeyPressed(key tcell.Key) { + if v.KeyPressed != nil { + v.KeyPressed(key) + } +} + +func NewEventView() *EventView { + return &EventView{} +} diff --git a/views/textview.go b/views/textview.go new file mode 100644 index 0000000..2af50f4 --- /dev/null +++ b/views/textview.go @@ -0,0 +1,24 @@ +package views + +import ( + "tui" + + "git.tordarus.net/tordarus/buf2d" +) + +type TextView struct { + tui.ViewTmpl + Text string +} + +var _ tui.View = &TextView{} + +func (v *TextView) Draw(buf *buf2d.Buffer) { + buf.WriteMultiLineString(v.Text, 0, 0) +} + +func NewTextView(text string) *TextView { + return &TextView{ + Text: text, + } +} diff --git a/viewtmpl.go b/viewtmpl.go new file mode 100644 index 0000000..878b835 --- /dev/null +++ b/viewtmpl.go @@ -0,0 +1,45 @@ +package tui + +import ( + "git.tordarus.net/tordarus/buf2d" + "github.com/gdamore/tcell" +) + +type ViewTmpl struct { + view View + + foreground tcell.Color + background tcell.Color +} + +var _ View = &ViewTmpl{} + +func NewViewTmpl(v View) *ViewTmpl { + return &ViewTmpl{ + view: v, + } +} + +func (v *ViewTmpl) Draw(buf *buf2d.Buffer) { + buf.Fill(' ') +} + +func (v *ViewTmpl) OnKeyPressed(key tcell.Key) { + +} + +func (v *ViewTmpl) Foreground() tcell.Color { + return v.foreground +} + +func (v *ViewTmpl) SetForeground(color tcell.Color) { + v.foreground = color +} + +func (v *ViewTmpl) Background() tcell.Color { + return v.background +} + +func (v *ViewTmpl) SetBackground(color tcell.Color) { + v.background = color +}