1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-18 05:17:55 +02:00
lazygit/pkg/gui/arrangement.go

270 lines
6.2 KiB
Go
Raw Normal View History

2020-05-17 21:32:17 +10:00
package gui
import (
"github.com/jesseduffield/lazygit/pkg/utils"
)
2020-05-18 22:00:07 +10:00
func (gui *Gui) mainSectionChildren() []*box {
currentViewName := gui.currentViewName()
// if we're not in split mode we can just show the one main panel. Likewise if
// the main panel is focused and we're in full-screen mode
if !gui.State.SplitMainPanel || (gui.State.ScreenMode == SCREEN_FULL && currentViewName == "main") {
return []*box{
{
viewName: "main",
weight: 1,
},
}
}
2020-05-17 21:32:17 +10:00
main := "main"
secondary := "secondary"
2020-05-18 22:00:07 +10:00
if gui.secondaryViewFocused() {
// when you think you've focused the secondary view, we've actually just swapped them around in the layout
2020-05-17 21:32:17 +10:00
main, secondary = secondary, main
}
2020-05-18 22:00:07 +10:00
return []*box{
2020-05-17 21:32:17 +10:00
{
viewName: main,
weight: 1,
},
2020-05-18 22:00:07 +10:00
{
2020-05-17 21:32:17 +10:00
viewName: secondary,
weight: 1,
2020-05-18 22:00:07 +10:00
},
2020-05-17 21:32:17 +10:00
}
2020-05-18 22:00:07 +10:00
}
func (gui *Gui) getMidSectionWeights() (int, int) {
currentViewName := gui.currentViewName()
2020-05-17 21:32:17 +10:00
2020-05-17 21:44:59 +10:00
// we originally specified this as a ratio i.e. .20 would correspond to a weight of 1 against 4
sidePanelWidthRatio := gui.Config.GetUserConfig().GetFloat64("gui.sidePanelWidth")
// we could make this better by creating ratios like 2:3 rather than always 1:something
mainSectionWeight := int(1/sidePanelWidthRatio) - 1
sideSectionWeight := 1
if gui.State.SplitMainPanel {
mainSectionWeight = 5 // need to shrink side panel to make way for main panels if side-by-side
}
2020-05-18 22:00:07 +10:00
2020-05-17 21:44:59 +10:00
if currentViewName == "main" {
if gui.State.ScreenMode == SCREEN_HALF || gui.State.ScreenMode == SCREEN_FULL {
sideSectionWeight = 0
}
} else {
if gui.State.ScreenMode == SCREEN_HALF {
mainSectionWeight = 1
} else if gui.State.ScreenMode == SCREEN_FULL {
mainSectionWeight = 0
}
}
2020-05-18 22:00:07 +10:00
return sideSectionWeight, mainSectionWeight
}
func (gui *Gui) infoSectionChildren(informationStr string, appStatus string) []*box {
if gui.State.Searching.isSearching {
return []*box{
{
viewName: "searchPrefix",
size: len(SEARCH_PREFIX),
},
{
viewName: "search",
weight: 1,
},
}
}
result := []*box{}
if len(appStatus) > 0 {
result = append(result,
&box{
viewName: "appStatus",
size: len(appStatus) + len(INFO_SECTION_PADDING),
},
)
}
result = append(result,
[]*box{
{
viewName: "options",
weight: 1,
},
{
viewName: "information",
// unlike appStatus, informationStr has various colors so we need to decolorise before taking the length
size: len(INFO_SECTION_PADDING) + len(utils.Decolorise(informationStr)),
},
}...,
)
return result
}
func (gui *Gui) getViewDimensions(informationStr string, appStatus string) map[string]dimensions {
2020-05-18 22:00:07 +10:00
width, height := gui.g.Size()
sideSectionWeight, mainSectionWeight := gui.getMidSectionWeights()
2020-05-17 21:44:59 +10:00
sidePanelsDirection := COLUMN
portraitMode := width <= 84 && height > 45
2020-05-17 21:44:59 +10:00
if portraitMode {
sidePanelsDirection = ROW
}
root := &box{
direction: ROW,
children: []*box{
{
direction: sidePanelsDirection,
weight: 1,
children: []*box{
{
direction: ROW,
weight: sideSectionWeight,
conditionalChildren: gui.sidePanelChildren,
},
{
conditionalDirection: func(width int, height int) int {
2020-08-12 22:18:03 +10:00
mainPanelSplitMode := gui.Config.GetUserConfig().GetString("gui.mainPanelSplitMode")
switch mainPanelSplitMode {
case "vertical":
2020-05-17 21:44:59 +10:00
return ROW
2020-08-12 22:18:03 +10:00
case "horizontal":
2020-05-17 21:44:59 +10:00
return COLUMN
2020-08-12 22:18:03 +10:00
default:
if width < 160 && height > 30 { // 2 80 character width panels
return ROW
} else {
return COLUMN
}
2020-05-17 21:44:59 +10:00
}
},
direction: COLUMN,
weight: mainSectionWeight,
2020-05-18 22:00:07 +10:00
children: gui.mainSectionChildren(),
2020-05-17 21:44:59 +10:00
},
},
},
{
direction: COLUMN,
size: 1,
children: gui.infoSectionChildren(informationStr, appStatus),
2020-05-17 21:44:59 +10:00
},
},
}
return gui.arrangeViews(root, 0, 0, width, height)
}
func (gui *Gui) sidePanelChildren(width int, height int) []*box {
2020-05-17 21:32:17 +10:00
currentCyclableViewName := gui.currentCyclableViewName()
if gui.State.ScreenMode == SCREEN_FULL || gui.State.ScreenMode == SCREEN_HALF {
fullHeightBox := func(viewName string) *box {
if viewName == currentCyclableViewName {
return &box{
viewName: viewName,
weight: 1,
}
} else {
return &box{
viewName: viewName,
size: 0,
}
}
}
2020-05-17 21:44:59 +10:00
return []*box{
2020-05-17 21:32:17 +10:00
fullHeightBox("status"),
fullHeightBox("files"),
fullHeightBox("branches"),
fullHeightBox("commits"),
fullHeightBox("stash"),
}
2020-05-17 21:44:59 +10:00
} else if height >= 28 {
accordianMode := gui.Config.GetUserConfig().GetBool("gui.expandFocusedSidePanel")
accordianBox := func(defaultBox *box) *box {
if accordianMode && defaultBox.viewName == currentCyclableViewName {
return &box{
viewName: defaultBox.viewName,
weight: 2,
}
}
return defaultBox
}
2020-05-17 21:44:59 +10:00
return []*box{
2020-05-17 21:32:17 +10:00
{
viewName: "status",
size: 3,
},
accordianBox(&box{viewName: "files", weight: 1}),
accordianBox(&box{viewName: "branches", weight: 1}),
accordianBox(&box{viewName: "commits", weight: 1}),
accordianBox(&box{viewName: "stash", size: 3}),
2020-05-17 21:32:17 +10:00
}
} else {
squashedHeight := 1
if height >= 21 {
squashedHeight = 3
}
squashedSidePanelBox := func(viewName string) *box {
if viewName == currentCyclableViewName {
return &box{
viewName: viewName,
weight: 1,
}
} else {
return &box{
viewName: viewName,
size: squashedHeight,
}
}
}
2020-05-17 21:44:59 +10:00
return []*box{
2020-05-17 21:32:17 +10:00
squashedSidePanelBox("status"),
squashedSidePanelBox("files"),
squashedSidePanelBox("branches"),
squashedSidePanelBox("commits"),
squashedSidePanelBox("stash"),
}
}
2020-05-17 21:44:59 +10:00
}
2020-05-17 21:32:17 +10:00
2020-05-17 21:44:59 +10:00
func (gui *Gui) currentCyclableViewName() string {
currView := gui.g.CurrentView()
currentCyclebleView := gui.State.PreviousView
if currView != nil {
viewName := currView.Name()
usePreviousView := true
2020-05-17 21:54:51 +10:00
for _, view := range gui.getCyclableViews() {
2020-05-17 21:44:59 +10:00
if view == viewName {
currentCyclebleView = viewName
usePreviousView = false
break
}
2020-05-17 21:32:17 +10:00
}
2020-05-17 21:44:59 +10:00
if usePreviousView {
currentCyclebleView = gui.State.PreviousView
2020-05-17 21:32:17 +10:00
}
}
2020-05-17 21:44:59 +10:00
// unfortunate result of the fact that these are separate views, have to map explicitly
if currentCyclebleView == "commitFiles" {
return "commits"
2020-05-17 21:32:17 +10:00
}
2020-05-17 21:44:59 +10:00
return currentCyclebleView
2020-05-17 21:32:17 +10:00
}