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 (
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/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/go.mod h1:XRf0+7nhOkIEr0gi9DUG4RvV2KaOFB0fYPDaR1KLenw=
git.tordarus.net/Tordarus/buf2d v1.1.2 h1:mmK3tARa30gCh4WaYoSEF5e7qk0C+1ODhxerUcfXN5M=
git.tordarus.net/Tordarus/buf2d v1.1.2/go.mod h1:XXPpS8nQK0gUI0ki7ftV/qlprsGCRWFVSD4ybvDuUL8=
git.tordarus.net/Tordarus/buf2d v1.1.4 h1:5R33Bq/no3uQIk7Tql6z55LI635DHeXQ7STNz0R7FQQ=
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/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.4.0 h1:vUnHwJRvcPQa3tzi+0QI4U9JINXYJlOz9yiaiPQ2wMU=

View File

@ -82,6 +82,22 @@ func TestScrollView(t *testing.T) {
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) {
textView := views.NewTextView("hello world!")
textView.SetStyle(tui.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack))

View File

@ -41,6 +41,16 @@ const (
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
const (

View File

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

View File

@ -8,47 +8,107 @@ import "git.tordarus.net/Tordarus/tui"
type BorderView struct {
tui.WrapperTmpl
Border BorderBox
HideBorder bool
ShowBorder map[tui.Side]bool
}
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.SetView(view)
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
}
func (g *BorderView) Draw(buf *tui.ViewBuffer) {
if g.HideBorder {
g.View().Draw(buf)
return
viewbuf := buf
// 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()})
buf.Set(buf.Width()-1, 0, tui.Rune{Rn: g.Border.TopRight, Style: g.Style()})
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, buf.Height()-1, tui.Rune{Rn: g.Border.Horizontal, Style: g.Style()})
// draw horizontal lines
for x := 0; x < buf.Width(); x++ {
if g.ShowBorder[tui.SideTop] {
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()})
}
}
for y := 1; y < buf.Height()-1; y++ {
buf.Set(0, 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 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()})
}
if g.ShowBorder[tui.SideRight] {
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) {
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
}