hide specific borders in BorderView

This commit is contained in:
Timon Ringwald 2022-05-04 10:17:16 +02:00
parent 5a460a9e40
commit c3ba6e36f2
6 changed files with 110 additions and 27 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.18
require ( require (
git.tordarus.net/Tordarus/adverr v0.2.0 git.tordarus.net/Tordarus/adverr v0.2.0
git.tordarus.net/Tordarus/buf2d v1.1.2 git.tordarus.net/Tordarus/buf2d v1.1.4
github.com/gdamore/tcell v1.4.0 github.com/gdamore/tcell v1.4.0
github.com/mattn/go-runewidth v0.0.7 github.com/mattn/go-runewidth v0.0.7
) )

4
go.sum
View File

@ -1,7 +1,7 @@
git.tordarus.net/Tordarus/adverr v0.2.0 h1:kLYjR2/Vb2GHiSAMvAv+WPNaHR9BRphKanf8H/pCZdA= git.tordarus.net/Tordarus/adverr v0.2.0 h1:kLYjR2/Vb2GHiSAMvAv+WPNaHR9BRphKanf8H/pCZdA=
git.tordarus.net/Tordarus/adverr v0.2.0/go.mod h1:XRf0+7nhOkIEr0gi9DUG4RvV2KaOFB0fYPDaR1KLenw= git.tordarus.net/Tordarus/adverr v0.2.0/go.mod h1:XRf0+7nhOkIEr0gi9DUG4RvV2KaOFB0fYPDaR1KLenw=
git.tordarus.net/Tordarus/buf2d v1.1.2 h1:mmK3tARa30gCh4WaYoSEF5e7qk0C+1ODhxerUcfXN5M= git.tordarus.net/Tordarus/buf2d v1.1.4 h1:5R33Bq/no3uQIk7Tql6z55LI635DHeXQ7STNz0R7FQQ=
git.tordarus.net/Tordarus/buf2d v1.1.2/go.mod h1:XXPpS8nQK0gUI0ki7ftV/qlprsGCRWFVSD4ybvDuUL8= git.tordarus.net/Tordarus/buf2d v1.1.4/go.mod h1:XXPpS8nQK0gUI0ki7ftV/qlprsGCRWFVSD4ybvDuUL8=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU= github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=

View File

@ -82,6 +82,22 @@ func TestScrollView(t *testing.T) {
fmt.Println(err) fmt.Println(err)
} }
func TestBorderView(t *testing.T) {
textView := views.NewTextView("hello world!")
borderView := views.NewBorderView(textView)
//borderView2 := views.NewBorderView(borderView)
screen, err := tui.NewScreen(borderView)
if err != nil {
t.Error(err)
return
}
if err := screen.Start(); err != nil {
fmt.Println(err)
}
}
func TestFlowLayout(t *testing.T) { func TestFlowLayout(t *testing.T) {
textView := views.NewTextView("hello world!") textView := views.NewTextView("hello world!")
textView.SetStyle(tui.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack)) textView.SetStyle(tui.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack))

View File

@ -41,6 +41,16 @@ const (
SideRight SideRight
) )
// Horizontal returns true if s is either SideLeft or SideRight
func (s Side) Horizontal() bool {
return s == SideLeft || s == SideRight
}
// Vertical returns true if s is either SideTop or SideBottom
func (s Side) Vertical() bool {
return s == SideTop || s == SideBottom
}
type Anchor uint8 type Anchor uint8
const ( const (

View File

@ -49,10 +49,7 @@ func (g *FlowLayout) removeView(v tui.View) {
} }
func (g *FlowLayout) RemoveViews(v ...tui.View) { func (g *FlowLayout) RemoveViews(v ...tui.View) {
views := make([]tui.View, 0, len(v)) views := append(make([]tui.View, 0, len(v)), v...)
for _, view := range v {
views = append(views, view)
}
for _, view := range views { for _, view := range views {
g.removeView(view) g.removeView(view)
} }

View File

@ -8,47 +8,107 @@ import "git.tordarus.net/Tordarus/tui"
type BorderView struct { type BorderView struct {
tui.WrapperTmpl tui.WrapperTmpl
Border BorderBox Border BorderBox
HideBorder bool ShowBorder map[tui.Side]bool
} }
var _ tui.Wrapper = &BorderView{} var _ tui.Wrapper = &BorderView{}
func NewBorderView(view tui.View) *BorderView { // NewBorderView create a new BorderView which show borders on the given sides around its view.
// If no sides are given, all sides will have a border by default
func NewBorderView(view tui.View, showBorders ...tui.Side) *BorderView {
v := new(BorderView) v := new(BorderView)
v.SetView(view) v.SetView(view)
v.Border = ThinBorder() v.Border = ThinBorder()
if len(showBorders) == 0 {
v.ShowBorder = map[tui.Side]bool{
tui.SideBottom: true,
tui.SideTop: true,
tui.SideLeft: true,
tui.SideRight: true,
}
} else {
v.ShowBorder = map[tui.Side]bool{}
for _, border := range showBorders {
v.ShowBorder[border] = true
}
}
return v return v
} }
func (g *BorderView) Draw(buf *tui.ViewBuffer) { func (g *BorderView) Draw(buf *tui.ViewBuffer) {
if g.HideBorder { viewbuf := buf
g.View().Draw(buf)
return // limit view buffer for child view
if g.ShowBorder[tui.SideTop] {
viewbuf = viewbuf.Sub(0, 1, viewbuf.Width(), viewbuf.Height())
}
if g.ShowBorder[tui.SideBottom] {
viewbuf = viewbuf.Sub(0, 0, viewbuf.Width(), viewbuf.Height()-1)
}
if g.ShowBorder[tui.SideLeft] {
viewbuf = viewbuf.Sub(1, 0, viewbuf.Width(), viewbuf.Height())
}
if g.ShowBorder[tui.SideRight] {
viewbuf = viewbuf.Sub(0, 0, viewbuf.Width()-1, viewbuf.Height())
} }
g.View().Draw(buf.Sub(1, 1, buf.Width()-2, buf.Height()-2)) // draw child view
g.View().Draw(viewbuf)
buf.Set(0, 0, tui.Rune{Rn: g.Border.TopLeft, Style: g.Style()}) // draw horizontal lines
buf.Set(buf.Width()-1, 0, tui.Rune{Rn: g.Border.TopRight, Style: g.Style()}) for x := 0; x < buf.Width(); x++ {
if g.ShowBorder[tui.SideTop] {
buf.Set(0, buf.Height()-1, tui.Rune{Rn: g.Border.BottomLeft, Style: g.Style()})
buf.Set(buf.Width()-1, buf.Height()-1, tui.Rune{Rn: g.Border.BottomRight, Style: g.Style()})
for x := 1; x < buf.Width()-1; x++ {
buf.Set(x, 0, tui.Rune{Rn: g.Border.Horizontal, Style: g.Style()}) buf.Set(x, 0, tui.Rune{Rn: g.Border.Horizontal, Style: g.Style()})
}
if g.ShowBorder[tui.SideBottom] {
buf.Set(x, buf.Height()-1, tui.Rune{Rn: g.Border.Horizontal, Style: g.Style()}) buf.Set(x, buf.Height()-1, tui.Rune{Rn: g.Border.Horizontal, Style: g.Style()})
} }
}
for y := 1; y < buf.Height()-1; y++ { // draw vertical lines
for y := 0; y < buf.Height(); y++ {
if g.ShowBorder[tui.SideLeft] {
buf.Set(0, y, tui.Rune{Rn: g.Border.Vertical, Style: g.Style()}) buf.Set(0, y, tui.Rune{Rn: g.Border.Vertical, Style: g.Style()})
}
if g.ShowBorder[tui.SideRight] {
buf.Set(buf.Width()-1, y, tui.Rune{Rn: g.Border.Vertical, Style: g.Style()}) buf.Set(buf.Width()-1, y, tui.Rune{Rn: g.Border.Vertical, Style: g.Style()})
} }
}
// draw corners
if g.ShowBorder[tui.SideTop] {
if g.ShowBorder[tui.SideLeft] {
buf.Set(0, 0, tui.Rune{Rn: g.Border.TopLeft, Style: g.Style()})
}
if g.ShowBorder[tui.SideRight] {
buf.Set(buf.Width()-1, 0, tui.Rune{Rn: g.Border.TopRight, Style: g.Style()})
}
}
if g.ShowBorder[tui.SideBottom] {
if g.ShowBorder[tui.SideLeft] {
buf.Set(0, buf.Height()-1, tui.Rune{Rn: g.Border.BottomLeft, Style: g.Style()})
}
if g.ShowBorder[tui.SideRight] {
buf.Set(buf.Width()-1, buf.Height()-1, tui.Rune{Rn: g.Border.BottomRight, Style: g.Style()})
}
}
} }
func (v *BorderView) Layout() (prefWidth, prefHeight int) { func (v *BorderView) Layout() (prefWidth, prefHeight int) {
w, h := v.View().Layout() w, h := v.View().Layout()
w = iff(w > 0, w+2, w)
h = iff(h > 0, h+2, h) for side, border := range v.ShowBorder {
if border {
if side.Horizontal() {
w++
} else if side.Vertical() {
h++
}
}
}
return w, h return w, h
} }