fix up boxes to actually work when moved around the screen

This commit is contained in:
David 2021-07-03 21:25:32 -04:00
parent 6cd94df521
commit 40b4cd3668
3 changed files with 217 additions and 10 deletions

116
ui/mock.go Normal file
View File

@ -0,0 +1,116 @@
package ui
import (
"fmt"
"github.com/gdamore/tcell"
)
type coord struct {
x, y int
}
type MockScreen struct {
x, y, h, w int
content map[coord]rune
}
func (m *MockScreen) Init() error {
m.content = map[coord]rune{}
return nil
}
func (m *MockScreen) Fini() {}
func (m *MockScreen) Clear() {
m.content = map[coord]rune{}
}
func (m *MockScreen) Fill(rune, tcell.Style) {}
func (m *MockScreen) SetCell(x int, y int, style tcell.Style, ch ...rune) {}
func (m *MockScreen) GetContent(x, y int) (mainc rune, combc []rune, style tcell.Style, width int) {
return m.content[coord{x, y}], nil, tcell.StyleDefault, 1
}
func (m *MockScreen) SetContent(x int, y int, mainc rune, combc []rune, style tcell.Style) {
m.content[coord{x, y}] = mainc
}
func (m *MockScreen) SetStyle(style tcell.Style) {}
func (m *MockScreen) ShowCursor(x int, y int) {}
func (m *MockScreen) HideCursor() {}
func (m *MockScreen) Size() (int, int) {
return m.h, m.w
}
func (m *MockScreen) PollEvent() tcell.Event {
return tcell.NewEventError(fmt.Errorf("mock error"))
}
func (m *MockScreen) PostEvent(ev tcell.Event) error {
return nil
}
func (m *MockScreen) PostEventWait(ev tcell.Event) {}
func (m *MockScreen) EnableMouse() {}
func (m *MockScreen) DisableMouse() {}
func (m *MockScreen) HasMouse() bool {
return false
}
func (m *MockScreen) Colors() int {
return 0
}
func (m *MockScreen) Show() {}
func (m *MockScreen) Sync() {}
func (m *MockScreen) CharacterSet() string {
return "UTF-8"
}
func (m *MockScreen) RegisterRuneFallback(r rune, subst string) {}
func (m *MockScreen) UnregisterRuneFallback(r rune) {}
func (m *MockScreen) CanDisplay(r rune, checkFallbacks bool) bool {
return true
}
func (m *MockScreen) Resize(x, y, h, w int) {
m.x, m.y, m.h, m.w = x, y, h, w
}
func (m *MockScreen) HasKey(tcell.Key) bool {
return true
}
func (m *MockScreen) Beep() error {
return nil
}
func (m *MockScreen) DumpContents() string {
var res string
for i := m.y; i < m.h; i++ {
str := []rune{}
for j := m.x; j < m.w; j++ {
r, ok := m.content[coord{x: j, y: i}]
if ok {
str = append(str, r)
} else {
str = append(str, ' ')
}
}
res = res + string(str) + "\n"
}
return res
}

View File

@ -59,10 +59,10 @@ func (c *Container) SetSize(x, y, h, w int) {
if c.layoutMethod == LayoutVerticalEven {
num := len(c.contents)
for r := range c.contents {
x := c.x
y := c.y + (num * (r + 1))
h := c.h / num
w := c.w
h := c.h / num
x := c.x
y := c.y + (h * r)
c.contents[r].Container.SetSize(x, y, h, w)
}
} else if c.layoutMethod == LayoutHorizontalEven {
@ -124,18 +124,18 @@ func (b *Box) SetSize(x, y, h, w int) {
}
func (b *Box) Draw(s tcell.Screen) {
for m := 1; m < b.w-1; m++ {
for m := b.x + 1; m < b.x+b.w-1; m++ {
s.SetContent(m, b.y, tcell.RuneHLine, nil, tcell.StyleDefault)
s.SetContent(m, b.h-1, tcell.RuneHLine, nil, tcell.StyleDefault)
s.SetContent(m, b.y+b.h-1, tcell.RuneHLine, nil, tcell.StyleDefault)
}
for m := 1; m < b.h-1; m++ {
for m := b.y + 1; m < b.y+b.h-1; m++ {
s.SetContent(b.x, m, tcell.RuneVLine, nil, tcell.StyleDefault)
s.SetContent(b.w-1, m, tcell.RuneVLine, nil, tcell.StyleDefault)
s.SetContent(b.x+b.w-1, m, tcell.RuneVLine, nil, tcell.StyleDefault)
}
s.SetContent(b.x, b.y, tcell.RuneULCorner, nil, tcell.StyleDefault)
s.SetContent(b.w-1, b.y, tcell.RuneURCorner, nil, tcell.StyleDefault)
s.SetContent(b.x, b.h-1, tcell.RuneLLCorner, nil, tcell.StyleDefault)
s.SetContent(b.w-1, b.h-1, tcell.RuneLRCorner, nil, tcell.StyleDefault)
s.SetContent(b.x+b.w-1, b.y, tcell.RuneURCorner, nil, tcell.StyleDefault)
s.SetContent(b.x, b.y+b.h-1, tcell.RuneLLCorner, nil, tcell.StyleDefault)
s.SetContent(b.x+b.w-1, b.y+b.h-1, tcell.RuneLRCorner, nil, tcell.StyleDefault)
if b.title != nil {
b.title.Draw(s)
@ -215,6 +215,9 @@ func (p *PaddedText) SetSize(x, y, _, _ int) {
}
func (p *PaddedText) Draw(s tcell.Screen) {
if p.text == "" {
return
}
t := p.x
s.SetContent(t, p.y, ' ', nil, tcell.StyleDefault)
t++

88
ui/ui_test.go Normal file
View File

@ -0,0 +1,88 @@
package ui
import (
"fmt"
"testing"
)
func TestContainerOneBox(t *testing.T) {
expect := ` box one
`
m := &MockScreen{}
one := NewBox("box one", nil, Contents{})
container := NewContainer(
Contents{{Container: one}},
LayoutHorizontalEven,
)
m.Init()
m.Resize(0, 0, 5, 20)
container.SetSize(0, 0, 5, 20)
container.Draw(m)
result := m.DumpContents()
if result != expect {
fmt.Printf("expected:\n%+v", expect)
fmt.Printf("actual:\n%+v", result)
t.Fail()
}
}
func TestContainerTwoBoxesHStack(t *testing.T) {
expect := ` one two
`
m := &MockScreen{}
one := NewBox("one", nil, Contents{})
two := NewBox("two", nil, Contents{})
container := NewContainer(
Contents{{Container: one}, {Container: two}},
LayoutHorizontalEven,
)
m.Init()
m.Resize(0, 0, 5, 20)
container.SetSize(0, 0, 5, 20)
container.Draw(m)
result := m.DumpContents()
if result != expect {
fmt.Printf("expected:\n%+v", expect)
fmt.Printf("actual:\n%+v", result)
t.Fail()
}
}
func TestContainerTwoBoxesVStack(t *testing.T) {
expect := ` one
two
`
m := &MockScreen{}
one := NewBox("one", nil, Contents{})
two := NewBox("two", nil, Contents{})
container := NewContainer(
Contents{{Container: one}, {Container: two}},
LayoutVerticalEven,
)
m.Init()
m.Resize(0, 0, 10, 10)
container.SetSize(0, 0, 10, 10)
container.Draw(m)
result := m.DumpContents()
if result != expect {
fmt.Printf("expected:\n%+v", expect)
fmt.Printf("actual:\n%+v", result)
t.Fail()
}
}