diff --git a/commands/set.go b/commands/set.go index 1d20f06..cc6333e 100644 --- a/commands/set.go +++ b/commands/set.go @@ -61,6 +61,9 @@ func SetCore(aerc *widgets.Aerc, args []string) error { return err } + // ensure any ui changes take effect + aerc.Invalidate() + return nil } diff --git a/lib/ui/grid.go b/lib/ui/grid.go index b47c6bd..cff5577 100644 --- a/lib/ui/grid.go +++ b/lib/ui/grid.go @@ -31,10 +31,12 @@ const ( type GridSpec struct { // One of SIZE_EXACT or SIZE_WEIGHT Strategy int - // If Strategy = SIZE_EXACT, this is the number of cells this row/col shall - // occupy. If SIZE_WEIGHT, the space left after all exact rows/cols are - // measured is distributed amonst the remainder weighted by this value. - Size int + + // If Strategy = SIZE_EXACT, this function returns the number of cells + // this row/col shall occupy. If SIZE_WEIGHT, the space left after all + // exact rows/cols are measured is distributed amonst the remainder + // weighted by the value returned by this function. + Size func() int } // Used to cache layout of each row/column @@ -61,11 +63,11 @@ func NewGrid() *Grid { func MakeGrid(numRows, numCols, rowStrategy, colStrategy int) *Grid { rows := make([]GridSpec, numRows) for i := 0; i < numRows; i++ { - rows[i] = GridSpec{rowStrategy, 1} + rows[i] = GridSpec{rowStrategy, Const(1)} } cols := make([]GridSpec, numCols) for i := 0; i < numCols; i++ { - cols[i] = GridSpec{colStrategy, 1} + cols[i] = GridSpec{colStrategy, Const(1)} } return NewGrid().Rows(rows).Columns(cols) } @@ -191,10 +193,10 @@ func (grid *Grid) reflow(ctx *Context) { nweights := 0 for _, spec := range *specs { if spec.Strategy == SIZE_EXACT { - exact += spec.Size + exact += spec.Size() } else if spec.Strategy == SIZE_WEIGHT { nweights += 1 - weight += spec.Size + weight += spec.Size() } } offset := 0 @@ -205,9 +207,9 @@ func (grid *Grid) reflow(ctx *Context) { for _, spec := range *specs { layout := gridLayout{Offset: offset} if spec.Strategy == SIZE_EXACT { - layout.Size = spec.Size + layout.Size = spec.Size() } else if spec.Strategy == SIZE_WEIGHT { - proportion := float64(spec.Size) / float64(weight) + proportion := float64(spec.Size()) / float64(weight) size := proportion * float64(extent-exact) if remainingExact > 0 { extraExact := int(math.Ceil(proportion * float64(remainingExact))) @@ -284,3 +286,7 @@ func (grid *Grid) cellInvalidated(drawable Drawable) { cell.invalid.Store(true) grid.DoInvalidate(grid) } + +func Const(i int) func() int { + return func() int { return i } +} diff --git a/widgets/account-wizard.go b/widgets/account-wizard.go index 6f93367..4e51926 100644 --- a/widgets/account-wizard.go +++ b/widgets/account-wizard.go @@ -136,18 +136,18 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { }) basics := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 8}, // Introduction - {ui.SIZE_EXACT, 1}, // Account name (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Full name (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Email address (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(8)}, // Introduction + {ui.SIZE_EXACT, ui.Const(1)}, // Account name (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Full name (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Email address (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_WEIGHT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) basics.AddChild( ui.NewText("\nWelcome to aerc! Let's configure your account.\n\n" + @@ -209,23 +209,23 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { }) incoming := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 3}, // Introduction - {ui.SIZE_EXACT, 1}, // Username (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Password (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Server (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Connection mode (label) - {ui.SIZE_EXACT, 2}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Connection string - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(3)}, // Introduction + {ui.SIZE_EXACT, ui.Const(1)}, // Username (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Password (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Server (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Connection mode (label) + {ui.SIZE_EXACT, ui.Const(2)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Connection string + {ui.SIZE_WEIGHT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) incoming.AddChild(ui.NewText("\nConfigure incoming mail (IMAP)")) incoming.AddChild( @@ -283,26 +283,26 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { }) outgoing := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 3}, // Introduction - {ui.SIZE_EXACT, 1}, // Username (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Password (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Server (label) - {ui.SIZE_EXACT, 1}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Connection mode (label) - {ui.SIZE_EXACT, 2}, // (input) - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Connection string - {ui.SIZE_EXACT, 1}, // Padding - {ui.SIZE_EXACT, 1}, // Copy to sent (label) - {ui.SIZE_EXACT, 2}, // (input) - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(3)}, // Introduction + {ui.SIZE_EXACT, ui.Const(1)}, // Username (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Password (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Server (label) + {ui.SIZE_EXACT, ui.Const(1)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Connection mode (label) + {ui.SIZE_EXACT, ui.Const(2)}, // (input) + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Connection string + {ui.SIZE_EXACT, ui.Const(1)}, // Padding + {ui.SIZE_EXACT, ui.Const(1)}, // Copy to sent (label) + {ui.SIZE_EXACT, ui.Const(2)}, // (input) + {ui.SIZE_WEIGHT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) outgoing.AddChild(ui.NewText("\nConfigure outgoing mail (SMTP)")) outgoing.AddChild( @@ -374,10 +374,10 @@ func NewAccountWizard(conf *config.AercConfig, aerc *Aerc) *AccountWizard { }) complete := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 7}, // Introduction - {ui.SIZE_WEIGHT, 1}, // Previous / Finish / Finish & open tutorial + {ui.SIZE_EXACT, ui.Const(7)}, // Introduction + {ui.SIZE_WEIGHT, ui.Const(1)}, // Previous / Finish / Finish & open tutorial }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) complete.AddChild(ui.NewText( "\nConfiguration complete!\n\n" + diff --git a/widgets/account.go b/widgets/account.go index 20ed345..313a364 100644 --- a/widgets/account.go +++ b/widgets/account.go @@ -45,45 +45,38 @@ func NewAccountView(aerc *Aerc, conf *config.AercConfig, acct *config.AccountCon config.UI_CONTEXT_ACCOUNT: acct.Name, }) - grid := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + view := &AccountView{ + acct: acct, + aerc: aerc, + conf: conf, + host: host, + logger: logger, + } + + view.grid = ui.NewGrid().Rows([]ui.GridSpec{ + {ui.SIZE_WEIGHT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_EXACT, acctUiConf.SidebarWidth}, - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, func() int { + return view.UiConfig().SidebarWidth + }}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) worker, err := worker.NewWorker(acct.Source, logger) if err != nil { host.SetStatus(fmt.Sprintf("%s: %s", acct.Name, err)). Color(tcell.ColorDefault, tcell.ColorRed) - return &AccountView{ - acct: acct, - aerc: aerc, - grid: grid, - host: host, - logger: logger, - } + return view } + view.worker = worker - dirlist := NewDirectoryList(conf, acct, logger, worker) + view.dirlist = NewDirectoryList(conf, acct, logger, worker) if acctUiConf.SidebarWidth > 0 { - grid.AddChild(ui.NewBordered(dirlist, ui.BORDER_RIGHT)) + view.grid.AddChild(ui.NewBordered(view.dirlist, ui.BORDER_RIGHT)) } - msglist := NewMessageList(conf, logger, aerc) - grid.AddChild(msglist).At(0, 1) - - view := &AccountView{ - acct: acct, - aerc: aerc, - conf: conf, - dirlist: dirlist, - grid: grid, - host: host, - logger: logger, - msglist: msglist, - worker: worker, - } + view.msglist = NewMessageList(conf, logger, aerc) + view.grid.AddChild(view.msglist).At(0, 1) go worker.Backend.Run() diff --git a/widgets/aerc.go b/widgets/aerc.go index 829873a..4913be3 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -56,11 +56,11 @@ func NewAerc(conf *config.AercConfig, logger *log.Logger, statusbar.Push(statusline) grid := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 1}, - {ui.SIZE_WEIGHT, 1}, - {ui.SIZE_EXACT, 1}, + {ui.SIZE_EXACT, ui.Const(1)}, + {ui.SIZE_WEIGHT, ui.Const(1)}, + {ui.SIZE_EXACT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) grid.AddChild(tabs.TabStrip) grid.AddChild(tabs.TabContent).At(1, 0) @@ -552,7 +552,6 @@ func (aerc *Aerc) CloseDialog() { return } - func (aerc *Aerc) GetPassword(title string, prompt string) (chText chan string, chErr chan error) { chText = make(chan string, 1) chErr = make(chan error, 1) diff --git a/widgets/compose.go b/widgets/compose.go index 01b8dd8..b68c406 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -673,13 +673,15 @@ func (c *Composer) updateGrid() { ) if c.grid == nil { - c.grid = ui.NewGrid().Columns([]ui.GridSpec{{ui.SIZE_WEIGHT, 1}}) + c.grid = ui.NewGrid().Columns([]ui.GridSpec{ + {ui.SIZE_WEIGHT, ui.Const(1)}, + }) } c.grid.Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, height}, - {ui.SIZE_EXACT, 1}, - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(height)}, + {ui.SIZE_EXACT, ui.Const(1)}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) if c.header != nil { @@ -768,15 +770,18 @@ type reviewMessage struct { } func newReviewMessage(composer *Composer, err error) *reviewMessage { - spec := []ui.GridSpec{{ui.SIZE_EXACT, 2}, {ui.SIZE_EXACT, 1}} + spec := []ui.GridSpec{ + {ui.SIZE_EXACT, ui.Const(2)}, + {ui.SIZE_EXACT, ui.Const(1)}, + } for i := 0; i < len(composer.attachments)-1; i++ { - spec = append(spec, ui.GridSpec{ui.SIZE_EXACT, 1}) + spec = append(spec, ui.GridSpec{ui.SIZE_EXACT, ui.Const(1)}) } // make the last element fill remaining space - spec = append(spec, ui.GridSpec{ui.SIZE_WEIGHT, 1}) + spec = append(spec, ui.GridSpec{ui.SIZE_WEIGHT, ui.Const(1)}) grid := ui.NewGrid().Rows(spec).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) if err != nil { diff --git a/widgets/msgviewer.go b/widgets/msgviewer.go index ce85970..f06b787 100644 --- a/widgets/msgviewer.go +++ b/widgets/msgviewer.go @@ -69,7 +69,7 @@ func NewMessageViewer(acct *AccountView, ) rows := []ui.GridSpec{ - {ui.SIZE_EXACT, headerHeight}, + {ui.SIZE_EXACT, ui.Const(headerHeight)}, } if msg.PGPDetails() != nil { @@ -77,16 +77,16 @@ func NewMessageViewer(acct *AccountView, if msg.PGPDetails().IsSigned && msg.PGPDetails().IsEncrypted { height = 2 } - rows = append(rows, ui.GridSpec{ui.SIZE_EXACT, height}) + rows = append(rows, ui.GridSpec{ui.SIZE_EXACT, ui.Const(height)}) } rows = append(rows, []ui.GridSpec{ - {ui.SIZE_EXACT, 1}, - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(1)}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }...) grid := ui.NewGrid().Rows(rows).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) switcher := &PartSwitcher{} @@ -373,7 +373,7 @@ func (ps *PartSwitcher) MouseEvent(localX int, localY int, event tcell.Event) { if localY < y && ps.parts[ps.selected].term != nil { ps.parts[ps.selected].term.MouseEvent(localX, localY, event) } - for i, _ := range ps.parts { + for i := range ps.parts { if localY != y+i { continue } @@ -511,11 +511,11 @@ func NewPartViewer(acct *AccountView, conf *config.AercConfig, } grid := ui.NewGrid().Rows([]ui.GridSpec{ - {ui.SIZE_EXACT, 3}, // Message - {ui.SIZE_EXACT, 1}, // Selector - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_EXACT, ui.Const(3)}, // Message + {ui.SIZE_EXACT, ui.Const(1)}, // Selector + {ui.SIZE_WEIGHT, ui.Const(1)}, }).Columns([]ui.GridSpec{ - {ui.SIZE_WEIGHT, 1}, + {ui.SIZE_WEIGHT, ui.Const(1)}, }) selecter := NewSelecter([]string{"Save message", "Pipe to command"}, 0).