Initial commit

This commit is contained in:
Roi Martin (@nibble_ds) 2013-12-27 21:36:26 +01:00
commit 58bbbb3d53
4 changed files with 211 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.swp

4
README.md Normal file
View File

@ -0,0 +1,4 @@
GOCUI - Go Console User Interface
=================================
WIP

153
gui.go Normal file
View File

@ -0,0 +1,153 @@
package gocui
import (
"errors"
"github.com/jroimartin/termbox-go"
)
var ErrorQuit = errors.New("quit")
const (
RuneCornerTopLeft = '┌'
RuneCornerTopRight = '┐'
RuneCornerBottomLeft = '└'
RuneCornerBottomRight = '┘'
RuneEdgeVertical = '│'
RuneEdgeHorizontal = '─'
RuneIntersection = '┼'
RuneIntersectionLeft = '├'
RuneIntersectionRight = '┤'
RuneIntersectionTop = '┬'
RuneIntersectionBottom = '┴'
RuneTriangleLeft = '◄'
RuneTriangleRight = '►'
RuneArrowLeft = '←'
RuneArrowRight = '→'
)
type Gui struct {
events chan termbox.Event
views []*View
currentView *View
}
func NewGui() (g *Gui) {
return &Gui{}
}
func (g *Gui) Init() (err error) {
g.events = make(chan termbox.Event, 20)
return termbox.Init()
}
func (g *Gui) Close() {
termbox.Close()
}
func (g *Gui) Size() (x, y int) {
return termbox.Size()
}
func (g *Gui) AddView(x0, y0, x1, y1 int) (v *View, err error) {
maxX, maxY := termbox.Size()
if x0 < 0 || y0 < 0 || x1 < 0 || y1 < 0 ||
x0 > maxX || y0 > maxY || x1 > maxX || y1 > maxY {
return nil, errors.New("Invalid coordinates")
}
v = NewView(x0, y0, x1, y1)
g.views = append(g.views, v)
return v, nil
}
func (g *Gui) MainLoop() (err error) {
go func() {
for {
g.events <- termbox.PollEvent()
}
}()
if err := g.resize(); err != nil {
return err
}
if err := g.draw(); err != nil {
return err
}
// TODO: Set initial cursor position
//termbox.SetCursor(10, 10)
termbox.Flush()
for {
select {
case ev := <-g.events:
if err := g.handleEvent(&ev); err != nil {
return err
}
if err := g.consumeevents(); err != nil {
return err
}
if err := g.draw(); err != nil {
return err
}
termbox.Flush()
}
}
return nil
}
func (g *Gui) consumeevents() (err error) {
for {
select {
case ev := <-g.events:
if err := g.handleEvent(&ev); err != nil {
return err
}
default:
return nil
}
}
}
func (g *Gui) handleEvent(ev *termbox.Event) (err error) {
switch ev.Type {
case termbox.EventKey:
return g.onKey(ev)
case termbox.EventResize:
return g.resize()
case termbox.EventError:
return ev.Err
default:
return nil
}
}
func (g *Gui) draw() (err error) {
for _, v := range g.views {
if err := v.Draw(); err != nil {
return err
}
}
return nil
}
func (g *Gui) resize() (err error) {
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
for _, v := range g.views {
if err := v.Resize(); err != nil {
return err
}
}
return nil
}
func (g *Gui) onKey(ev *termbox.Event) (err error) {
switch ev.Key {
case termbox.KeyCtrlC:
return ErrorQuit
default:
return nil
}
}

53
view.go Normal file
View File

@ -0,0 +1,53 @@
package gocui
import (
"github.com/jroimartin/termbox-go"
)
type View struct {
x0, y0, x1, y1 int
cx, cy int
BgColor, FgColor termbox.Attribute
SelBgColor, SelFgColor termbox.Attribute
}
func NewView(x0, y0, x1, y1 int) (v *View) {
return &View{x0: x0, y0: y0, x1: x1, y1: y1,
BgColor: termbox.ColorBlack, FgColor: termbox.ColorWhite,
SelBgColor: termbox.ColorBlack, SelFgColor: termbox.ColorWhite}
}
func (v *View) SetCell(x, y int, ch rune) {
var bgColor, fgColor termbox.Attribute
if y == v.cy {
bgColor = v.SelBgColor
fgColor = v.SelFgColor
} else {
bgColor = v.BgColor
fgColor = v.FgColor
}
termbox.SetCell(x, y, ch, fgColor, bgColor)
}
func (v *View) Draw() (err error) {
//maxX, maxY := termbox.Size()
v.SetCell(v.x0, v.y0, RuneCornerTopLeft)
v.SetCell(v.x1, v.y0, RuneCornerTopRight)
v.SetCell(v.x0, v.y1, RuneCornerBottomLeft)
v.SetCell(v.x1, v.y1, RuneCornerBottomRight)
for x := v.x0 + 1; x < v.x1; x++ {
v.SetCell(x, v.y0, RuneEdgeHorizontal)
v.SetCell(x, v.y1, RuneEdgeHorizontal)
}
for y := v.y0 + 1; y < v.y1; y++ {
v.SetCell(v.x0, y, RuneEdgeVertical)
v.SetCell(v.x1, y, RuneEdgeVertical)
}
return nil
}
func (v *View) Resize() (err error) {
//TODO
return nil
}