Skip to content

Commit

Permalink
some more changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed May 17, 2020
1 parent ed9a08f commit e3375fb
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 128 deletions.
183 changes: 89 additions & 94 deletions pkg/gui/arrangement.go
Original file line number Diff line number Diff line change
@@ -1,41 +1,8 @@
package gui

func (gui *Gui) getViewDimensions() map[string]dimensions {
// things to consider:
// current cyclable view
// three modes: normal, squashed, portrait
// three fullscreen modes: regular, half, full
// half/full ignored squashed but not portrait where the orientation is just swapped
// height (for squashing)
// width (for portrait mode)
// let's start by saying squashing and portrait mode are mutuall exclusive. If you're in portrait mode and you end up in a squashed state you're pretty much fucked either way.
// having said that, half and fullscreen mode can be combined with the other two. Fullscreen is gonna be the same across all of the options. Half mode will just be split vertically rather than horizontally for

// need

// we'll start assuming normal mode
// in normal mode pick the split between the main panel and the side panels, then give every cyclablable view roughly equal height.

// the options panel has 1 height always

// so our views are:
// "status"
// "files"
// "branches"
// "commits"
// "stash"
// "main"
// "commitFiles"
// "secondary"

// would be good to have a way of describing this programmatically, like with html:

// <box>

width, height := gui.g.Size()

portraitMode := width <= 84 && height > 50

main := "main"
secondary := "secondary"
if gui.State.Panels.LineByLine != nil && gui.State.Panels.LineByLine.SecondaryFocused {
Expand All @@ -56,9 +23,74 @@ func (gui *Gui) getViewDimensions() map[string]dimensions {
})
}

// 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
}
currentViewName := gui.currentViewName()
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
}
}

sidePanelsDirection := COLUMN
portraitMode := width <= 84 && height > 50
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 {
if width < 160 && height > 30 { // 2 80 character width panels
return ROW
} else {
return COLUMN
}
},
direction: COLUMN,
weight: mainSectionWeight,
children: mainSectionChildren,
},
},
},
// TODO: actually handle options here. Currently we're just hard-coding it to be set on the bottom row in our layout function given that we need some custom logic to have it share space with other views on that row.
{
viewName: "options",
size: 1,
},
},
}

return gui.arrangeViews(root, 0, 0, width, height)
}

func (gui *Gui) sidePanelChildren(width int, height int) []*box {
currentCyclableViewName := gui.currentCyclableViewName()

var sideSectionChildren []*box
if gui.State.ScreenMode == SCREEN_FULL || gui.State.ScreenMode == SCREEN_HALF {
fullHeightBox := func(viewName string) *box {
if viewName == currentCyclableViewName {
Expand All @@ -74,15 +106,15 @@ func (gui *Gui) getViewDimensions() map[string]dimensions {
}
}

sideSectionChildren = []*box{
return []*box{
fullHeightBox("status"),
fullHeightBox("files"),
fullHeightBox("branches"),
fullHeightBox("commits"),
fullHeightBox("stash"),
}
} else if height >= 28 && !portraitMode {
sideSectionChildren = []*box{
} else if height >= 28 {
return []*box{
{
viewName: "status",
size: 3,
Expand Down Expand Up @@ -124,75 +156,38 @@ func (gui *Gui) getViewDimensions() map[string]dimensions {
}
}

sideSectionChildren = []*box{
return []*box{
squashedSidePanelBox("status"),
squashedSidePanelBox("files"),
squashedSidePanelBox("branches"),
squashedSidePanelBox("commits"),
squashedSidePanelBox("stash"),
}
}
}

// 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
}
currentViewName := gui.currentViewName()
if currentViewName == "main" {
if gui.State.ScreenMode == SCREEN_HALF || gui.State.ScreenMode == SCREEN_FULL {
sideSectionWeight = 0
func (gui *Gui) currentCyclableViewName() string {
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
}
}
} else {
if gui.State.ScreenMode == SCREEN_HALF {
mainSectionWeight = 1
} else if gui.State.ScreenMode == SCREEN_FULL {
mainSectionWeight = 0
if usePreviousView {
currentCyclebleView = gui.State.PreviousView
}
}

sidePanelsDirection := COLUMN
if portraitMode {
sidePanelsDirection = ROW
}

root := &box{
direction: ROW,
children: []*box{
{
direction: sidePanelsDirection,
weight: 1,
children: []*box{
{
direction: ROW,
weight: sideSectionWeight,
children: sideSectionChildren,
},
{
conditionalDirection: func(width int, _height int) int {
if width < 160 && height > 30 { // 2 80 character width panels
return ROW
} else {
return COLUMN
}
},
direction: COLUMN,
weight: mainSectionWeight,
children: mainSectionChildren,
},
},
},
// TODO: actually handle options here. Currently we're just hard-coding it to be set on the bottom row in our layout function given that we need some custom logic to have it share space with other views on that row.
{
viewName: "options",
size: 1,
},
},
// unfortunate result of the fact that these are separate views, have to map explicitly
if currentCyclebleView == "commitFiles" {
return "commits"
}

return gui.layoutViews(root, 0, 0, width, height)
return currentCyclebleView
}
15 changes: 7 additions & 8 deletions pkg/gui/dimensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ func (b *box) getChildren(width int, height int) []*box {
return b.children
}

func (gui *Gui) layoutViews(root *box, x0, y0, width, height int) map[string]dimensions {
gui.Log.Warn(x0, y0, width, height)

if len(root.children) == 0 {
func (gui *Gui) arrangeViews(root *box, x0, y0, width, height int) map[string]dimensions {
children := root.getChildren(width, height)
if len(children) == 0 {
// leaf node
if root.viewName != "" {
dimensionsForView := dimensions{x0: x0, y0: y0, x1: x0 + width - 1, y1: y0 + height - 1}
Expand All @@ -79,7 +78,7 @@ func (gui *Gui) layoutViews(root *box, x0, y0, width, height int) map[string]dim
// work out size taken up by children
reservedSize := 0
totalWeight := 0
for _, child := range root.children {
for _, child := range children {
// assuming either size or weight are non-zero
reservedSize += child.size
totalWeight += child.weight
Expand All @@ -99,7 +98,7 @@ func (gui *Gui) layoutViews(root *box, x0, y0, width, height int) map[string]dim

result := map[string]dimensions{}
offset := 0
for _, child := range root.children {
for _, child := range children {
var boxSize int
if child.isStatic() {
boxSize = child.size
Expand All @@ -113,9 +112,9 @@ func (gui *Gui) layoutViews(root *box, x0, y0, width, height int) map[string]dim

var resultForChild map[string]dimensions
if direction == COLUMN {
resultForChild = gui.layoutViews(child, x0+offset, y0, boxSize, height)
resultForChild = gui.arrangeViews(child, x0+offset, y0, boxSize, height)
} else {
resultForChild = gui.layoutViews(child, x0, y0+offset, width, boxSize)
resultForChild = gui.arrangeViews(child, x0, y0+offset, width, boxSize)
}

result = gui.mergeDimensionMaps(result, resultForChild)
Expand Down
26 changes: 0 additions & 26 deletions pkg/gui/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,32 +71,6 @@ func (gui *Gui) onFocus(v *gocui.View) error {
return nil
}

func (gui *Gui) currentCyclableViewName() string {
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" {
return "commits"
}

return currentCyclebleView
}

// 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
Expand Down

0 comments on commit e3375fb

Please sign in to comment.