diff --git a/pkg/gui/presentation/graph/cell.go b/pkg/gui/presentation/graph/cell.go index 618a2149d..5660c5745 100644 --- a/pkg/gui/presentation/graph/cell.go +++ b/pkg/gui/presentation/graph/cell.go @@ -21,17 +21,33 @@ const ( MERGE ) +// How a line that touches the top or bottom edge of a cell runs within it +type verticalLine uint8 + +const ( + noLine verticalLine = iota + // On to the opposite edge, or into the commit symbol + straightLine + // Bends towards the left edge + lineToLeft + // Bends towards the right edge + lineToRight +) + type Cell struct { - up, down, left, right bool - cellType cellType - rightStyle *style.TextStyle - style *style.TextStyle + // The lines that touch the top and bottom edges + up, down verticalLine + // Whether lines touch the left and right edges + left, right bool + // Whether a line passes through from the left edge to the right edge + horizontal bool + cellType cellType + rightStyle *style.TextStyle + style *style.TextStyle } func (cell *Cell) render(writer io.StringWriter) { - up, down, left, right := cell.up, cell.down, cell.left, cell.right - - first, second := getBoxDrawingChars(up, down, left, right) + first, second := getBoxDrawingChars(cell.up != noLine, cell.down != noLine, cell.left, cell.right) var adjustedFirst string switch cell.cellType { case CONNECTION: @@ -98,34 +114,34 @@ func cachedSprint(style style.TextStyle, str string) string { } func (cell *Cell) reset() { - cell.up = false - cell.down = false + cell.up = noLine + cell.down = noLine cell.left = false cell.right = false + cell.horizontal = false } -func (cell *Cell) setUp(style *style.TextStyle) *Cell { - cell.up = true +func (cell *Cell) setUp(style *style.TextStyle, line verticalLine) *Cell { + cell.up = line cell.style = style return cell } -func (cell *Cell) setDown(style *style.TextStyle) *Cell { - cell.down = true +func (cell *Cell) setDown(style *style.TextStyle, line verticalLine) *Cell { + cell.down = line cell.style = style return cell } func (cell *Cell) setLeft(style *style.TextStyle) *Cell { cell.left = true - if !cell.up && !cell.down { + if cell.up == noLine && cell.down == noLine { // vertical trumps left cell.style = style } return cell } -//nolint:unparam func (cell *Cell) setRight(style *style.TextStyle, override bool) *Cell { cell.right = true if cell.rightStyle == nil || override { @@ -134,6 +150,11 @@ func (cell *Cell) setRight(style *style.TextStyle, override bool) *Cell { return cell } +func (cell *Cell) setHorizontal(style *style.TextStyle, overrideRightStyle bool) *Cell { + cell.horizontal = true + return cell.setLeft(style).setRight(style, overrideRightStyle) +} + func (cell *Cell) setStyle(style *style.TextStyle) *Cell { cell.style = style return cell diff --git a/pkg/gui/presentation/graph/graph.go b/pkg/gui/presentation/graph/graph.go index c267bbbcb..996892d7b 100644 --- a/pkg/gui/presentation/graph/graph.go +++ b/pkg/gui/presentation/graph/graph.go @@ -303,17 +303,17 @@ func renderPipeSet( if left != right { for i := left + 1; i < right; i++ { - cells[i].setLeft(style).setRight(style, overrideRightStyle) + cells[i].setHorizontal(style, overrideRightStyle) } cells[left].setRight(style, overrideRightStyle) cells[right].setLeft(style) } if pipe.kind == STARTS || pipe.kind == CONTINUES { - cells[pipe.toPos].setDown(style) + cells[pipe.toPos].setDown(style, lineTowards(pipe.toPos, pipe.fromPos)) } if pipe.kind == TERMINATES || pipe.kind == CONTINUES { - cells[pipe.fromPos].setUp(style) + cells[pipe.fromPos].setUp(style, lineTowards(pipe.fromPos, pipe.toPos)) } } @@ -375,6 +375,19 @@ func renderPipeSet( return writer.String() } +// The course of a line through the top or bottom edge of the cell at pos, +// given the column of the pipe's other end +func lineTowards(pos, otherPos int16) verticalLine { + switch { + case otherPos < pos: + return lineToLeft + case otherPos > pos: + return lineToRight + default: + return straightLine + } +} + func equalHashes(a, b *string) bool { // if our selectedCommitHashPtr is nil, there is no selected commit if a == nil || b == nil {