fix up boxes to actually work when moved around the screen
This commit is contained in:
		
							
								
								
									
										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()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user