149 lines
3.2 KiB
Go
149 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"git.yetaga.in/alazyreader/library/config"
|
|
"github.com/gdamore/tcell"
|
|
"github.com/kelseyhightower/envconfig"
|
|
)
|
|
|
|
func main() {
|
|
var c config.Config
|
|
err := envconfig.Process("library", &c)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
screen, err := tcell.NewScreen()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
err = screen.Init()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
screen.Clear()
|
|
w, h := screen.Size()
|
|
l := &list{
|
|
w: w - 4, h: h - 4,
|
|
x: 2, y: 1,
|
|
selected: 2,
|
|
listItems: []string{"foo", "bar", "baz"},
|
|
}
|
|
b := &box{
|
|
w: w, h: h,
|
|
x: 0, y: 0,
|
|
title: "library",
|
|
menuItems: []string{"(e)dit", "(q)uit"},
|
|
contents: l,
|
|
}
|
|
for {
|
|
e := screen.PollEvent()
|
|
switch v := e.(type) {
|
|
case *tcell.EventError:
|
|
screen.Clear()
|
|
screen.Beep()
|
|
b.draw(screen)
|
|
screen.SetContent(1, 1, 'E', nil, tcell.StyleDefault)
|
|
case *tcell.EventKey:
|
|
screen.Clear()
|
|
if v.Key() == tcell.KeyUp && l.selected > 0 {
|
|
l.selected = l.selected - 1
|
|
}
|
|
if v.Key() == tcell.KeyDown && l.selected < len(l.listItems)-1 {
|
|
l.selected = l.selected + 1
|
|
}
|
|
if v.Rune() == 'q' {
|
|
screen.Fini()
|
|
fmt.Printf("Thank you for playing Wing Commander!\n\n")
|
|
return
|
|
}
|
|
b.draw(screen)
|
|
case *tcell.EventResize:
|
|
screen.Clear()
|
|
w, h := screen.Size()
|
|
b.w, b.h = w, h
|
|
b.draw(screen)
|
|
case *tcell.EventInterrupt:
|
|
case *tcell.EventMouse:
|
|
case *tcell.EventTime:
|
|
default:
|
|
}
|
|
screen.Sync()
|
|
}
|
|
}
|
|
|
|
type drawable interface {
|
|
draw(tcell.Screen)
|
|
}
|
|
|
|
type box struct {
|
|
x, y int
|
|
h, w int
|
|
title string
|
|
menuItems []string
|
|
contents drawable
|
|
}
|
|
|
|
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 != "" {
|
|
t := b.x + 2
|
|
s.SetContent(t, b.y, ' ', nil, tcell.StyleDefault)
|
|
t++
|
|
for _, r := range b.title {
|
|
s.SetContent(t, b.y, r, nil, tcell.StyleDefault)
|
|
t++
|
|
}
|
|
s.SetContent(t, b.y, ' ', nil, tcell.StyleDefault)
|
|
}
|
|
if len(b.menuItems) != 0 {
|
|
t := b.x + 2
|
|
s.SetContent(t, b.h-1, ' ', nil, tcell.StyleDefault)
|
|
t++
|
|
for i := range b.menuItems {
|
|
for _, r := range b.menuItems[i] {
|
|
s.SetContent(t, b.h-1, r, nil, tcell.StyleDefault)
|
|
t++
|
|
}
|
|
s.SetContent(t, b.h-1, ' ', nil, tcell.StyleDefault)
|
|
t++
|
|
}
|
|
}
|
|
if b.contents != nil {
|
|
b.contents.draw(s)
|
|
}
|
|
}
|
|
|
|
type list struct {
|
|
x, y int
|
|
h, w int
|
|
selected int
|
|
listItems []string
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
}
|