diff options
Diffstat (limited to 'pkg/gui/gui.go')
-rw-r--r-- | pkg/gui/gui.go | 180 |
1 files changed, 122 insertions, 58 deletions
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"]) |