gim: refactor positioning and drawing code to take advantage of terminal buffers more
This commit is contained in:
parent
b906697151
commit
a6d540f1fb
48
gim/box.go
48
gim/box.go
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/mediocregopher/ginger/gg"
|
"github.com/mediocregopher/ginger/gg"
|
||||||
"github.com/mediocregopher/ginger/gim/geo"
|
"github.com/mediocregopher/ginger/gim/geo"
|
||||||
@ -13,7 +12,7 @@ type box struct {
|
|||||||
topLeft geo.XY
|
topLeft geo.XY
|
||||||
flowDir geo.XY
|
flowDir geo.XY
|
||||||
numIn, numOut int
|
numIn, numOut int
|
||||||
body string
|
bodyBuf *terminal.Buffer
|
||||||
|
|
||||||
transparent bool
|
transparent bool
|
||||||
}
|
}
|
||||||
@ -25,37 +24,16 @@ func boxFromVertex(v *gg.Vertex, flowDir geo.XY) box {
|
|||||||
numOut: len(v.Out),
|
numOut: len(v.Out),
|
||||||
}
|
}
|
||||||
if v.VertexType == gg.ValueVertex {
|
if v.VertexType == gg.ValueVertex {
|
||||||
b.body = v.Value.V.(string)
|
b.bodyBuf = terminal.NewBuffer()
|
||||||
|
b.bodyBuf.WriteString(v.Value.V.(string))
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b box) bodyLines() []string {
|
|
||||||
lines := strings.Split(b.body, "\n")
|
|
||||||
// if the last line is empty don't include it, it means there was a trailing
|
|
||||||
// newline (or the whole string is empty)
|
|
||||||
if lines[len(lines)-1] == "" {
|
|
||||||
lines = lines[:len(lines)-1]
|
|
||||||
}
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this is utterly broken, the terminal.Buffer should be used for this
|
|
||||||
func (b box) bodySize() geo.XY {
|
|
||||||
var size geo.XY
|
|
||||||
for _, line := range b.bodyLines() {
|
|
||||||
size[1]++
|
|
||||||
if l := len(line); l > size[0] {
|
|
||||||
size[0] = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b box) rect() geo.Rect {
|
func (b box) rect() geo.Rect {
|
||||||
bodyRect := geo.Rect{
|
var bodyRect geo.Rect
|
||||||
Size: b.bodySize().Add(geo.XY{2, 2}),
|
if b.bodyBuf != nil {
|
||||||
|
bodyRect.Size = b.bodyBuf.Size().Add(geo.XY{2, 2})
|
||||||
}
|
}
|
||||||
|
|
||||||
var edgesRect geo.Rect
|
var edgesRect geo.Rect
|
||||||
@ -80,19 +58,13 @@ func (b box) rect() geo.Rect {
|
|||||||
return bodyRect.Union(edgesRect).Translate(b.topLeft)
|
return bodyRect.Union(edgesRect).Translate(b.topLeft)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b box) bodyRect() geo.Rect {
|
|
||||||
center := b.rect().Center(rounder)
|
|
||||||
return geo.Rect{Size: b.bodySize()}.Centered(center, rounder)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b box) draw(buf *terminal.Buffer) {
|
func (b box) draw(buf *terminal.Buffer) {
|
||||||
bodyBuf := terminal.NewBuffer()
|
|
||||||
bodyBuf.WriteString(b.body)
|
|
||||||
bodyBufRect := geo.Rect{Size: bodyBuf.Size()}
|
|
||||||
|
|
||||||
rect := b.rect()
|
rect := b.rect()
|
||||||
buf.DrawRect(rect, terminal.SingleLine)
|
buf.DrawRect(rect, terminal.SingleLine)
|
||||||
|
|
||||||
|
if b.bodyBuf != nil {
|
||||||
center := rect.Center(rounder)
|
center := rect.Center(rounder)
|
||||||
buf.DrawBuffer(bodyBufRect.Centered(center, rounder).TopLeft, bodyBuf)
|
bodyBufRect := geo.Rect{Size: b.bodyBuf.Size()}
|
||||||
|
buf.DrawBuffer(bodyBufRect.Centered(center, rounder).TopLeft, b.bodyBuf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,7 @@ func main() {
|
|||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
term := terminal.New()
|
term := terminal.New()
|
||||||
wSize := term.WindowSize()
|
wSize := term.WindowSize()
|
||||||
|
center := geo.Zero.Midpoint(wSize, rounder)
|
||||||
|
|
||||||
g, start := mkGraph()
|
g, start := mkGraph()
|
||||||
v := view{
|
v := view{
|
||||||
@ -88,11 +89,14 @@ func main() {
|
|||||||
primFlowDir: geo.Right,
|
primFlowDir: geo.Right,
|
||||||
secFlowDir: geo.Down,
|
secFlowDir: geo.Down,
|
||||||
start: start,
|
start: start,
|
||||||
center: geo.Zero.Midpoint(wSize, rounder),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf := terminal.NewBuffer()
|
||||||
|
v.draw(buf)
|
||||||
|
bufRect := geo.Rect{Size: buf.Size()}.Centered(center, rounder)
|
||||||
|
|
||||||
term.Clear()
|
term.Clear()
|
||||||
v.draw(term)
|
term.WriteBuffer(bufRect.TopLeft, buf)
|
||||||
term.SetPos(wSize.Add(geo.XY{0, -1}))
|
term.SetPos(wSize.Add(geo.XY{0, -1}))
|
||||||
term.Draw()
|
term.Draw()
|
||||||
}
|
}
|
||||||
|
26
gim/view.go
26
gim/view.go
@ -86,28 +86,13 @@ func posSolve(g *gg.Graph) ([][]*gg.Vertex, map[string]int, map[string]int) {
|
|||||||
return out, prim, sec
|
return out, prim, sec
|
||||||
}
|
}
|
||||||
|
|
||||||
// mutates the boxes to be centered around the given point, keeping their
|
|
||||||
// relative position to each other
|
|
||||||
func centerBoxes(boxes []*box, around geo.XY) {
|
|
||||||
var graphRect geo.Rect
|
|
||||||
for _, b := range boxes {
|
|
||||||
graphRect = graphRect.Union(b.rect())
|
|
||||||
}
|
|
||||||
graphMid := graphRect.Center(rounder)
|
|
||||||
delta := around.Sub(graphMid)
|
|
||||||
for _, b := range boxes {
|
|
||||||
b.topLeft = b.topLeft.Add(delta)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type view struct {
|
type view struct {
|
||||||
g *gg.Graph
|
g *gg.Graph
|
||||||
primFlowDir, secFlowDir geo.XY
|
primFlowDir, secFlowDir geo.XY
|
||||||
start gg.Value
|
start gg.Value
|
||||||
center geo.XY // TODO this shouldnt be needed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (view *view) draw(term *terminal.Terminal) {
|
func (view *view) draw(buf *terminal.Buffer) {
|
||||||
relPos, _, secSol := posSolve(view.g)
|
relPos, _, secSol := posSolve(view.g)
|
||||||
|
|
||||||
// create boxes
|
// create boxes
|
||||||
@ -142,7 +127,9 @@ func (view *view) draw(term *terminal.Terminal) {
|
|||||||
}
|
}
|
||||||
secPos += secBoxLen + secPadding
|
secPos += secBoxLen + secPadding
|
||||||
}
|
}
|
||||||
centerBoxes(primBoxes, view.primFlowDir.Scale(primPos))
|
for _, b := range primBoxes {
|
||||||
|
b.topLeft = b.topLeft.Add(view.primFlowDir.Scale(primPos))
|
||||||
|
}
|
||||||
primPos += maxPrim + primPadding
|
primPos += maxPrim + primPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,16 +173,11 @@ func (view *view) draw(term *terminal.Terminal) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate all boxes so the graph is centered around v.center
|
|
||||||
centerBoxes(boxes, view.center)
|
|
||||||
|
|
||||||
// actually draw the boxes and lines
|
// actually draw the boxes and lines
|
||||||
buf := terminal.NewBuffer()
|
|
||||||
for _, b := range boxes {
|
for _, b := range boxes {
|
||||||
b.draw(buf)
|
b.draw(buf)
|
||||||
}
|
}
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
line.draw(buf, view.primFlowDir, view.secFlowDir)
|
line.draw(buf, view.primFlowDir, view.secFlowDir)
|
||||||
}
|
}
|
||||||
term.WriteBuffer(geo.Zero, buf)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user