Skip to content

Commit

Permalink
Starting implementation of Windeau
Browse files Browse the repository at this point in the history
Basically just really simple windows with titles and easily
customizable borders. Wooooooo
  • Loading branch information
Chris Saunders committed Jun 14, 2014
0 parents commit d5642be
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 0 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Windeau

Windeau is a windowing/widgeting extension for termbox that came out
of the necessity for more flexible and controllable windows than just
what came with termbox.

Currently it just supports building empty windows that have titles.

You can see the windows in action by doing:

`go run _demos/windows.go`

Press the any key to quit the demo
54 changes: 54 additions & 0 deletions _demos/windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"github.com/csaunders/windeau"
"github.com/nsf/termbox-go"
)

func main() {
termbox.Init()
termbox.Clear(termbox.ColorGreen, termbox.ColorBlack)
defer termbox.Close()

border := windeau.MakeSimpleBorder('+', '|', '-')
window := &windeau.Window{X: 0, Y: 0, Width: 30, Height: 25, Fg: termbox.ColorGreen, Bg: termbox.ColorDefault, Border: border}
window.Title = "Hello World"
window.Draw()

fancyBorder := FancyBorder{TopLeft: '┏', TopRight: '┓', BottomLeft: '┗', BottomRight: '┛', Vertical: '┃', Horizontal: '━'}
fancyWindow := &windeau.Window{X: 40, Y: 20, Width: 40, Height: 30, Fg: termbox.ColorBlue, Bg: termbox.ColorDefault, Border: fancyBorder}
fancyWindow.Title = "Fancy Window"
fancyWindow.Draw()

termbox.Flush()

termbox.PollEvent()
}

type FancyBorder struct {
TopLeft, TopRight, BottomLeft, BottomRight rune
Vertical, Horizontal rune
}

func (f FancyBorder) Edge(x, y int, w windeau.Window) rune {
switch {
case x == w.X && y == w.Y:
return f.TopLeft
case x == w.X+w.Width-1 && y == w.Y:
return f.TopRight
case x == w.X && y == w.Y+w.Height-1:
return f.BottomLeft
case x == w.X+w.Width-1 && y == w.Y+w.Height-1:
return f.BottomRight
default:
return ' '
}
}

func (f FancyBorder) VerticalBorder() rune {
return f.Vertical
}

func (f FancyBorder) HorizontalBorder() rune {
return f.Horizontal
}
21 changes: 21 additions & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package windeau

type WindowBorder interface {
Edge(x, y int, window Window) rune
VerticalBorder() rune
HorizontalBorder() rune
}

type Drawable interface {
Draw()
}

type DataSource interface {
Entries() []string
Position() int
}

type EventHandler interface {
OnHighlight(context interface{})
OnSelect(context interface{})
}
98 changes: 98 additions & 0 deletions window.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package windeau

import "github.com/nsf/termbox-go"

type SimpleBorder struct {
edge, verticalBorder, horizontalBorder rune
}

func (sb SimpleBorder) Edge(x, y int, window Window) rune {
return sb.edge
}

func (sb SimpleBorder) VerticalBorder() rune {
return sb.verticalBorder
}

func (sb SimpleBorder) HorizontalBorder() rune {
return sb.horizontalBorder
}

func MakeSimpleBorder(edge, vertical, horizontal rune) SimpleBorder {
return SimpleBorder{edge: edge, verticalBorder: vertical, horizontalBorder: horizontal}
}

type PositionHandler func(x, y int)

func WalkRegion(x, y, w, h int, handler PositionHandler) {
for px := x; px < x+w; px++ {
for py := y; py < y+h; py++ {
handler(px, py)
}
}
}

type Window struct {
X, Y int
Width, Height int
Border WindowBorder
Title string
Fg, Bg termbox.Attribute
}

func (w *Window) Draw() {
w.drawBorder()
w.drawTitle()
}

func (w *Window) drawBorder() {
WalkRegion(w.X, w.Y, w.Width, w.Height, func(x, y int) {
var element rune
if w.isEdge(x, y) {
element = w.Border.Edge(x, y, *w)
} else if w.isTopOrBottom(x, y) {
element = w.Border.HorizontalBorder()
} else if w.isLeftOrRight(x, y) {
element = w.Border.VerticalBorder()
} else {
element = ' '
}
termbox.SetCell(x, y, element, w.Fg, w.Bg)
})
}

func (w *Window) drawTitle() {
title := w.Title
if len(title) > 0 {
if len(title) > w.titleWidth() {
title = title[0:w.titleWidth()]
}
for c := 0; c < len(title); c++ {
termbox.SetCell(c+w.X+w.titleStart(), w.Y, rune(title[c]), w.Fg, w.Bg)
}
}
}

func (w *Window) titleWidth() int {
return w.Width - w.titleStart() - w.titlePadding()
}

func (w *Window) titleStart() int {
return w.titlePadding()
}

func (w *Window) titlePadding() int {
return 2
}

func (w *Window) isEdge(x, y int) bool {
return w.isTopOrBottom(x, y) && w.isLeftOrRight(x, y)
}

func (w *Window) isTopOrBottom(x, y int) bool {
return y == w.Y || y == w.Y+w.Height-1
}

func (w *Window) isLeftOrRight(x, y int) bool {
return x == w.X || x == w.X+w.Width-1
}

0 comments on commit d5642be

Please sign in to comment.