diff --git a/border.go b/border.go new file mode 100644 index 0000000..3d69363 --- /dev/null +++ b/border.go @@ -0,0 +1,75 @@ +package tui + +const ( + runeMinus = '-' + runePlusSmall = '+' + runeVLineSmall = '|' + + runePlus = '┼' + runeHLine = '─' + runeVLine = '│' + runeTTee = '┬' + runeRTee = '┤' + runeLTee = '├' + runeBTee = '┴' + runeULCorner = '┌' + runeURCorner = '┐' + runeLLCorner = '└' + runeLRCorner = '┘' +) + +var runeFallbacks = map[rune]rune{} + +func init() { + defaultBorder() +} + +// default +// ┌──────────────────┐ +// │┌────────┬───────┐│ +// ││A │apple ││ +// │└────────┴───────┘│ +// └──────────────────┘ +func defaultBorder() { + runeFallbacks = map[rune]rune{ + runePlus: runePlus, + runeHLine: runeHLine, + runeVLine: runeVLine, + runeTTee: runeTTee, + runeRTee: runeRTee, + runeLTee: runeLTee, + runeBTee: runeBTee, + runeULCorner: runeULCorner, + runeURCorner: runeURCorner, + runeLLCorner: runeLLCorner, + runeLRCorner: runeLRCorner, + } +} + +// small +// +------------------+ +// |+--------+-------+| +// ||A |apple || +// |+--------+-------+| +// +------------------+ +func simpleBorder() { + runeFallbacks = map[rune]rune{ + runeHLine: runeMinus, + runeVLine: runeVLineSmall, + + runePlus: runePlusSmall, + runeLLCorner: runePlusSmall, + runeLRCorner: runePlusSmall, + runeTTee: runePlusSmall, + runeRTee: runePlusSmall, + runeLTee: runePlusSmall, + runeBTee: runePlusSmall, + runeULCorner: runePlusSmall, + runeURCorner: runePlusSmall, + } +} + +// GetBorder get a simple or default border in a compatible way +func GetBorder(k rune) rune { + return runeFallbacks[k] +} diff --git a/grid.go b/grid.go index dbb379e..74afc6f 100644 --- a/grid.go +++ b/grid.go @@ -49,8 +49,8 @@ func (g *Grid) Draw(p *Painter) { for i := 0; i < g.cols-1; i++ { x := g.colWidths[i] + coloff + border p.DrawVerticalLine(x, 0, s.Y-1) - p.DrawRune(x, 0, '┬') - p.DrawRune(x, s.Y-1, '┴') + p.DrawRune(x, 0, GetBorder('┬')) + p.DrawRune(x, s.Y-1, GetBorder('┴')) coloff = x } @@ -59,8 +59,8 @@ func (g *Grid) Draw(p *Painter) { for j := 0; j < g.rows-1; j++ { y := g.rowHeights[j] + rowoff + border p.DrawHorizontalLine(0, s.X-1, y) - p.DrawRune(0, y, '├') - p.DrawRune(s.X-1, y, '┤') + p.DrawRune(0, y, GetBorder('├')) + p.DrawRune(s.X-1, y, GetBorder('┤')) rowoff = y } @@ -71,7 +71,7 @@ func (g *Grid) Draw(p *Painter) { coloff = 0 for i := 0; i < g.cols-1; i++ { x := g.colWidths[i] + coloff + border - p.DrawRune(x, y, '┼') + p.DrawRune(x, y, GetBorder('┼')) coloff = x } rowoff = y @@ -409,6 +409,16 @@ func (g *Grid) SetBorder(enabled bool) { g.hasBorder = enabled } +// SetSimpleBorder sets the border use [+ - |]. This is a global config. +func (g *Grid) SetSimpleBorder() { + simpleBorder() +} + +// SetDefaultBorder sets the border use [┼ ─ │ ┬ ┤ ├ ┴ ┌ ┐ └ ┘]. This is a global config. +func (g *Grid) SetDefaultBorder() { + defaultBorder() +} + // AppendRow adds a new row at the end. func (g *Grid) AppendRow(row ...Widget) { g.rows++ diff --git a/grid_test.go b/grid_test.go index 979e2c5..14dac96 100644 --- a/grid_test.go +++ b/grid_test.go @@ -221,6 +221,23 @@ var drawGridTests = []struct { ┌─┬─────────┬──────────────────┬─┐ │f│bar......│baz...............│t│ └─┴─────────┴──────────────────┴─┘ +`, + }, + { + test: "Empty grid with simple border", + size: image.Point{15, 5}, + setup: func() *Grid { + g := NewGrid(0, 0) + g.SetBorder(true) + g.SetSimpleBorder() + return g + }, + want: ` ++-------------+ +|.............| +|.............| +|.............| ++-------------+ `, }, } @@ -232,6 +249,8 @@ func TestGrid_Draw(t *testing.T) { painter := NewPainter(surface, NewTheme()) painter.Repaint(tt.setup()) + // Reset + tt.setup().SetDefaultBorder() if diff := surfaceEquals(surface, tt.want); diff != "" { t.Error(diff) } diff --git a/painter.go b/painter.go index eea1add..3db1bad 100644 --- a/painter.go +++ b/painter.go @@ -106,14 +106,14 @@ func (p *Painter) DrawText(x, y int, text string) { // DrawHorizontalLine paints a horizontal line using box characters. func (p *Painter) DrawHorizontalLine(x1, x2, y int) { for x := x1; x < x2; x++ { - p.DrawRune(x, y, '─') + p.DrawRune(x, y, GetBorder('─')) } } // DrawVerticalLine paints a vertical line using box characters. func (p *Painter) DrawVerticalLine(x, y1, y2 int) { for y := y1; y < y2; y++ { - p.DrawRune(x, y, '│') + p.DrawRune(x, y, GetBorder('│')) } } @@ -126,17 +126,17 @@ func (p *Painter) DrawRect(x, y, w, h int) { switch { case i == 0 && j == 0: - p.DrawRune(m, n, '┌') + p.DrawRune(m, n, GetBorder('┌')) case i == w-1 && j == 0: - p.DrawRune(m, n, '┐') + p.DrawRune(m, n, GetBorder('┐')) case i == 0 && j == h-1: - p.DrawRune(m, n, '└') + p.DrawRune(m, n, GetBorder('└')) case i == w-1 && j == h-1: - p.DrawRune(m, n, '┘') + p.DrawRune(m, n, GetBorder('┘')) case i == 0 || i == w-1: - p.DrawRune(m, n, '│') + p.DrawRune(m, n, GetBorder('│')) case j == 0 || j == h-1: - p.DrawRune(m, n, '─') + p.DrawRune(m, n, GetBorder('─')) } } } diff --git a/table.go b/table.go index 3f8865f..006e36a 100644 --- a/table.go +++ b/table.go @@ -35,8 +35,8 @@ func (t *Table) Draw(p *Painter) { for i := 0; i < t.cols-1; i++ { x := t.colWidths[i] + coloff + border p.DrawVerticalLine(x, 0, s.Y-1) - p.DrawRune(x, 0, '┬') - p.DrawRune(x, s.Y-1, '┴') + p.DrawRune(x, 0, GetBorder('┬')) + p.DrawRune(x, s.Y-1, GetBorder('┴')) coloff = x } @@ -45,8 +45,8 @@ func (t *Table) Draw(p *Painter) { for j := 0; j < t.rows-1; j++ { y := t.rowHeights[j] + rowoff + border p.DrawHorizontalLine(0, s.X-1, y) - p.DrawRune(0, y, '├') - p.DrawRune(s.X-1, y, '┤') + p.DrawRune(0, y, GetBorder('├')) + p.DrawRune(s.X-1, y, GetBorder('┤')) rowoff = y } @@ -57,7 +57,7 @@ func (t *Table) Draw(p *Painter) { coloff = 0 for i := 0; i < t.cols-1; i++ { x := t.colWidths[i] + coloff + border - p.DrawRune(x, y, '┼') + p.DrawRune(x, y, GetBorder('┼')) coloff = x } rowoff = y