summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-02-25 08:32:46 +1100
committerJesse Duffield <jessedduffield@gmail.com>2020-02-25 08:41:53 +1100
commit91de559f15167ffd28ca274c96b9cfbf54f92fcd (patch)
tree6cc44c09ce40a15a9da066c2d568863c05dde90b
parent52b5a6410c33557f754c4a6cd3ce0c69220dc780 (diff)
add half and fullscreen modesv0.15
-rw-r--r--docs/Config.md2
-rw-r--r--pkg/config/app_config.go2
-rw-r--r--pkg/gui/gui.go180
-rw-r--r--pkg/gui/keybindings.go14
-rw-r--r--pkg/i18n/english.go6
-rw-r--r--pkg/utils/utils.go26
6 files changed, 172 insertions, 58 deletions
diff --git a/docs/Config.md b/docs/Config.md
index b167750c5..d255ef1b9 100644
--- a/docs/Config.md
+++ b/docs/Config.md
@@ -75,6 +75,8 @@ Default path for the config file:
createPatchOptionsMenu: '<c-p>'
nextTab: ']'
prevTab: '['
+ nextScreenMode: '+'
+ prevScreenMode: '_'
status:
checkForUpdate: 'u'
recentRepos: '<enter>'
diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go
index a0de1fb4e..2ed84b8e4 100644
--- a/pkg/config/app_config.go
+++ b/pkg/config/app_config.go
@@ -308,6 +308,8 @@ keybinding:
createPatchOptionsMenu: '<c-p>'
nextTab: ']'
prevTab: '['
+ nextScreenMode: '+'
+ prevScreenMode: '_'
status:
checkForUpdate: 'u'
recentRepos: '<enter>'
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 0a0dbe204..f04032fb5 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -33,6 +33,12 @@ import (
"github.com/sirupsen/logrus"
)
+const (
+ SCREEN_NORMAL int = iota
+ SCREEN_HALF
+ SCREEN_FULL
+)
+
const StartupPopupVersion = 1
// OverlappingEdges determines if panel edges overlap
@@ -202,6 +208,8 @@ type guiState struct {
IsRefreshingFiles bool
RefreshingFilesMutex sync.Mutex
Searching searchingState
+ ScreenMode int
+ SideView *gocui.View
}
// for now the split view will always be on
@@ -236,6 +244,8 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
},
Status: &statusPanelState{},
},
+ ScreenMode: SCREEN_NORMAL,
+ SideView: nil,
}
gui := &Gui{
@@ -257,6 +267,18 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
return gui, nil
}
+func (gui *Gui) nextScreenMode(g *gocui.Gui, v *gocui.View) error {
+ gui.State.ScreenMode = utils.NextIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
+
+ return nil
+}
+
+func (gui *Gui) prevScreenMode(g *gocui.Gui, v *gocui.View) error {
+ gui.State.ScreenMode = utils.PrevIntInCycle([]int{SCREEN_NORMAL, SCREEN_HALF, SCREEN_FULL}, gui.State.ScreenMode)
+
+ return nil
+}
+
func (gui *Gui) scrollUpView(viewName string) error {
mainView, _ := gui.g.View(viewName)
ox, oy := mainView.Origin()
@@ -379,6 +401,75 @@ func (gui *Gui) onFocus(v *gocui.View) error {
return nil
}
+func (gui *Gui) getViewHeights() map[string]int {
+ currView := gui.g.CurrentView()
+ currentCyclebleView := gui.State.PreviousView
+ if currView != nil {
+ viewName := currView.Name()
+ usePreviousView := true
+ for _, view := range cyclableViews {
+ if view == viewName {
+ currentCyclebleView = viewName
+ usePreviousView = false
+ break
+ }
+ }
+ if usePreviousView {
+ currentCyclebleView = gui.State.PreviousView
+ }
+ }
+
+ // unfortunate result of the fact that these are separate views, have to map explicitly
+ if currentCyclebleView == "commitFiles" {
+ currentCyclebleView = "commits"
+ }
+
+ _, height := gui.g.Size()
+
+ if gui.State.ScreenMode == SCREEN_FULL || gui.State.ScreenMode == SCREEN_HALF {
+ vHeights := map[string]int{
+ "status": 0,
+ "files": 0,
+ "branches": 0,
+ "commits": 0,
+ "stash": 0,
+ "options": 0,
+ }
+ vHeights[currentCyclebleView] = height - 1
+ return vHeights
+ }
+
+ usableSpace := height - 7
+ extraSpace := usableSpace - (usableSpace/3)*3
+
+ if height >= 28 {
+ return map[string]int{
+ "status": 3,
+ "files": (usableSpace / 3) + extraSpace,
+ "branches": usableSpace / 3,
+ "commits": usableSpace / 3,
+ "stash": 3,
+ "options": 1,
+ }
+ }
+
+ defaultHeight := 3
+ if height < 21 {
+ defaultHeight = 1
+ }
+ vHeights := map[string]int{
+ "status": defaultHeight,
+ "files": defaultHeight,
+ "branches": defaultHeight,
+ "commits": defaultHeight,
+ "stash": defaultHeight,
+ "options": defaultHeight,
+ }
+ vHeights[currentCyclebleView] = height - defaultHeight*4 - 1
+
+ return vHeights
+}
+
// layout is called for every screen re-render e.g. when the screen is resized
func (gui *Gui) layout(g *gocui.Gui) error {
g.Highlight = true
@@ -405,50 +496,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
return nil
}
- currView := gui.g.CurrentView()
- currentCyclebleView := gui.State.PreviousView
- if currView != nil {
- viewName := currView.Name()
- usePreviouseView := true
- for _, view := range cyclableViews {
- if view == viewName {
- currentCyclebleView = viewName
- usePreviouseView = false
- break
- }
- }
- if usePreviouseView {
- currentCyclebleView = gui.State.PreviousView
- }
- }
-
- usableSpace := height - 7
- extraSpace := usableSpace - (usableSpace/3)*3
-
- vHeights := map[string]int{
- "status": 3,
- "files": (usableSpace / 3) + extraSpace,
- "branches": usableSpace / 3,
- "commits": usableSpace / 3,
- "stash": 3,
- "options": 1,
- }
-
- if height < 28 {
- defaultHeight := 3
- if height < 21 {
- defaultHeight = 1
- }
- vHeights = map[string]int{
- "status": defaultHeight,
- "files": defaultHeight,
- "branches": defaultHeight,
- "commits": defaultHeight,
- "stash": defaultHeight,
- "options": defaultHeight,
- }
- vHeights[currentCyclebleView] = height - defaultHeight*4 - 1
- }
+ vHeights := gui.getViewHeights()
optionsVersionBoundary := width - max(len(utils.Decolorise(information)), 1)
@@ -458,29 +506,45 @@ func (gui *Gui) layout(g *gocui.Gui) error {
appStatusOptionsBoundary = len(appStatus) + 2
}
- panelSpacing := 1
- if OverlappingEdges {
- panelSpacing = 0
- }
-
_, _ = g.SetViewOnBottom("limit")
g.DeleteView("limit")
textColor := theme.GocuiDefaultTextColor
- leftSideWidth := width / 3
+ var leftSideWidth int
+ switch gui.State.ScreenMode {
+ case SCREEN_NORMAL:
+ leftSideWidth = width / 3
+ case SCREEN_HALF:
+ leftSideWidth = width / 2
+ case SCREEN_FULL:
+ currentView := gui.g.CurrentView()
+ if currentView != nil && currentView.Name() == "main" {
+ leftSideWidth = 0
+ } else {
+ leftSideWidth = width - 1
+ }
+ }
+
panelSplitX := width - 1
+ mainPanelLeft := leftSideWidth + 1
mainPanelRight := width - 1
secondaryPanelLeft := width - 1
secondaryPanelTop := 0
mainPanelBottom := height - 2
if gui.State.SplitMainPanel {
- if width < 220 {
+ if gui.State.ScreenMode == SCREEN_FULL {
+ mainPanelLeft = 0
+ panelSplitX = width/2 - 4
+ mainPanelRight = panelSplitX
+ secondaryPanelLeft = panelSplitX + 1
+ } else if width < 220 {
mainPanelBottom = height/2 - 1
secondaryPanelTop = mainPanelBottom + 1
secondaryPanelLeft = leftSideWidth + 1
} else {
units := 5
leftSideWidth = width / units
+ mainPanelLeft = leftSideWidth + 1
panelSplitX = (1 + ((units - 1) / 2)) * width / units
mainPanelRight = panelSplitX
secondaryPanelLeft = panelSplitX + 1
@@ -510,7 +574,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
}
}
- v, err := g.SetView(main, leftSideWidth+panelSpacing, 0, mainPanelRight, mainPanelBottom, gocui.LEFT)
+ v, err := g.SetView(main, mainPanelLeft, 0, mainPanelRight, mainPanelBottom, gocui.LEFT)
if err != nil {
if err.Error() != "unknown view" {
return err
@@ -519,16 +583,15 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.Wrap = true
v.FgColor = textColor
v.IgnoreCarriageReturns = true
- v.SetOnSelectItem(gui.onSelectItemWrapper(func(selectedLine int) error {
- return nil
- }))
}
- hiddenViewOffset := 0
+ hiddenViewOffset := 9999
+
+ hiddenSecondaryPanelOffset := 0
if !gui.State.SplitMainPanel {
- hiddenViewOffset = 9999
+ hiddenSecondaryPanelOffset = hiddenViewOffset
}
- secondaryView, err := g.SetView(secondary, secondaryPanelLeft+hiddenViewOffset, hiddenViewOffset+secondaryPanelTop, width-1+hiddenViewOffset, height-2+hiddenViewOffset, gocui.LEFT)
+ secondaryView, err := g.SetView(secondary, secondaryPanelLeft+hiddenSecondaryPanelOffset, hiddenSecondaryPanelOffset+secondaryPanelTop, width-1+hiddenSecondaryPanelOffset, height-2+hiddenSecondaryPanelOffset, gocui.LEFT)
if err != nil {
if err.Error() != "unknown view" {
return err
@@ -577,6 +640,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
v.Title = gui.Tr.SLocalize("CommitFiles")
v.FgColor = textColor
v.SetOnSelectItem(gui.onSelectItemWrapper(gui.onCommitFilesPanelSearchSelect))
+ v.ContainsList = true
}
commitsView, err := g.SetViewBeneath("commits", "branches", vHeights["commits"])
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index d0820e066..d3a360874 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -318,6 +318,20 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Description: gui.Tr.SLocalize("EditConfig"),
},
{
+ ViewName: "",
+ Key: gui.getKey("universal.nextScreenMode"),
+ Modifier: gocui.ModNone,
+ Handler: gui.nextScreenMode,
+ Description: gui.Tr.SLocalize("nextScreenMode"),
+ },
+ {
+ ViewName: "",
+ Key: gui.getKey("universal.prevScreenMode"),
+ Modifier: gocui.ModNone,
+ Handler: gui.prevScreenMode,
+ Description: gui.Tr.SLocalize("prevScreenMode"),
+ },
+ {
ViewName: "status",
Key: gui.getKey("universal.openFile"),
Modifier: gocui.ModNone,
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index b60e914db..2c6fed0af 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -945,6 +945,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "viewResetToUpstreamOptions",
Other: "view upstream reset options",
+ }, &i18n.Message{
+ ID: "nextScreenMode",
+ Other: "next screen mode (normal/half/fullscreen)",
+ }, &i18n.Message{
+ ID: "prevScreenMode",
+ Other: "prev screen mode",
},
)
}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 1b69a9a5b..42529776f 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -322,3 +322,29 @@ func ModuloWithWrap(n, max int) int {
return n
}
}
+
+// NextIntInCycle returns the next int in a slice, returning to the first index if we've reached the end
+func NextIntInCycle(sl []int, current int) int {
+ for i, val := range sl {
+ if val == current {
+ if i == len(sl)-1 {
+ return sl[0]
+ }
+ return sl[i+1]
+ }
+ }
+ return sl[0]
+}
+
+// PrevIntInCycle returns the prev int in a slice, returning to the first index if we've reached the end
+func PrevIntInCycle(sl []int, current int) int {
+ for i, val := range sl {
+ if val == current {
+ if i > 0 {
+ return sl[i-1]
+ }
+ return sl[len(sl)-1]
+ }
+ }
+ return sl[len(sl)-1]
+}