doesn't quite work yet
This commit is contained in:
		@@ -1,135 +0,0 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gdamore/tcell"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Drawable interface {
 | 
			
		||||
	Draw(tcell.Screen)
 | 
			
		||||
	SetSize(x, y, h, w int)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type offsets struct {
 | 
			
		||||
	top    int
 | 
			
		||||
	bottom int
 | 
			
		||||
	left   int
 | 
			
		||||
	right  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type contents []struct {
 | 
			
		||||
	offsets   offsets
 | 
			
		||||
	container Drawable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type box struct {
 | 
			
		||||
	x, y      int
 | 
			
		||||
	h, w      int
 | 
			
		||||
	title     Drawable
 | 
			
		||||
	menuItems Drawable
 | 
			
		||||
	contents  []struct {
 | 
			
		||||
		offsets   offsets
 | 
			
		||||
		container Drawable
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBox(title string, menuItems []string, contents contents) *box {
 | 
			
		||||
	return &box{
 | 
			
		||||
		title:     NewPaddedText(title),
 | 
			
		||||
		menuItems: NewPaddedText(strings.Join(menuItems, " ")),
 | 
			
		||||
		contents:  contents,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *box) SetSize(x, y, h, w int) {
 | 
			
		||||
	b.x, b.y, b.h, b.w = x, y, h, w
 | 
			
		||||
	b.title.SetSize(b.x+2, b.y, 0, 0)
 | 
			
		||||
	b.menuItems.SetSize(b.x+2, b.y+b.h-1, 0, 0)
 | 
			
		||||
	for c := range b.contents {
 | 
			
		||||
		x := b.x + b.contents[c].offsets.left
 | 
			
		||||
		y := b.y + b.contents[c].offsets.top
 | 
			
		||||
		h := b.h - b.contents[c].offsets.bottom
 | 
			
		||||
		w := b.w - b.contents[c].offsets.right
 | 
			
		||||
		b.contents[c].container.SetSize(x, y, h, w)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *box) Draw(s tcell.Screen) {
 | 
			
		||||
	for m := 1; m < 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)
 | 
			
		||||
	}
 | 
			
		||||
	for m := 1; m < 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.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)
 | 
			
		||||
 | 
			
		||||
	if b.title != nil {
 | 
			
		||||
		b.title.Draw(s)
 | 
			
		||||
	}
 | 
			
		||||
	if b.menuItems != nil {
 | 
			
		||||
		b.menuItems.Draw(s)
 | 
			
		||||
	}
 | 
			
		||||
	for c := range b.contents {
 | 
			
		||||
		b.contents[c].container.Draw(s)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type list struct {
 | 
			
		||||
	x, y      int
 | 
			
		||||
	h, w      int
 | 
			
		||||
	selected  int
 | 
			
		||||
	listItems []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewList(listItems []string, initialSelected int) *list {
 | 
			
		||||
	return &list{
 | 
			
		||||
		listItems: listItems,
 | 
			
		||||
		selected:  initialSelected,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *list) SetSize(x, y, h, w int) {
 | 
			
		||||
	l.x, l.y, l.h, l.w = x, y, h, w
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *list) Draw(s tcell.Screen) {
 | 
			
		||||
	for i := range l.listItems {
 | 
			
		||||
		for j, r := range l.listItems[i] {
 | 
			
		||||
			s.SetContent(l.x+j, l.y+i, r, nil, tcell.StyleDefault)
 | 
			
		||||
		}
 | 
			
		||||
		if i == l.selected {
 | 
			
		||||
			s.SetContent(l.x+len(l.listItems[i])+1, l.y+i, '<', nil, tcell.StyleDefault)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type paddedText struct {
 | 
			
		||||
	x, y int
 | 
			
		||||
	h, w int
 | 
			
		||||
	text string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewPaddedText(text string) *paddedText {
 | 
			
		||||
	return &paddedText{text: text}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *paddedText) SetSize(x, y, _, _ int) {
 | 
			
		||||
	p.x, p.y, p.h, p.w = x, y, 1, len(p.text)+2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *paddedText) Draw(s tcell.Screen) {
 | 
			
		||||
	t := p.x
 | 
			
		||||
	s.SetContent(t, p.y, ' ', nil, tcell.StyleDefault)
 | 
			
		||||
	t++
 | 
			
		||||
	for _, r := range p.text {
 | 
			
		||||
		s.SetContent(t, p.y, r, nil, tcell.StyleDefault)
 | 
			
		||||
		t++
 | 
			
		||||
	}
 | 
			
		||||
	s.SetContent(t, p.y, ' ', nil, tcell.StyleDefault)
 | 
			
		||||
}
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"log"
 | 
			
		||||
 | 
			
		||||
	"git.yetaga.in/alazyreader/library/config"
 | 
			
		||||
	"git.yetaga.in/alazyreader/library/ui"
 | 
			
		||||
	"github.com/gdamore/tcell"
 | 
			
		||||
	"github.com/kelseyhightower/envconfig"
 | 
			
		||||
)
 | 
			
		||||
@@ -24,21 +25,31 @@ func main() {
 | 
			
		||||
		log.Fatalln(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	l := NewList([]string{"foo", "bar", "baz"}, 0)
 | 
			
		||||
	b := NewBox(
 | 
			
		||||
	l := ui.NewList([]string{"foo", "bar", "baz"}, 0)
 | 
			
		||||
	menu := ui.NewBox(
 | 
			
		||||
		"library",
 | 
			
		||||
		[]string{"(e)dit", "(q)uit"},
 | 
			
		||||
		contents{{
 | 
			
		||||
			offsets:   offsets{top: 1, left: 2, bottom: -2, right: -2},
 | 
			
		||||
			container: l,
 | 
			
		||||
		ui.Contents{{
 | 
			
		||||
			Offsets:   ui.Offsets{Top: 1, Left: 2, Bottom: -2, Right: -2},
 | 
			
		||||
			Container: l,
 | 
			
		||||
		}},
 | 
			
		||||
	)
 | 
			
		||||
	activeBook := ui.NewBox(
 | 
			
		||||
		"book",
 | 
			
		||||
		[]string{"test"},
 | 
			
		||||
		ui.Contents{},
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	container := ui.NewContainer(
 | 
			
		||||
		ui.Contents{{Container: menu}, {Container: activeBook}},
 | 
			
		||||
		ui.LayoutHorizontalEven,
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// init
 | 
			
		||||
	screen.Clear()
 | 
			
		||||
	w, h := screen.Size()
 | 
			
		||||
	b.SetSize(0, 0, h, w)
 | 
			
		||||
	b.Draw(screen)
 | 
			
		||||
	container.SetSize(0, 0, h, w)
 | 
			
		||||
	container.Draw(screen)
 | 
			
		||||
	screen.Sync()
 | 
			
		||||
 | 
			
		||||
	// UI loop
 | 
			
		||||
@@ -48,11 +59,11 @@ func main() {
 | 
			
		||||
		case *tcell.EventError:
 | 
			
		||||
			screen.Beep()
 | 
			
		||||
		case *tcell.EventKey: // input handling
 | 
			
		||||
			if v.Key() == tcell.KeyUp && l.selected > 0 {
 | 
			
		||||
				l.selected = l.selected - 1
 | 
			
		||||
			if v.Key() == tcell.KeyUp && l.Selected() > 0 {
 | 
			
		||||
				l.SetSelected(l.Selected() - 1)
 | 
			
		||||
			}
 | 
			
		||||
			if v.Key() == tcell.KeyDown && l.selected < len(l.listItems)-1 {
 | 
			
		||||
				l.selected = l.selected + 1
 | 
			
		||||
			if v.Key() == tcell.KeyDown && l.Selected() < len(l.ListMembers())-1 {
 | 
			
		||||
				l.SetSelected(l.Selected() + 1)
 | 
			
		||||
			}
 | 
			
		||||
			if v.Rune() == 'q' {
 | 
			
		||||
				screen.Fini()
 | 
			
		||||
@@ -60,17 +71,17 @@ func main() {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			screen.Clear()
 | 
			
		||||
			b.Draw(screen)
 | 
			
		||||
			container.Draw(screen)
 | 
			
		||||
		case *tcell.EventResize: // screen redraw
 | 
			
		||||
			w, h := screen.Size()
 | 
			
		||||
			b.SetSize(0, 0, h, w)
 | 
			
		||||
			container.SetSize(0, 0, h, w)
 | 
			
		||||
			screen.Clear()
 | 
			
		||||
			b.Draw(screen)
 | 
			
		||||
			container.Draw(screen)
 | 
			
		||||
		case *tcell.EventInterrupt:
 | 
			
		||||
		case *tcell.EventMouse:
 | 
			
		||||
		case *tcell.EventTime:
 | 
			
		||||
		default:
 | 
			
		||||
		}
 | 
			
		||||
		screen.Sync() // repaint
 | 
			
		||||
		screen.Show() // repaint
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user