gim: move line drawing code into terminal. drawing the line body is kind of busted, but whatever
This commit is contained in:
parent
a6d540f1fb
commit
ef48a2d708
68
gim/line.go
68
gim/line.go
@ -8,68 +8,26 @@ import (
|
|||||||
type line struct {
|
type line struct {
|
||||||
from, to *box
|
from, to *box
|
||||||
fromI, toI int
|
fromI, toI int
|
||||||
body string
|
bodyBuf *terminal.Buffer
|
||||||
}
|
|
||||||
|
|
||||||
// given the "primary" direction the line should be headed, picks a possible
|
|
||||||
// secondary one which may be used to detour along the path in order to reach
|
|
||||||
// the destination (in the case that the two boxes are diagonal from each other)
|
|
||||||
func secondaryDir(flowDir, start, end geo.XY) geo.XY {
|
|
||||||
var perpDir geo.XY
|
|
||||||
perpDir[0], perpDir[1] = flowDir[1], flowDir[0]
|
|
||||||
return end.Sub(start).Mul(perpDir.Abs()).Unit()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l line) draw(buf *terminal.Buffer, flowDir, secFlowDir geo.XY) {
|
func (l line) draw(buf *terminal.Buffer, flowDir, secFlowDir geo.XY) {
|
||||||
from, to := *(l.from), *(l.to)
|
from, to := *(l.from), *(l.to)
|
||||||
|
|
||||||
start := from.rect().Edge(flowDir, secFlowDir)[0].Add(secFlowDir.Scale(l.fromI*2 + 1))
|
start := from.rect().Edge(flowDir, secFlowDir)[0].Add(secFlowDir.Scale(l.fromI*2 + 1))
|
||||||
end := to.rect().Edge(flowDir.Inv(), secFlowDir)[0].Add(secFlowDir.Scale(l.toI*2 + 1))
|
end := to.rect().Edge(flowDir.Inv(), secFlowDir)[0]
|
||||||
dirSec := secondaryDir(flowDir, start, end)
|
end = end.Add(flowDir.Inv())
|
||||||
mid := start.Midpoint(end, rounder)
|
end = end.Add(secFlowDir.Scale(l.toI*2 + 1))
|
||||||
|
|
||||||
along := func(xy, dir geo.XY) int {
|
buf.SetPos(start)
|
||||||
if dir[0] != 0 {
|
buf.WriteRune(terminal.SingleLine.Perpendicular(flowDir))
|
||||||
return xy[0]
|
buf.DrawLine(start.Add(flowDir), end.Add(flowDir.Inv()), flowDir, terminal.SingleLine)
|
||||||
}
|
buf.SetPos(end)
|
||||||
return xy[1]
|
buf.WriteRune(terminal.SingleLine.Arrow(flowDir))
|
||||||
}
|
|
||||||
|
|
||||||
// collect the points along the line into an array
|
|
||||||
var pts []geo.XY
|
|
||||||
midPrim := along(mid, flowDir)
|
|
||||||
endSec := along(end, dirSec)
|
|
||||||
for curr := start; curr != end; {
|
|
||||||
pts = append(pts, curr)
|
|
||||||
if prim := along(curr, flowDir); prim == midPrim {
|
|
||||||
if sec := along(curr, dirSec); sec != endSec {
|
|
||||||
curr = curr.Add(dirSec)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curr = curr.Add(flowDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw each point
|
|
||||||
for i, pt := range pts {
|
|
||||||
var r rune
|
|
||||||
switch {
|
|
||||||
case i == 0:
|
|
||||||
r = terminal.SingleLine.Perpendicular(flowDir)
|
|
||||||
case i == len(pts)-1:
|
|
||||||
r = terminal.SingleLine.Arrow(flowDir)
|
|
||||||
default:
|
|
||||||
prev, next := pts[i-1], pts[i+1]
|
|
||||||
r = terminal.SingleLine.Segment(prev.Sub(pt), next.Sub(pt))
|
|
||||||
}
|
|
||||||
buf.SetPos(pt)
|
|
||||||
buf.WriteRune(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the body
|
// draw the body
|
||||||
if l.body != "" {
|
if l.bodyBuf != nil {
|
||||||
bodyPos := mid.Add(geo.Left.Scale(len(l.body) / 2))
|
mid := start.Midpoint(end, rounder)
|
||||||
buf.SetPos(bodyPos)
|
bodyBufRect := geo.Rect{Size: l.bodyBuf.Size()}
|
||||||
buf.WriteString(l.body)
|
buf.DrawBuffer(bodyBufRect.Centered(mid, rounder).TopLeft, l.bodyBuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,3 +133,60 @@ func (b *Buffer) DrawRect(r geo.Rect, ls LineStyle) {
|
|||||||
b.WriteString(horiz)
|
b.WriteString(horiz)
|
||||||
b.WriteRune(ls.BottomRight)
|
b.WriteRune(ls.BottomRight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DrawLine draws a line from the start point to the ending one, primarily
|
||||||
|
// moving in the given direction, using the given LineStyle to do so.
|
||||||
|
func (b *Buffer) DrawLine(start, end, dir geo.XY, ls LineStyle) {
|
||||||
|
// given the "primary" direction the line should be headed, pick a possible
|
||||||
|
// secondary one which may be used to detour along the path in order to
|
||||||
|
// reach the destination (in the case that the two boxes are diagonal from
|
||||||
|
// each other)
|
||||||
|
var perpDir geo.XY
|
||||||
|
perpDir[0], perpDir[1] = dir[1], dir[0]
|
||||||
|
dirSec := end.Sub(start).Mul(perpDir.Abs()).Unit()
|
||||||
|
|
||||||
|
// TODO gross that this doesn't have some way of discovering the rounder.
|
||||||
|
// Maybe rounder should just be a global? ugh...
|
||||||
|
mid := start.Midpoint(end, geo.Round)
|
||||||
|
|
||||||
|
along := func(xy, dir geo.XY) int {
|
||||||
|
if dir[0] != 0 {
|
||||||
|
return xy[0]
|
||||||
|
}
|
||||||
|
return xy[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect the points along the line into an array
|
||||||
|
var pts []geo.XY
|
||||||
|
var curr geo.XY
|
||||||
|
midPrim := along(mid, dir)
|
||||||
|
endSec := along(end, dirSec)
|
||||||
|
for curr = start; curr != end; {
|
||||||
|
pts = append(pts, curr)
|
||||||
|
if prim := along(curr, dir); prim == midPrim {
|
||||||
|
if sec := along(curr, dirSec); sec != endSec {
|
||||||
|
curr = curr.Add(dirSec)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curr = curr.Add(dir)
|
||||||
|
}
|
||||||
|
pts = append(pts, curr) // appending end
|
||||||
|
|
||||||
|
// draw each point
|
||||||
|
for i, pt := range pts {
|
||||||
|
var prev, next geo.XY
|
||||||
|
switch {
|
||||||
|
case i == 0:
|
||||||
|
prev = pt.Add(dir.Inv())
|
||||||
|
next = pts[i+1]
|
||||||
|
case i == len(pts)-1:
|
||||||
|
prev = pts[i-1]
|
||||||
|
next = pt.Add(dir)
|
||||||
|
default:
|
||||||
|
prev, next = pts[i-1], pts[i+1]
|
||||||
|
}
|
||||||
|
b.SetPos(pt)
|
||||||
|
b.WriteRune(ls.Segment(prev.Sub(pt), next.Sub(pt)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
12
gim/view.go
12
gim/view.go
@ -163,12 +163,14 @@ func (view *view) draw(buf *terminal.Buffer) {
|
|||||||
for i, e := range v.In {
|
for i, e := range v.In {
|
||||||
bFrom := boxesMr[e.From]
|
bFrom := boxesMr[e.From]
|
||||||
fromI := findFromI(e.From, e)
|
fromI := findFromI(e.From, e)
|
||||||
|
buf := terminal.NewBuffer()
|
||||||
|
buf.WriteString(e.Value.V.(string))
|
||||||
lines = append(lines, line{
|
lines = append(lines, line{
|
||||||
from: bFrom,
|
from: bFrom,
|
||||||
fromI: fromI,
|
fromI: fromI,
|
||||||
to: b,
|
to: b,
|
||||||
toI: i,
|
toI: i,
|
||||||
body: e.Value.V.(string),
|
bodyBuf: buf,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user