diff options
| author | Drew DeVault <sir@cmpwn.com> | 2018-02-27 21:17:26 -0500 | 
|---|---|---|
| committer | Drew DeVault <sir@cmpwn.com> | 2018-02-27 21:17:26 -0500 | 
| commit | cab3771e17286788913255a6abe858b476166837 (patch) | |
| tree | 85c626c779e380bb6a9d7ddd6cba69ef33cf919d | |
| parent | a073d7613fac7c79b7909d93a0dd7bfea05d5c9d (diff) | |
Pull main aerc UI into widget
| -rw-r--r-- | cmd/aerc/main.go | 71 | ||||
| -rw-r--r-- | lib/ui/fill.go | 27 | ||||
| -rw-r--r-- | lib/ui/interactive.go | 5 | ||||
| -rw-r--r-- | lib/ui/ui.go | 19 | ||||
| -rw-r--r-- | widgets/aerc.go | 91 | 
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) +}  | 
