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) } } }