diff options
author | Jeffas <dev@jeffas.io> | 2020-06-09 20:13:13 +0100 |
---|---|---|
committer | Reto Brunner <reto@labrat.space> | 2020-06-09 21:52:10 +0200 |
commit | 15b72df1dabb6675c20cff043648e97a209d2132 (patch) | |
tree | 184b15a40d8aa242259f4ee46caebc51527f5e26 | |
parent | c6f4d7badd4cb36067f0e76198630a3d0f9e7ce9 (diff) | |
download | aerc-15b72df1dabb6675c20cff043648e97a209d2132.tar.gz |
Rework msglist scrolling
This changes the scrolling to be done on the draw, when the height is
updated, ensuring that the selected item is kept on screen during
resizing.
Also, this ensures that messages will fill the screen when resizing the
window, for instance, shrinking and then growing drags down more
messages if possible.
This is a transplant of the dirlist scrolling logic.
-rw-r--r-- | commands/account/next-result.go | 4 | ||||
-rw-r--r-- | commands/account/next.go | 4 | ||||
-rw-r--r-- | commands/account/search.go | 2 | ||||
-rw-r--r-- | commands/msg/archive.go | 2 | ||||
-rw-r--r-- | commands/msg/delete.go | 4 | ||||
-rw-r--r-- | commands/msg/move.go | 2 | ||||
-rw-r--r-- | widgets/msglist.go | 44 |
7 files changed, 39 insertions, 23 deletions
diff --git a/commands/account/next-result.go b/commands/account/next-result.go index 78d437d3..fe835eab 100644 --- a/commands/account/next-result.go +++ b/commands/account/next-result.go @@ -34,13 +34,13 @@ func (NextPrevResult) Execute(aerc *widgets.Aerc, args []string) error { if store != nil { store.PrevResult() } - acct.Messages().Scroll() + acct.Messages().Invalidate() } else { store := acct.Store() if store != nil { store.NextResult() } - acct.Messages().Scroll() + acct.Messages().Invalidate() } return nil } diff --git a/commands/account/next.go b/commands/account/next.go index 5e4838e0..427f5637 100644 --- a/commands/account/next.go +++ b/commands/account/next.go @@ -65,13 +65,13 @@ func ExecuteNextPrevMessage(args []string, acct *widgets.AccountView, pct bool, store := acct.Store() if store != nil { store.NextPrev(-n) - acct.Messages().Scroll() + acct.Messages().Invalidate() } } else { store := acct.Store() if store != nil { store.NextPrev(n) - acct.Messages().Scroll() + acct.Messages().Invalidate() } } return nil diff --git a/commands/account/search.go b/commands/account/search.go index 1d2e7a2b..607dc24c 100644 --- a/commands/account/search.go +++ b/commands/account/search.go @@ -45,7 +45,7 @@ func (SearchFilter) Execute(aerc *widgets.Aerc, args []string) error { acct.Logger().Printf("Search results: %v", uids) store.ApplySearch(uids) // TODO: Remove when stores have multiple OnUpdate handlers - acct.Messages().Scroll() + acct.Messages().Invalidate() } } store.Search(args, cb) diff --git a/commands/msg/archive.go b/commands/msg/archive.go index 55616748..07de13f7 100644 --- a/commands/msg/archive.go +++ b/commands/msg/archive.go @@ -53,7 +53,7 @@ func (Archive) Execute(aerc *widgets.Aerc, args []string) error { } archiveDir := acct.AccountConfig().Archive store.Next() - acct.Messages().Scroll() + acct.Messages().Invalidate() var uidMap map[string][]uint32 switch args[1] { diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 4bda8b98..e74bf104 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -62,7 +62,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { // no more messages in the list if next == nil { aerc.RemoveTab(h.msgProvider) - acct.Messages().Scroll() + acct.Messages().Invalidate() return nil } lib.NewMessageStoreView(next, store, aerc.DecryptKeys, @@ -76,7 +76,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { }) } } - acct.Messages().Scroll() + acct.Messages().Invalidate() return nil } diff --git a/commands/msg/move.go b/commands/msg/move.go index 830e7521..41f61dad 100644 --- a/commands/msg/move.go +++ b/commands/msg/move.go @@ -62,7 +62,7 @@ func (Move) Execute(aerc *widgets.Aerc, args []string) error { aerc.RemoveTab(h.msgProvider) } store.Next() - acct.Messages().Scroll() + acct.Messages().Invalidate() joinedArgs := strings.Join(args[optind:], " ") store.Move(uids, joinedArgs, createParents, func( msg types.WorkerMessage) { diff --git a/widgets/msglist.go b/widgets/msglist.go index 5aedb446..38b6369a 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -63,6 +63,8 @@ func (ml *MessageList) Draw(ctx *ui.Context) { } } + ml.ensureScroll() + var ( needsHeaders []uint32 row int = 0 @@ -179,12 +181,12 @@ func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) { if ml.store != nil { ml.store.Next() } - ml.Scroll() + ml.Invalidate() case tcell.WheelUp: if ml.store != nil { ml.store.Prev() } - ml.Scroll() + ml.Invalidate() } } } @@ -225,7 +227,6 @@ func (ml *MessageList) storeUpdate(store *lib.MessageStore) { ml.nmsgs = len(uids) } - ml.Scroll() ml.Invalidate() } @@ -266,25 +267,40 @@ func (ml *MessageList) Selected() *models.MessageInfo { func (ml *MessageList) Select(index int) { store := ml.Store() store.Select(index) - ml.Scroll() + ml.Invalidate() } -func (ml *MessageList) Scroll() { +func (ml *MessageList) ensureScroll() { store := ml.Store() - if store == nil || len(store.Uids()) == 0 { return } - if ml.Height() != 0 { - // I'm too lazy to do the math right now - for store.SelectedIndex()-ml.scroll >= ml.Height() { - ml.scroll += 1 - } - for store.SelectedIndex()-ml.scroll < 0 { - ml.scroll -= 1 + + h := ml.Height() + + maxScroll := len(store.Uids()) - h + if maxScroll < 0 { + maxScroll = 0 + } + + selectedIndex := store.SelectedIndex() + + if selectedIndex >= ml.scroll && selectedIndex < ml.scroll+h { + if ml.scroll > maxScroll { + ml.scroll = maxScroll } + return + } + + if selectedIndex >= ml.scroll+h { + ml.scroll = selectedIndex - h + 1 + } else if selectedIndex < ml.scroll { + ml.scroll = selectedIndex + } + + if ml.scroll > maxScroll { + ml.scroll = maxScroll } - ml.Invalidate() } func (ml *MessageList) drawEmptyMessage(ctx *ui.Context) { |