aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/aerc/main.go71
-rw-r--r--lib/ui/fill.go27
-rw-r--r--lib/ui/interactive.go5
-rw-r--r--lib/ui/ui.go19
-rw-r--r--widgets/aerc.go91
5 files changed, 130 insertions, 83 deletions
diff --git a/cmd/aerc/main.go b/cmd/aerc/main.go
index 009b5eb..3030ee9 100644
--- a/cmd/aerc/main.go
+++ b/cmd/aerc/main.go
@@ -8,31 +8,12 @@ import (
"time"
"github.com/mattn/go-isatty"
- tb "github.com/nsf/termbox-go"
"git.sr.ht/~sircmpwn/aerc2/config"
libui "git.sr.ht/~sircmpwn/aerc2/lib/ui"
"git.sr.ht/~sircmpwn/aerc2/widgets"
)
-type fill rune
-
-func (f fill) Draw(ctx *libui.Context) {
- for x := 0; x < ctx.Width(); x += 1 {
- for y := 0; y < ctx.Height(); y += 1 {
- ctx.SetCell(x, y, rune(f), tb.ColorDefault, tb.ColorDefault)
- }
- }
-}
-
-func (f fill) OnInvalidate(callback func(d libui.Drawable)) {
- // no-op
-}
-
-func (f fill) Invalidate() {
- // no-op
-}
-
func main() {
var logOut io.Writer
var logger *log.Logger
@@ -49,62 +30,12 @@ func main() {
panic(err)
}
- tabs := libui.NewTabs()
- tabs.Add(fill('★'), "白い星")
- tabs.Add(fill('☆'), "empty stars")
-
- grid := libui.NewGrid().Rows([]libui.GridSpec{
- libui.GridSpec{libui.SIZE_EXACT, 1},
- libui.GridSpec{libui.SIZE_WEIGHT, 1},
- libui.GridSpec{libui.SIZE_EXACT, 1},
- }).Columns([]libui.GridSpec{
- libui.GridSpec{libui.SIZE_EXACT, 20},
- libui.GridSpec{libui.SIZE_WEIGHT, 1},
- })
-
- // TODO: move sidebar into tab content, probably
- grid.AddChild(libui.NewText("aerc").
- Strategy(libui.TEXT_CENTER).
- Color(tb.ColorBlack, tb.ColorWhite))
- // sidebar placeholder:
- grid.AddChild(libui.NewBordered(
- fill('.'), libui.BORDER_RIGHT)).At(1, 0).Span(2, 1)
- grid.AddChild(tabs.TabStrip).At(0, 1)
- grid.AddChild(tabs.TabContent).At(1, 1)
-
- statusbar := libui.NewStack()
- grid.AddChild(statusbar).At(2, 1)
-
- statusline := widgets.NewStatusLine()
- statusline.Push("test status!", 6*time.Second)
- statusline.Push("test error!", 3*time.Second).
- Color(tb.ColorRed, tb.ColorBlack)
- statusbar.Push(statusline)
-
- exline := widgets.NewExLine(func(command string) {
- statusbar.Pop()
- logger.Printf("TODO: execute command: %s\n", command)
- }, func() {
- statusbar.Pop()
- })
- statusbar.Push(exline)
-
- ui, err := libui.Initialize(conf, grid)
+ ui, err := libui.Initialize(conf, widgets.NewAerc(logger))
if err != nil {
panic(err)
}
defer ui.Close()
- // TODO: this should be a stack
- ui.AddInteractive(exline)
-
- go (func() {
- for {
- time.Sleep(1 * time.Second)
- tabs.Select((tabs.Selected + 1) % 2)
- }
- })()
-
for !ui.Exit {
if !ui.Tick() {
// ~60 FPS
diff --git a/lib/ui/fill.go b/lib/ui/fill.go
new file mode 100644
index 0000000..3c6f0a5
--- /dev/null
+++ b/lib/ui/fill.go
@@ -0,0 +1,27 @@
+package ui
+
+import (
+ tb "github.com/nsf/termbox-go"
+)
+
+type Fill rune
+
+func NewFill(f rune) Fill {
+ return Fill(f)
+}
+
+func (f Fill) Draw(ctx *Context) {
+ for x := 0; x < ctx.Width(); x += 1 {
+ for y := 0; y < ctx.Height(); y += 1 {
+ ctx.SetCell(x, y, rune(f), tb.ColorDefault, tb.ColorDefault)
+ }
+ }
+}
+
+func (f Fill) OnInvalidate(callback func(d Drawable)) {
+ // no-op
+}
+
+func (f Fill) Invalidate() {
+ // no-op
+}
diff --git a/lib/ui/interactive.go b/lib/ui/interactive.go
index 8bdf592..efab828 100644
--- a/lib/ui/interactive.go
+++ b/lib/ui/interactive.go
@@ -13,3 +13,8 @@ type Simulator interface {
// Queues up the given input events for simulation
Simulate(events []tb.Event)
}
+
+type DrawableInteractive interface {
+ Drawable
+ Interactive
+}
diff --git a/lib/ui/ui.go b/lib/ui/ui.go
index 9ea037c..e9b4e9b 100644
--- a/lib/ui/ui.go
+++ b/lib/ui/ui.go
@@ -8,16 +8,16 @@ import (
type UI struct {
Exit bool
- Content Drawable
+ Content DrawableInteractive
ctx *Context
- interactive []Interactive
-
tbEvents chan tb.Event
invalidations chan interface{}
}
-func Initialize(conf *config.AercConfig, content Drawable) (*UI, error) {
+func Initialize(conf *config.AercConfig,
+ content DrawableInteractive) (*UI, error) {
+
if err := tb.Init(); err != nil {
return nil, err
}
@@ -52,6 +52,7 @@ func (state *UI) Tick() bool {
case event := <-state.tbEvents:
switch event.Type {
case tb.EventKey:
+ // TODO: temporary
if event.Key == tb.KeyEsc {
state.Exit = true
}
@@ -60,11 +61,7 @@ func (state *UI) Tick() bool {
state.ctx = NewContext(event.Width, event.Height)
state.Content.Invalidate()
}
- if state.interactive != nil {
- for _, i := range state.interactive {
- i.Event(event)
- }
- }
+ state.Content.Event(event)
case <-state.invalidations:
state.Content.Draw(state.ctx)
tb.Flush()
@@ -73,7 +70,3 @@ func (state *UI) Tick() bool {
}
return true
}
-
-func (state *UI) AddInteractive(i Interactive) {
- state.interactive = append(state.interactive, i)
-}
diff --git a/widgets/aerc.go b/widgets/aerc.go
new file mode 100644
index 0000000..2168e61
--- /dev/null
+++ b/widgets/aerc.go
@@ -0,0 +1,91 @@
+package widgets
+
+import (
+ "log"
+ "time"
+
+ tb "github.com/nsf/termbox-go"
+
+ libui "git.sr.ht/~sircmpwn/aerc2/lib/ui"
+)
+
+type Aerc struct {
+ grid *libui.Grid
+ tabs *libui.Tabs
+ statusbar *libui.Stack
+ statusline *StatusLine
+ interactive libui.Interactive
+}
+
+func NewAerc(logger *log.Logger) *Aerc {
+ tabs := libui.NewTabs()
+ tabs.Add(libui.NewFill('★'), "白い星")
+ tabs.Add(libui.NewFill('☆'), "empty stars")
+
+ grid := libui.NewGrid().Rows([]libui.GridSpec{
+ libui.GridSpec{libui.SIZE_EXACT, 1},
+ libui.GridSpec{libui.SIZE_WEIGHT, 1},
+ libui.GridSpec{libui.SIZE_EXACT, 1},
+ }).Columns([]libui.GridSpec{
+ libui.GridSpec{libui.SIZE_EXACT, 20},
+ libui.GridSpec{libui.SIZE_WEIGHT, 1},
+ })
+
+ // TODO: move sidebar into tab content, probably
+ grid.AddChild(libui.NewText("aerc").
+ Strategy(libui.TEXT_CENTER).
+ Color(tb.ColorBlack, tb.ColorWhite))
+ // sidebar placeholder:
+ grid.AddChild(libui.NewBordered(
+ libui.NewFill('.'), libui.BORDER_RIGHT)).At(1, 0).Span(2, 1)
+ grid.AddChild(tabs.TabStrip).At(0, 1)
+ grid.AddChild(tabs.TabContent).At(1, 1)
+
+ statusbar := libui.NewStack()
+ grid.AddChild(statusbar).At(2, 1)
+
+ statusline := NewStatusLine()
+ statusline.Push("test status!", 6 * time.Second)
+ statusline.Push("test error!", 3 * time.Second).
+ Color(tb.ColorRed, tb.ColorBlack)
+ statusbar.Push(statusline)
+
+ exline := NewExLine(func(command string) {
+ statusbar.Pop()
+ logger.Printf("TODO: execute command: %s\n", command)
+ }, func() {
+ statusbar.Pop()
+ })
+ statusbar.Push(exline)
+
+ go (func() {
+ for {
+ time.Sleep(1 * time.Second)
+ tabs.Select((tabs.Selected + 1) % 2)
+ }
+ })()
+
+ return &Aerc{
+ grid: grid,
+ interactive: exline,
+ statusbar: statusbar,
+ statusline: statusline,
+ tabs: tabs,
+ }
+}
+
+func (aerc *Aerc) OnInvalidate(onInvalidate func(d libui.Drawable)) {
+ aerc.grid.OnInvalidate(onInvalidate)
+}
+
+func (aerc *Aerc) Invalidate() {
+ aerc.grid.Invalidate()
+}
+
+func (aerc *Aerc) Draw(ctx *libui.Context) {
+ aerc.grid.Draw(ctx)
+}
+
+func (aerc *Aerc) Event(event tb.Event) bool {
+ return aerc.interactive.Event(event)
+}