diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2020-08-19 19:07:14 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2020-08-23 14:29:18 +1000 |
commit | 2b812b01e9d80409a0bf212eb7208dcdd6f5c974 (patch) | |
tree | 4c1b0cd51ba170c92bc38410ec6005373736720b /pkg/gui/context.go | |
parent | 2f5d5034dbe4523c44faa58ba6f30c2fef06c128 (diff) |
more standardisation of rendering
Diffstat (limited to 'pkg/gui/context.go')
-rw-r--r-- | pkg/gui/context.go | 343 |
1 files changed, 193 insertions, 150 deletions
diff --git a/pkg/gui/context.go b/pkg/gui/context.go index a54625306..559cfa108 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -98,6 +98,164 @@ type ContextTree struct { Search SimpleContextNode } +func (gui *Gui) allContexts() []Context { + return []Context{ + gui.Contexts.Status.Context, + gui.Contexts.Files.Context, + gui.Contexts.Branches.Context, + gui.Contexts.Remotes.Context, + gui.Contexts.Remotes.Branches.Context, + gui.Contexts.BranchCommits.Context, + gui.Contexts.BranchCommits.Files.Context, + gui.Contexts.ReflogCommits.Context, + gui.Contexts.Stash.Context, + gui.Contexts.Menu.Context, + gui.Contexts.Confirmation.Context, + gui.Contexts.Credentials.Context, + gui.Contexts.CommitMessage.Context, + gui.Contexts.Normal.Context, + gui.Contexts.Staging.Context, + gui.Contexts.Merging.Context, + gui.Contexts.PatchBuilding.Context, + } +} + +func (gui *Gui) contextTree() ContextTree { + return ContextTree{ + Status: SimpleContextNode{ + Context: BasicContext{ + OnFocus: gui.handleStatusSelect, + Kind: SIDE_CONTEXT, + ViewName: "status", + Key: "status", + }, + }, + Files: SimpleContextNode{ + Context: gui.filesListContext(), + }, + Menu: SimpleContextNode{ + Context: gui.menuListContext(), + }, + Remotes: RemotesContextNode{ + Context: gui.remotesListContext(), + Branches: SimpleContextNode{ + Context: gui.remoteBranchesListContext(), + }, + }, + BranchCommits: CommitsContextNode{ + Context: gui.branchCommitsListContext(), + Files: SimpleContextNode{ + Context: gui.commitFilesListContext(), + }, + }, + ReflogCommits: SimpleContextNode{ + Context: gui.reflogCommitsListContext(), + }, + Branches: SimpleContextNode{ + Context: gui.branchesListContext(), + }, + Tags: SimpleContextNode{ + Context: gui.tagsListContext(), + }, + Stash: SimpleContextNode{ + Context: gui.stashListContext(), + }, + Normal: SimpleContextNode{ + Context: BasicContext{ + OnFocus: func() error { + return nil // TODO: should we do something here? We should allow for scrolling the panel + }, + Kind: MAIN_CONTEXT, + ViewName: "main", + Key: "normal", + }, + }, + Staging: SimpleContextNode{ + Context: BasicContext{ + // TODO: think about different situations where this arises + OnFocus: func() error { + return nil + // return gui.refreshStagingPanel(false, -1) + }, + Kind: MAIN_CONTEXT, + ViewName: "main", + Key: "staging", + }, + }, + PatchBuilding: SimpleContextNode{ + Context: BasicContext{ + // TODO: think about different situations where this arises + OnFocus: func() error { + return gui.refreshPatchBuildingPanel(-1) + }, + Kind: MAIN_CONTEXT, + ViewName: "main", + Key: "patch-building", + }, + }, + Merging: SimpleContextNode{ + Context: BasicContext{ + // TODO: think about different situations where this arises + OnFocus: func() error { + return gui.refreshMergePanel() + }, + Kind: MAIN_CONTEXT, + ViewName: "main", + Key: "merging", + }, + }, + Credentials: SimpleContextNode{ + Context: BasicContext{ + OnFocus: func() error { return gui.handleCredentialsViewFocused() }, + Kind: PERSISTENT_POPUP, + ViewName: "credentials", + Key: "credentials", + }, + }, + Confirmation: SimpleContextNode{ + Context: BasicContext{ + OnFocus: func() error { return nil }, + Kind: TEMPORARY_POPUP, + ViewName: "confirmation", + Key: "confirmation", + }, + }, + CommitMessage: SimpleContextNode{ + Context: BasicContext{ + OnFocus: func() error { return gui.handleCommitMessageFocused() }, + Kind: PERSISTENT_POPUP, + ViewName: "commitMessage", + Key: "commit-message", // admittedly awkward to have view names in camelCase and contexts in kebab-case + }, + }, + Search: SimpleContextNode{ + Context: BasicContext{ + OnFocus: func() error { return nil }, + Kind: PERSISTENT_POPUP, + ViewName: "search", + Key: "search", + }, + }, + } +} + +func (gui *Gui) initialViewContextMap() map[string]Context { + return map[string]Context{ + "status": gui.Contexts.Status.Context, + "files": gui.Contexts.Files.Context, + "branches": gui.Contexts.Branches.Context, + "commits": gui.Contexts.BranchCommits.Context, + "commitFiles": gui.Contexts.BranchCommits.Files.Context, + "stash": gui.Contexts.Stash.Context, + "menu": gui.Contexts.Menu.Context, + "confirmation": gui.Contexts.Confirmation.Context, + "credentials": gui.Contexts.Credentials.Context, + "commitMessage": gui.Contexts.CommitMessage.Context, + "main": gui.Contexts.Normal.Context, + "secondary": gui.Contexts.Normal.Context, + } +} + func (gui *Gui) switchContext(c Context) error { gui.g.Update(func(*gocui.Gui) error { // push onto stack @@ -168,14 +326,25 @@ func (gui *Gui) deactivateContext(c Context) error { return nil } -func (gui *Gui) rerenderIfVisible(c Context) error { +// postRefreshUpdate is to be called on a context after the state that it depends on has been refreshed +// if the context's view is set to another context we do nothing. +// if the context's view is the current view we trigger a focus; re-selecting the current item. +func (gui *Gui) postRefreshUpdate(c Context) error { v, err := gui.g.View(c.GetViewName()) if err != nil { return nil } - if v.Context == c.GetKey() { - if err := c.HandleRender(); err != nil { + if v.Context != c.GetKey() { + return nil + } + + if err := c.HandleRender(); err != nil { + return err + } + + if gui.currentViewName() == c.GetViewName() { + if err := c.HandleFocus(); err != nil { return err } } @@ -200,6 +369,8 @@ func (gui *Gui) activateContext(c Context) error { } } + gui.setViewAsActiveForWindow(viewName) + if viewName == "main" { gui.changeMainViewsContext(c.GetKey()) } else { @@ -253,142 +424,6 @@ func (gui *Gui) currentContextKey() string { return gui.State.ContextStack[len(gui.State.ContextStack)-1].GetKey() } -func (gui *Gui) contextTree() ContextTree { - return ContextTree{ - Status: SimpleContextNode{ - Context: BasicContext{ - OnFocus: gui.handleStatusSelect, - Kind: SIDE_CONTEXT, - ViewName: "status", - Key: "status", - }, - }, - Files: SimpleContextNode{ - Context: gui.filesListContext(), - }, - Menu: SimpleContextNode{ - Context: gui.menuListContext(), - }, - Remotes: RemotesContextNode{ - Context: gui.remotesListContext(), - Branches: SimpleContextNode{ - Context: gui.remoteBranchesListContext(), - }, - }, - BranchCommits: CommitsContextNode{ - Context: gui.branchCommitsListContext(), - Files: SimpleContextNode{ - Context: gui.commitFilesListContext(), - }, - }, - ReflogCommits: SimpleContextNode{ - Context: gui.reflogCommitsListContext(), - }, - Branches: SimpleContextNode{ - Context: gui.branchesListContext(), - }, - Tags: SimpleContextNode{ - Context: gui.tagsListContext(), - }, - Stash: SimpleContextNode{ - Context: gui.stashListContext(), - }, - Normal: SimpleContextNode{ - Context: BasicContext{ - OnFocus: func() error { - return nil // TODO: should we do something here? We should allow for scrolling the panel - }, - Kind: MAIN_CONTEXT, - ViewName: "main", - Key: "normal", - }, - }, - Staging: SimpleContextNode{ - Context: BasicContext{ - // TODO: think about different situations where this arises - OnFocus: func() error { - return nil - // return gui.refreshStagingPanel(false, -1) - }, - Kind: MAIN_CONTEXT, - ViewName: "main", - Key: "staging", - }, - }, - PatchBuilding: SimpleContextNode{ - Context: BasicContext{ - // TODO: think about different situations where this arises - OnFocus: func() error { - return gui.refreshPatchBuildingPanel(-1) - }, - Kind: MAIN_CONTEXT, - ViewName: "main", - Key: "patch-building", - }, - }, - Merging: SimpleContextNode{ - Context: BasicContext{ - // TODO: think about different situations where this arises - OnFocus: func() error { - return gui.refreshMergePanel() - }, - Kind: MAIN_CONTEXT, - ViewName: "main", - Key: "merging", - }, - }, - Credentials: SimpleContextNode{ - Context: BasicContext{ - OnFocus: func() error { return gui.handleCredentialsViewFocused() }, - Kind: PERSISTENT_POPUP, - ViewName: "credentials", - Key: "credentials", - }, - }, - Confirmation: SimpleContextNode{ - Context: BasicContext{ - OnFocus: func() error { return nil }, - Kind: TEMPORARY_POPUP, - ViewName: "confirmation", - Key: "confirmation", - }, - }, - CommitMessage: SimpleContextNode{ - Context: BasicContext{ - OnFocus: func() error { return gui.handleCommitMessageFocused() }, - Kind: PERSISTENT_POPUP, - ViewName: "commitMessage", - Key: "commit-message", // admittedly awkward to have view names in camelCase and contexts in kebab-case - }, - }, - Search: SimpleContextNode{ - Context: BasicContext{ - OnFocus: func() error { return nil }, - Kind: PERSISTENT_POPUP, - ViewName: "search", - Key: "search", - }, - }, - } -} - -func (gui *Gui) initialViewContextMap() map[string]Context { - return map[string]Context{ - "status": gui.Contexts.Status.Context, - "files": gui.Contexts.Files.Context, - "branches": gui.Contexts.Branches.Context, - "commits": gui.Contexts.BranchCommits.Context, - "commitFiles": gui.Contexts.BranchCommits.Files.Context, - "stash": gui.Contexts.Stash.Context, - "menu": gui.Contexts.Menu.Context, - "confirmation": gui.Contexts.Confirmation.Context, - "credentials": gui.Contexts.Credentials.Context, - "commitMessage": gui.Contexts.CommitMessage.Context, - "main": gui.Contexts.Normal.Context, - "secondary": gui.Contexts.Normal.Context, - } -} - func (gui *Gui) setInitialViewContexts() { // arguably we should only have our ViewContextMap and we should do away with // contexts on views, or vice versa @@ -417,9 +452,6 @@ func (gui *Gui) getFocusLayout() func(g *gocui.Gui) error { return err } - if err := gui.onViewFocus(newView); err != nil { - return err - } previousView = newView } return nil @@ -449,12 +481,6 @@ func (gui *Gui) onViewFocusLost(v *gocui.View, newView *gocui.View) error { return nil } -func (gui *Gui) onViewFocus(newView *gocui.View) error { - gui.setViewAsActiveForWindow(newView.Name()) - - return nil -} - // changeContext is a helper function for when we want to change a 'main' context // which currently just means a context that affects both the main and secondary views // other views can have their context changed directly but this function helps @@ -553,7 +579,24 @@ type tabContext struct { contexts []Context } -func (gui *Gui) handleContextRefresh(c Context) { - // if context is not the current context of it's view, return +func (gui *Gui) contextForContextKey(contextKey string) Context { + for _, context := range gui.allContexts() { + if context.GetKey() == contextKey { + return context + } + } + + panic(fmt.Sprintf("context now found for key %s", contextKey)) +} + +func (gui *Gui) rerenderView(viewName string) error { + v, err := gui.g.View(viewName) + if err != nil { + return nil + } + + contextKey := v.Context + context := gui.contextForContextKey(contextKey) + return context.HandleRender() } |