fix up boxes to actually work when moved around the screen
This commit is contained in:
parent
6cd94df521
commit
40b4cd3668
116
ui/mock.go
Normal file
116
ui/mock.go
Normal 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
|
||||||
|
}
|
23
ui/ui.go
23
ui/ui.go
@ -59,10 +59,10 @@ func (c *Container) SetSize(x, y, h, w int) {
|
|||||||
if c.layoutMethod == LayoutVerticalEven {
|
if c.layoutMethod == LayoutVerticalEven {
|
||||||
num := len(c.contents)
|
num := len(c.contents)
|
||||||
for r := range c.contents {
|
for r := range c.contents {
|
||||||
x := c.x
|
|
||||||
y := c.y + (num * (r + 1))
|
|
||||||
h := c.h / num
|
|
||||||
w := c.w
|
w := c.w
|
||||||
|
h := c.h / num
|
||||||
|
x := c.x
|
||||||
|
y := c.y + (h * r)
|
||||||
c.contents[r].Container.SetSize(x, y, h, w)
|
c.contents[r].Container.SetSize(x, y, h, w)
|
||||||
}
|
}
|
||||||
} else if c.layoutMethod == LayoutHorizontalEven {
|
} 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) {
|
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.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.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.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.w-1, b.y, tcell.RuneURCorner, nil, tcell.StyleDefault)
|
||||||
s.SetContent(b.x, b.h-1, tcell.RuneLLCorner, nil, tcell.StyleDefault)
|
s.SetContent(b.x, b.y+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+b.h-1, tcell.RuneLRCorner, nil, tcell.StyleDefault)
|
||||||
|
|
||||||
if b.title != nil {
|
if b.title != nil {
|
||||||
b.title.Draw(s)
|
b.title.Draw(s)
|
||||||
@ -215,6 +215,9 @@ func (p *PaddedText) SetSize(x, y, _, _ int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PaddedText) Draw(s tcell.Screen) {
|
func (p *PaddedText) Draw(s tcell.Screen) {
|
||||||
|
if p.text == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
t := p.x
|
t := p.x
|
||||||
s.SetContent(t, p.y, ' ', nil, tcell.StyleDefault)
|
s.SetContent(t, p.y, ' ', nil, tcell.StyleDefault)
|
||||||
t++
|
t++
|
||||||
|
88
ui/ui_test.go
Normal file
88
ui/ui_test.go
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user