From db1b2cd53f5dc7bfbfb6ee54ad0bb0882ea2cc03 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 10 Jan 2018 22:03:56 -0500 Subject: [PATCH] Renderer scaffolding --- cmd/aerc/main.go | 12 +++++++---- ui/render.go | 45 +++++++++++++++++++++++++++++++++++++++++ ui/types.go | 47 +++++++++++++++++++++++++++++++++++++++++++ worker/imap/worker.go | 2 -- 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 ui/render.go create mode 100644 ui/types.go diff --git a/cmd/aerc/main.go b/cmd/aerc/main.go index 9188dce..4adf11e 100644 --- a/cmd/aerc/main.go +++ b/cmd/aerc/main.go @@ -1,10 +1,10 @@ package main import ( - "fmt" "time" "git.sr.ht/~sircmpwn/aerc2/config" + "git.sr.ht/~sircmpwn/aerc2/ui" "git.sr.ht/~sircmpwn/aerc2/worker" "git.sr.ht/~sircmpwn/aerc2/worker/types" ) @@ -20,19 +20,23 @@ func main() { if err != nil { panic(err) } - fmt.Printf("Initializing worker %s\n", account.Name) go work.Run() work.PostAction(types.Configure{Config: account}) workers = append(workers, work) } - for { + _ui, err := ui.Initialize(conf) + if err != nil { + panic(err) + } + defer _ui.Close() + for !_ui.Exit { activity := false for _, worker := range workers { if msg := worker.GetMessage(); msg != nil { activity = true - fmt.Printf("<- %T\n", msg) } } + activity = _ui.Tick() || activity if !activity { time.Sleep(100 * time.Millisecond) } diff --git a/ui/render.go b/ui/render.go new file mode 100644 index 0000000..bca0cf6 --- /dev/null +++ b/ui/render.go @@ -0,0 +1,45 @@ +package ui + +import ( + tb "github.com/nsf/termbox-go" + + "git.sr.ht/~sircmpwn/aerc2/config" +) + +func Initialize(conf *config.AercConfig) (*UIState, error) { + state := UIState{ + InvalidPanes: InvalidateAll, + Tabs: make([]AercTab, len(conf.Accounts)), + } + // 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) + return &state, nil +} + +func (state *UIState) Close() { + tb.Close() +} + +func (state *UIState) Invalidate(what uint) { + state.InvalidPanes |= what +} + +func (state *UIState) Tick() bool { + switch e := tb.PollEvent(); e.Type { + case tb.EventKey: + if e.Key == tb.KeyEsc { + state.Exit = true + } + case tb.EventResize: + state.Invalidate(InvalidateAll) + } + if state.InvalidPanes != 0 { + // TODO: re-render + state.InvalidPanes = 0 + } + return true +} diff --git a/ui/types.go b/ui/types.go new file mode 100644 index 0000000..a7918b5 --- /dev/null +++ b/ui/types.go @@ -0,0 +1,47 @@ +package ui + +const ( + Valid = 0 + InvalidateTabs = 1 << iota + InvalidateSidebar + InvalidateStatusBar +) + +const ( + InvalidateAll = InvalidateTabs | InvalidateSidebar | InvalidateStatusBar +) + +type Geometry struct { + row int + col int + width int + height int +} + +type AercTab interface { + Name() string + Invalid() bool + Render(at Geometry) +} + +type UIState struct { + Exit bool + InvalidPanes uint + + Panes struct { + TabList Geometry + TabView Geometry + Sidebar Geometry + StatusBar Geometry + } + + Tabs []AercTab + SelectedTab int + + Prompt struct { + Prompt *string + Text *string + Index int + Scroll int + } +} diff --git a/worker/imap/worker.go b/worker/imap/worker.go index 6ffdf3a..14e4004 100644 --- a/worker/imap/worker.go +++ b/worker/imap/worker.go @@ -1,7 +1,6 @@ package imap import ( - "fmt" "time" "git.sr.ht/~sircmpwn/aerc2/worker/types" @@ -50,7 +49,6 @@ func (w *IMAPWorker) Run() { for { select { case msg := <-w.actions: - fmt.Printf("<= %T\n", msg) w.handleMessage(msg) default: time.Sleep(100 * time.Millisecond)