diff options
author | Stefan Haller <stefan@haller-berlin.de> | 2023-10-14 12:45:13 +0200 |
---|---|---|
committer | Stefan Haller <stefan@haller-berlin.de> | 2023-10-16 09:03:07 +0200 |
commit | d5b4f7bb3e16d8e06fdcc9a53a4ec393ab4bf1b1 (patch) | |
tree | 11e0902b2c1d7c3691cba457bad1c63f08fdeb77 /pkg/gui | |
parent | 3cee4de39ca120ee207fb8f5cc82dcdb0517e324 (diff) |
Rerender certain views when their width changes
Situations where a view's width changes:
- changing screen modes
- enter staging or patch building
- resizing the terminal window
For the first of these we currently have special code to force a rerender, since
some views render different content depending on whether they are in full-screen
mode. We'll be able to remove that code now, since this new generic mechanism
takes care of that too.
But we will need this more general mechanism for cases where views truncate
their content to the view width; we'll add one example for that later in this
branch.
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/context/base_context.go | 53 | ||||
-rw-r--r-- | pkg/gui/context/branches_context.go | 11 | ||||
-rw-r--r-- | pkg/gui/context/local_commits_context.go | 11 | ||||
-rw-r--r-- | pkg/gui/context/reflog_commits_context.go | 11 | ||||
-rw-r--r-- | pkg/gui/context/remote_branches_context.go | 13 | ||||
-rw-r--r-- | pkg/gui/context/sub_commits_context.go | 13 | ||||
-rw-r--r-- | pkg/gui/layout.go | 25 | ||||
-rw-r--r-- | pkg/gui/types/context.go | 3 |
8 files changed, 88 insertions, 52 deletions
diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go index 421476368..acece1994 100644 --- a/pkg/gui/context/base_context.go +++ b/pkg/gui/context/base_context.go @@ -20,10 +20,11 @@ type BaseContext struct { onFocusFn onFocusFn onFocusLostFn onFocusLostFn - focusable bool - transient bool - hasControlledBounds bool - highlightOnFocus bool + focusable bool + transient bool + hasControlledBounds bool + needsRerenderOnWidthChange bool + highlightOnFocus bool *ParentContextMgr } @@ -36,14 +37,15 @@ type ( var _ types.IBaseContext = &BaseContext{} type NewBaseContextOpts struct { - Kind types.ContextKind - Key types.ContextKey - View *gocui.View - WindowName string - Focusable bool - Transient bool - HasUncontrolledBounds bool // negating for the sake of making false the default - HighlightOnFocus bool + Kind types.ContextKind + Key types.ContextKey + View *gocui.View + WindowName string + Focusable bool + Transient bool + HasUncontrolledBounds bool // negating for the sake of making false the default + HighlightOnFocus bool + NeedsRerenderOnWidthChange bool OnGetOptionsMap func() map[string]string } @@ -54,17 +56,18 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext { hasControlledBounds := !opts.HasUncontrolledBounds return &BaseContext{ - kind: opts.Kind, - key: opts.Key, - view: opts.View, - windowName: opts.WindowName, - onGetOptionsMap: opts.OnGetOptionsMap, - focusable: opts.Focusable, - transient: opts.Transient, - hasControlledBounds: hasControlledBounds, - highlightOnFocus: opts.HighlightOnFocus, - ParentContextMgr: &ParentContextMgr{}, - viewTrait: viewTrait, + kind: opts.Kind, + key: opts.Key, + view: opts.View, + windowName: opts.WindowName, + onGetOptionsMap: opts.OnGetOptionsMap, + focusable: opts.Focusable, + transient: opts.Transient, + hasControlledBounds: hasControlledBounds, + highlightOnFocus: opts.HighlightOnFocus, + needsRerenderOnWidthChange: opts.NeedsRerenderOnWidthChange, + ParentContextMgr: &ParentContextMgr{}, + viewTrait: viewTrait, } } @@ -190,6 +193,10 @@ func (self *BaseContext) HasControlledBounds() bool { return self.hasControlledBounds } +func (self *BaseContext) NeedsRerenderOnWidthChange() bool { + return self.needsRerenderOnWidthChange +} + func (self *BaseContext) Title() string { return "" } diff --git a/pkg/gui/context/branches_context.go b/pkg/gui/context/branches_context.go index 68324d020..79dfc7adc 100644 --- a/pkg/gui/context/branches_context.go +++ b/pkg/gui/context/branches_context.go @@ -40,11 +40,12 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext { FilteredListViewModel: viewModel, ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().Branches, - WindowName: "branches", - Key: LOCAL_BRANCHES_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().Branches, + WindowName: "branches", + Key: LOCAL_BRANCHES_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index fa91e6a79..e0172638d 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -68,11 +68,12 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext { SearchTrait: NewSearchTrait(c), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().Commits, - WindowName: "commits", - Key: LOCAL_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().Commits, + WindowName: "commits", + Key: LOCAL_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/reflog_commits_context.go b/pkg/gui/context/reflog_commits_context.go index a90507e86..8dc52cde7 100644 --- a/pkg/gui/context/reflog_commits_context.go +++ b/pkg/gui/context/reflog_commits_context.go @@ -43,11 +43,12 @@ func NewReflogCommitsContext(c *ContextCommon) *ReflogCommitsContext { FilteredListViewModel: viewModel, ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().ReflogCommits, - WindowName: "commits", - Key: REFLOG_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().ReflogCommits, + WindowName: "commits", + Key: REFLOG_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/remote_branches_context.go b/pkg/gui/context/remote_branches_context.go index 144a8c369..82d37b613 100644 --- a/pkg/gui/context/remote_branches_context.go +++ b/pkg/gui/context/remote_branches_context.go @@ -36,12 +36,13 @@ func NewRemoteBranchesContext( DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.RemoteBranchesDynamicTitle), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().RemoteBranches, - WindowName: "branches", - Key: REMOTE_BRANCHES_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, - Transient: true, + View: c.Views().RemoteBranches, + WindowName: "branches", + Key: REMOTE_BRANCHES_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + Transient: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 7bf34d190..79b0d9781 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -115,12 +115,13 @@ func NewSubCommitsContext( DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.SubCommitsDynamicTitle), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().SubCommits, - WindowName: "branches", - Key: SUB_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, - Transient: true, + View: c.Views().SubCommits, + WindowName: "branches", + Key: SUB_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + Transient: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 2f6e21b73..7b43f8aaa 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -44,8 +44,13 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } + contextsToRerender := []types.Context{} + // we assume that the view has already been created. - setViewFromDimensions := func(viewName string, windowName string) (*gocui.View, error) { + setViewFromDimensions := func(context types.Context) (*gocui.View, error) { + viewName := context.GetViewName() + windowName := context.GetWindowName() + dimensionsObj, ok := viewDimensions[windowName] view, err := g.View(viewName) @@ -67,6 +72,16 @@ func (gui *Gui) layout(g *gocui.Gui) error { if view.Frame { frameOffset = 0 } + + if context.NeedsRerenderOnWidthChange() { + // view.Width() returns the width -1 for some reason + oldWidth := view.Width() + 1 + newWidth := dimensionsObj.X1 - dimensionsObj.X0 + 2*frameOffset + if oldWidth != newWidth { + contextsToRerender = append(contextsToRerender, context) + } + } + _, err = g.SetView( viewName, dimensionsObj.X0-frameOffset, @@ -85,7 +100,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { continue } - _, err := setViewFromDimensions(context.GetViewName(), context.GetWindowName()) + _, err := setViewFromDimensions(context) if err != nil && !gocui.IsUnknownView(err) { return err } @@ -146,6 +161,12 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } + for _, context := range contextsToRerender { + if err := context.HandleRender(); err != nil { + return err + } + } + // here is a good place log some stuff // if you run `lazygit --logs` // this will let you see these branches as prettified json diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index c47945aee..aca694228 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -60,6 +60,9 @@ type IBaseContext interface { // determined independently. HasControlledBounds() bool + // true if the view needs to be rerendered when its width changes + NeedsRerenderOnWidthChange() bool + // returns the desired title for the view upon activation. If there is no desired title (returns empty string), then // no title will be set Title() string |