summary refs log tree commit diff stats
path: root/ui
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-01-10 22:41:15 -0500
committerDrew DeVault <sir@cmpwn.com>2018-01-10 22:41:15 -0500
commit77a0f68758905faa74407499ff92c90929e27989 (patch)
tree44edc8d2de572deff60330f609aecab56aa4dea7 /ui
parentdb1b2cd53f5dc7bfbfb6ee54ad0bb0882ea2cc03 (diff)
downloadaerc-77a0f68758905faa74407499ff92c90929e27989.tar.gz
Make termbox event loop async
Diffstat (limited to 'ui')
-rw-r--r--ui/account.go41
-rw-r--r--ui/helpers.go21
-rw-r--r--ui/render.go53
-rw-r--r--ui/types.go18
4 files changed, 120 insertions, 13 deletions
diff --git a/ui/account.go b/ui/account.go
new file mode 100644
index 0000000..0949e52
--- /dev/null
+++ b/ui/account.go
@@ -0,0 +1,41 @@
+package ui
+
+import (
+	tb "github.com/nsf/termbox-go"
+
+	"git.sr.ht/~sircmpwn/aerc2/config"
+	"git.sr.ht/~sircmpwn/aerc2/worker"
+)
+
+type AccountTab struct {
+	Config *config.AccountConfig
+	Worker *worker.Worker
+	Parent *UIState
+}
+
+func NewAccountTab(conf *config.AccountConfig, work *worker.Worker) *AccountTab {
+	return &AccountTab{
+		Config: conf,
+		Worker: work,
+	}
+}
+
+func (acc *AccountTab) Name() string {
+	return acc.Config.Name
+}
+
+func (acc *AccountTab) Invalid() bool {
+	return false
+}
+
+func (acc *AccountTab) SetParent(parent *UIState) {
+	acc.Parent = parent
+}
+
+func (acc *AccountTab) Render(at Geometry) {
+	cell := tb.Cell{
+		Fg: tb.ColorDefault,
+		Bg: tb.ColorDefault,
+	}
+	TPrintf(&at, cell, "%s", acc.Name())
+}
diff --git a/ui/helpers.go b/ui/helpers.go
new file mode 100644
index 0000000..0b8789e
--- /dev/null
+++ b/ui/helpers.go
@@ -0,0 +1,21 @@
+package ui
+
+import (
+	"fmt"
+
+	tb "github.com/nsf/termbox-go"
+)
+
+func TPrintf(geo *Geometry, ref tb.Cell, format string, a ...interface{}) {
+	str := fmt.Sprintf(format, a...)
+	_geo := *geo
+	for _, ch := range str {
+		tb.SetCell(geo.Col, geo.Row, ch, ref.Fg, ref.Bg)
+		geo.Col++
+		if geo.Col == _geo.Col+geo.Width {
+			// TODO: Abort when out of room?
+			geo.Col = _geo.Col
+			geo.Row++
+		}
+	}
+}
diff --git a/ui/render.go b/ui/render.go
index bca0cf6..4fedc2c 100644
--- a/ui/render.go
+++ b/ui/render.go
@@ -8,15 +8,21 @@ import (
 
 func Initialize(conf *config.AercConfig) (*UIState, error) {
 	state := UIState{
+		Config:       conf,
 		InvalidPanes: InvalidateAll,
-		Tabs:         make([]AercTab, len(conf.Accounts)),
+
+		tbEvents: make(chan tb.Event, 10),
 	}
-	// TODO: Initialize each tab to a mailbox tab
 	if err := tb.Init(); err != nil {
 		return nil, err
 	}
 	tb.SetInputMode(tb.InputEsc | tb.InputMouse)
 	tb.SetOutputMode(tb.Output256)
+	go (func() {
+		for !state.Exit {
+			state.tbEvents <- tb.PollEvent()
+		}
+	})()
 	return &state, nil
 }
 
@@ -24,21 +30,50 @@ func (state *UIState) Close() {
 	tb.Close()
 }
 
+func (state *UIState) AddTab(tab AercTab) {
+	state.Tabs = append(state.Tabs, tab)
+}
+
 func (state *UIState) Invalidate(what uint) {
 	state.InvalidPanes |= what
 }
 
+func (state *UIState) calcGeometries() {
+	width, height := tb.Size()
+	// TODO: more
+	state.Panes.TabView = Geometry{
+		Row:    0,
+		Col:    0,
+		Width:  width,
+		Height: height,
+	}
+}
+
 func (state *UIState) Tick() bool {
-	switch e := tb.PollEvent(); e.Type {
-	case tb.EventKey:
-		if e.Key == tb.KeyEsc {
-			state.Exit = true
+	select {
+	case event := <-state.tbEvents:
+		switch event.Type {
+		case tb.EventKey:
+			if event.Key == tb.KeyEsc {
+				state.Exit = true
+			}
+		case tb.EventResize:
+			state.Invalidate(InvalidateAll)
 		}
-	case tb.EventResize:
-		state.Invalidate(InvalidateAll)
+	default:
+		// no-op
+		break
 	}
 	if state.InvalidPanes != 0 {
-		// TODO: re-render
+		if state.InvalidPanes&InvalidateAll == InvalidateAll {
+			tb.Clear(tb.ColorDefault, tb.ColorDefault)
+			state.calcGeometries()
+		}
+		if state.InvalidPanes&InvalidateTabs != 0 {
+			tab := state.Tabs[state.SelectedTab]
+			tab.Render(state.Panes.TabView)
+		}
+		tb.Flush()
 		state.InvalidPanes = 0
 	}
 	return true
diff --git a/ui/types.go b/ui/types.go
index a7918b5..588c3b3 100644
--- a/ui/types.go
+++ b/ui/types.go
@@ -1,5 +1,11 @@
 package ui
 
+import (
+	tb "github.com/nsf/termbox-go"
+
+	"git.sr.ht/~sircmpwn/aerc2/config"
+)
+
 const (
 	Valid          = 0
 	InvalidateTabs = 1 << iota
@@ -12,19 +18,21 @@ const (
 )
 
 type Geometry struct {
-	row    int
-	col    int
-	width  int
-	height int
+	Row    int
+	Col    int
+	Width  int
+	Height int
 }
 
 type AercTab interface {
 	Name() string
 	Invalid() bool
 	Render(at Geometry)
+	SetParent(parent *UIState)
 }
 
 type UIState struct {
+	Config       *config.AercConfig
 	Exit         bool
 	InvalidPanes uint
 
@@ -44,4 +52,6 @@ type UIState struct {
 		Index  int
 		Scroll int
 	}
+
+	tbEvents chan tb.Event
 }