aboutsummaryrefslogtreecommitdiff
path: root/widgets/aerc.go
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/aerc.go')
-rw-r--r--widgets/aerc.go129
1 files changed, 114 insertions, 15 deletions
diff --git a/widgets/aerc.go b/widgets/aerc.go
index 3537897..5841876 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -2,6 +2,7 @@ package widgets
import (
"log"
+ "time"
"github.com/gdamore/tcell"
@@ -11,10 +12,16 @@ import (
)
type Aerc struct {
- accounts map[string]*AccountView
- cmd func(cmd string) error
- grid *libui.Grid
- tabs *libui.Tabs
+ accounts map[string]*AccountView
+ cmd func(cmd string) error
+ conf *config.AercConfig
+ focused libui.Interactive
+ grid *libui.Grid
+ logger *log.Logger
+ statusbar *libui.Stack
+ statusline *StatusLine
+ pendingKeys []config.KeyStroke
+ tabs *libui.Tabs
}
func NewAerc(conf *config.AercConfig, logger *log.Logger,
@@ -22,29 +29,42 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger,
tabs := libui.NewTabs()
- mainGrid := libui.NewGrid().Rows([]libui.GridSpec{
+ statusbar := ui.NewStack()
+ statusline := NewStatusLine()
+ statusbar.Push(statusline)
+
+ grid := libui.NewGrid().Rows([]libui.GridSpec{
{libui.SIZE_EXACT, 1},
{libui.SIZE_WEIGHT, 1},
+ {libui.SIZE_EXACT, 1},
}).Columns([]libui.GridSpec{
{libui.SIZE_EXACT, conf.Ui.SidebarWidth},
{libui.SIZE_WEIGHT, 1},
})
+ grid.AddChild(statusbar).At(2, 1)
+ // Minor hack
+ grid.AddChild(libui.NewBordered(
+ libui.NewFill(' '), libui.BORDER_RIGHT)).At(2, 0)
- mainGrid.AddChild(libui.NewText("aerc").
+ grid.AddChild(libui.NewText("aerc").
Strategy(libui.TEXT_CENTER).
Color(tcell.ColorBlack, tcell.ColorWhite))
- mainGrid.AddChild(tabs.TabStrip).At(0, 1)
- mainGrid.AddChild(tabs.TabContent).At(1, 0).Span(1, 2)
+ grid.AddChild(tabs.TabStrip).At(0, 1)
+ grid.AddChild(tabs.TabContent).At(1, 0).Span(1, 2)
aerc := &Aerc{
- accounts: make(map[string]*AccountView),
- cmd: cmd,
- grid: mainGrid,
- tabs: tabs,
+ accounts: make(map[string]*AccountView),
+ conf: conf,
+ cmd: cmd,
+ grid: grid,
+ logger: logger,
+ statusbar: statusbar,
+ statusline: statusline,
+ tabs: tabs,
}
for _, acct := range conf.Accounts {
- view := NewAccountView(conf, &acct, logger, cmd)
+ view := NewAccountView(conf, &acct, logger, aerc)
aerc.accounts[acct.Name] = view
tabs.Add(view, acct.Name)
}
@@ -75,8 +95,41 @@ func (aerc *Aerc) Draw(ctx *libui.Context) {
}
func (aerc *Aerc) Event(event tcell.Event) bool {
- acct, _ := aerc.tabs.Tabs[aerc.tabs.Selected].Content.(*AccountView)
- return acct.Event(event)
+ if aerc.focused != nil {
+ aerc.logger.Println("sending event to focused child")
+ return aerc.focused.Event(event)
+ }
+
+ switch event := event.(type) {
+ case *tcell.EventKey:
+ aerc.pendingKeys = append(aerc.pendingKeys, config.KeyStroke{
+ Key: event.Key(),
+ Rune: event.Rune(),
+ })
+ result, output := aerc.conf.Lbinds.GetBinding(aerc.pendingKeys)
+ switch result {
+ case config.BINDING_FOUND:
+ aerc.pendingKeys = []config.KeyStroke{}
+ for _, stroke := range output {
+ simulated := tcell.NewEventKey(
+ stroke.Key, stroke.Rune, tcell.ModNone)
+ aerc.Event(simulated)
+ }
+ case config.BINDING_INCOMPLETE:
+ return false
+ case config.BINDING_NOT_FOUND:
+ aerc.pendingKeys = []config.KeyStroke{}
+ if event.Rune() == ':' {
+ aerc.BeginExCommand()
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (aerc *Aerc) Config() *config.AercConfig {
+ return aerc.conf
}
func (aerc *Aerc) SelectedAccount() *AccountView {
@@ -86,3 +139,49 @@ func (aerc *Aerc) SelectedAccount() *AccountView {
}
return acct
}
+
+func (aerc *Aerc) NewTab(drawable ui.Drawable, name string) *ui.Tab {
+ tab := aerc.tabs.Add(drawable, name)
+ aerc.tabs.Select(len(aerc.tabs.Tabs) - 1)
+ return tab
+}
+
+// TODO: Use per-account status lines, but a global ex line
+func (aerc *Aerc) SetStatus(status string) *StatusMessage {
+ return aerc.statusline.Set(status)
+}
+
+func (aerc *Aerc) PushStatus(text string, expiry time.Duration) *StatusMessage {
+ return aerc.statusline.Push(text, expiry)
+}
+
+func (aerc *Aerc) focus(item libui.Interactive) {
+ if aerc.focused == item {
+ return
+ }
+ if aerc.focused != nil {
+ aerc.focused.Focus(false)
+ }
+ aerc.focused = item
+ if item != nil {
+ item.Focus(true)
+ }
+}
+
+func (aerc *Aerc) BeginExCommand() {
+ previous := aerc.focused
+ exline := NewExLine(func(cmd string) {
+ err := aerc.cmd(cmd)
+ if err != nil {
+ aerc.PushStatus(" "+err.Error(), 10*time.Second).
+ Color(tcell.ColorRed, tcell.ColorWhite)
+ }
+ aerc.statusbar.Pop()
+ aerc.focus(previous)
+ }, func() {
+ aerc.statusbar.Pop()
+ aerc.focus(previous)
+ })
+ aerc.statusbar.Push(exline)
+ aerc.focus(exline)
+}