refactored groups, separators and delays
This commit is contained in:
27
src/core/draw/delay.typ
Normal file
27
src/core/draw/delay.typ
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#import "../utils.typ": get-ctx, set-ctx
|
||||||
|
#import "../../cetz.typ": draw
|
||||||
|
|
||||||
|
#let render(delay) = get-ctx(ctx => {
|
||||||
|
let y0 = ctx.y
|
||||||
|
let y1 = ctx.y - delay.size
|
||||||
|
for (i, line) in ctx.lifelines.enumerate() {
|
||||||
|
line.lines.push(("delay-start", y0))
|
||||||
|
line.lines.push(("delay-end", y1))
|
||||||
|
ctx.lifelines.at(i) = line
|
||||||
|
}
|
||||||
|
if delay.name != none {
|
||||||
|
let x0 = ctx.x-pos.first()
|
||||||
|
let x1 = ctx.x-pos.last()
|
||||||
|
draw.content(
|
||||||
|
((x0 + x1) / 2, (y0 + y1) / 2),
|
||||||
|
anchor: "center",
|
||||||
|
delay.name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
ctx.y = y1
|
||||||
|
set-ctx(c => {
|
||||||
|
c.y = ctx.y
|
||||||
|
c.lifelines = ctx.lifelines
|
||||||
|
return c
|
||||||
|
})
|
||||||
|
})
|
120
src/core/draw/group.typ
Normal file
120
src/core/draw/group.typ
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#import "../utils.typ": get-ctx, set-ctx
|
||||||
|
#import "../../consts.typ": *
|
||||||
|
#import "../../cetz.typ": draw
|
||||||
|
|
||||||
|
#let render-start(grp) = get-ctx(ctx => {
|
||||||
|
let grp = grp
|
||||||
|
ctx.y -= Y-SPACE
|
||||||
|
let m = measure(
|
||||||
|
box(
|
||||||
|
grp.name,
|
||||||
|
inset: (
|
||||||
|
left: 5pt,
|
||||||
|
right: 5pt,
|
||||||
|
top: 3pt,
|
||||||
|
bottom: 3pt
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
ctx.groups = ctx.groups.map(g => {
|
||||||
|
if g.at(1).min-i == grp.min-i { g.at(2) += 1 }
|
||||||
|
if g.at(1).max-i == grp.max-i { g.at(3) += 1 }
|
||||||
|
g
|
||||||
|
})
|
||||||
|
if grp.grp-type == "alt" {
|
||||||
|
grp.insert("elses", ())
|
||||||
|
}
|
||||||
|
ctx.groups.push((ctx.y, grp, 0, 0))
|
||||||
|
ctx.y -= m.height / 1pt
|
||||||
|
|
||||||
|
set-ctx(c => {
|
||||||
|
c.y = ctx.y
|
||||||
|
c.groups = ctx.groups
|
||||||
|
return c
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
#let draw-group(x0, x1, y0, y1, group) = {
|
||||||
|
let name = text(group.name, weight: "bold")
|
||||||
|
let m = measure(box(name))
|
||||||
|
let w = m.width / 1pt + 15
|
||||||
|
let h = m.height / 1pt + 6
|
||||||
|
draw.rect(
|
||||||
|
(x0, y0),
|
||||||
|
(x1, y1)
|
||||||
|
)
|
||||||
|
draw.merge-path(
|
||||||
|
fill: COL-GRP-NAME,
|
||||||
|
close: true,
|
||||||
|
{
|
||||||
|
draw.line(
|
||||||
|
(x0, y0),
|
||||||
|
(x0 + w, y0),
|
||||||
|
(x0 + w, y0 - h / 2),
|
||||||
|
(x0 + w - 5, y0 - h),
|
||||||
|
(x0, y0 - h)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
draw.content(
|
||||||
|
(x0, y0),
|
||||||
|
name,
|
||||||
|
anchor: "north-west",
|
||||||
|
padding: (left: 5pt, right: 10pt, top: 3pt, bottom: 3pt)
|
||||||
|
)
|
||||||
|
|
||||||
|
if group.desc != none {
|
||||||
|
draw.content(
|
||||||
|
(x0 + w, y0),
|
||||||
|
text([\[#group.desc\]], weight: "bold", size: .8em),
|
||||||
|
anchor: "north-west",
|
||||||
|
padding: 3pt
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let draw-else(x0, x1, y, elmt) = {
|
||||||
|
draw.line(
|
||||||
|
(x0, y),
|
||||||
|
(x1, y),
|
||||||
|
stroke: (dash: (2pt, 1pt), thickness: .5pt)
|
||||||
|
)
|
||||||
|
draw.content(
|
||||||
|
(x0, y),
|
||||||
|
text([\[#elmt.desc\]], weight: "bold", size: .8em),
|
||||||
|
anchor: "north-west",
|
||||||
|
padding: 3pt
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let render-end(group) = get-ctx(ctx => {
|
||||||
|
ctx.y -= Y-SPACE
|
||||||
|
let (start-y, group, start-lvl, end-lvl) = ctx.groups.pop()
|
||||||
|
let x0 = ctx.x-pos.at(group.min-i) - start-lvl * 10 - 20
|
||||||
|
let x1 = ctx.x-pos.at(group.max-i) + end-lvl * 10 + 20
|
||||||
|
|
||||||
|
draw-group(x0, x1, start-y, ctx.y, group)
|
||||||
|
|
||||||
|
if group.grp-type == "alt" {
|
||||||
|
for (else-y, else-elmt) in group.elses {
|
||||||
|
draw-else(x0, x1, else-y, else-elmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set-ctx(c => {
|
||||||
|
c.y = ctx.y
|
||||||
|
c.groups = ctx.groups
|
||||||
|
return c
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
#let render-else(else_) = set-ctx(ctx => {
|
||||||
|
ctx.y -= Y-SPACE
|
||||||
|
let m = measure(text([\[#else_.desc\]], weight: "bold", size: .8em))
|
||||||
|
ctx.groups.last().at(1).elses.push((
|
||||||
|
ctx.y, else_
|
||||||
|
))
|
||||||
|
ctx.y -= m.height / 1pt
|
||||||
|
return ctx
|
||||||
|
})
|
46
src/core/draw/separator.typ
Normal file
46
src/core/draw/separator.typ
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#import "../utils.typ": get-ctx, set-ctx
|
||||||
|
#import "../../consts.typ": *
|
||||||
|
#import "../../cetz.typ": draw
|
||||||
|
|
||||||
|
#let render(sep) = get-ctx(ctx => {
|
||||||
|
ctx.y -= Y-SPACE
|
||||||
|
|
||||||
|
let x0 = ctx.x-pos.first() - 20
|
||||||
|
let x1 = ctx.x-pos.last() + 20
|
||||||
|
let m = measure(
|
||||||
|
box(
|
||||||
|
sep.name,
|
||||||
|
inset: (left: 3pt, right: 3pt, top: 5pt, bottom: 5pt)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
let w = m.width / 1pt
|
||||||
|
let h = m.height / 1pt
|
||||||
|
let cx = (x0 + x1) / 2
|
||||||
|
let xl = cx - w / 2
|
||||||
|
let xr = cx + w / 2
|
||||||
|
|
||||||
|
ctx.y -= h / 2
|
||||||
|
draw.rect(
|
||||||
|
(x0, ctx.y),
|
||||||
|
(x1, ctx.y - 3),
|
||||||
|
stroke: none,
|
||||||
|
fill: white
|
||||||
|
)
|
||||||
|
draw.line((x0, ctx.y), (x1, ctx.y))
|
||||||
|
ctx.y -= 3
|
||||||
|
draw.line((x0, ctx.y), (x1, ctx.y))
|
||||||
|
draw.content(
|
||||||
|
((x0 + x1) / 2, ctx.y + 1.5),
|
||||||
|
sep.name,
|
||||||
|
anchor: "center",
|
||||||
|
padding: (5pt, 3pt),
|
||||||
|
frame: "rect",
|
||||||
|
fill: COL-SEP-NAME
|
||||||
|
)
|
||||||
|
ctx.y -= h / 2
|
||||||
|
|
||||||
|
set-ctx(c => {
|
||||||
|
c.y = ctx.y
|
||||||
|
return c
|
||||||
|
})
|
||||||
|
})
|
@ -354,7 +354,6 @@
|
|||||||
},)
|
},)
|
||||||
|
|
||||||
#let render(participants, elements) = context canvas(length: 1pt, {
|
#let render(participants, elements) = context canvas(length: 1pt, {
|
||||||
let shapes = ()
|
|
||||||
setup-ctx(participants, elements)
|
setup-ctx(participants, elements)
|
||||||
|
|
||||||
// Draw participants (start)
|
// Draw participants (start)
|
||||||
@ -372,80 +371,6 @@
|
|||||||
(elmt,)
|
(elmt,)
|
||||||
} else if "draw" in elmt and elmt.type != "par" {
|
} else if "draw" in elmt and elmt.type != "par" {
|
||||||
(elmt.draw)(elmt)
|
(elmt.draw)(elmt)
|
||||||
|
|
||||||
// Groups (start) -> reserve space for labels + store position
|
|
||||||
} else if elmt.type == "grp" {
|
|
||||||
y -= Y-SPACE
|
|
||||||
let m = measure(
|
|
||||||
box(
|
|
||||||
elmt.name,
|
|
||||||
inset: (
|
|
||||||
left: 5pt,
|
|
||||||
right: 5pt,
|
|
||||||
top: 3pt,
|
|
||||||
bottom: 3pt
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
groups = groups.map(g => {
|
|
||||||
if g.at(1).min-i == elmt.min-i { g.at(2) += 1 }
|
|
||||||
if g.at(1).max-i == elmt.max-i { g.at(3) += 1 }
|
|
||||||
g
|
|
||||||
})
|
|
||||||
if elmt.grp-type == "alt" {
|
|
||||||
elmt.insert("elses", ())
|
|
||||||
}
|
|
||||||
groups.push((y, elmt, 0, 0))
|
|
||||||
y -= m.height / 1pt
|
|
||||||
|
|
||||||
// Groups (end) -> actual drawing
|
|
||||||
} else if elmt.type == "grp-end" {
|
|
||||||
y -= Y-SPACE
|
|
||||||
let (start-y, group, start-lvl, end-lvl) = groups.pop()
|
|
||||||
let x0 = x-pos.at(group.min-i) - start-lvl * 10 - 20
|
|
||||||
let x1 = x-pos.at(group.max-i) + end-lvl * 10 + 20
|
|
||||||
shapes += draw-group(x0, x1, start-y, y, group)
|
|
||||||
|
|
||||||
if group.grp-type == "alt" {
|
|
||||||
for (else-y, else-elmt) in group.elses {
|
|
||||||
shapes += draw-else(x0, x1, else-y, else-elmt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alt's elses -> reserve space for label + store position
|
|
||||||
} else if elmt.type == "else" {
|
|
||||||
y -= Y-SPACE
|
|
||||||
let m = measure(text([\[#elmt.desc\]], weight: "bold", size: .8em))
|
|
||||||
groups.last().at(1).elses.push((
|
|
||||||
y, elmt
|
|
||||||
))
|
|
||||||
y -= m.height / 1pt
|
|
||||||
|
|
||||||
// Separator
|
|
||||||
} else if elmt.type == "sep" {
|
|
||||||
let shps
|
|
||||||
(y, shps) = draw-sep(elmt, y)
|
|
||||||
shapes += shps
|
|
||||||
|
|
||||||
// Delay
|
|
||||||
} else if elmt.type == "delay" {
|
|
||||||
let y0 = y
|
|
||||||
let y1 = y - elmt.size
|
|
||||||
for (i, line) in lifelines.enumerate() {
|
|
||||||
line.lines.push(("delay-start", y0))
|
|
||||||
line.lines.push(("delay-end", y1))
|
|
||||||
lifelines.at(i) = line
|
|
||||||
}
|
|
||||||
if elmt.name != none {
|
|
||||||
let x0 = x-pos.first()
|
|
||||||
let x1 = x-pos.last()
|
|
||||||
shapes += draw.content(
|
|
||||||
((x0 + x1) / 2, (y0 + y1) / 2),
|
|
||||||
anchor: "center",
|
|
||||||
elmt.name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
y = y1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,6 +401,4 @@
|
|||||||
|
|
||||||
participant.render-lifelines()
|
participant.render-lifelines()
|
||||||
})
|
})
|
||||||
|
|
||||||
shapes
|
|
||||||
})
|
})
|
@ -1,5 +1,6 @@
|
|||||||
#import "utils.typ": is-elmt, get-group-span
|
#import "utils.typ": is-elmt, get-group-span
|
||||||
#import "../participant.typ": _exists as par-exists, _par
|
#import "../participant.typ": _exists as par-exists, _par
|
||||||
|
#import "draw/group.typ": render-end as grp-render-end
|
||||||
|
|
||||||
#let flatten-group(elmts, i) = {
|
#let flatten-group(elmts, i) = {
|
||||||
let group = elmts.at(i)
|
let group = elmts.at(i)
|
||||||
@ -9,6 +10,7 @@
|
|||||||
group.elmts +
|
group.elmts +
|
||||||
((
|
((
|
||||||
type: "grp-end",
|
type: "grp-end",
|
||||||
|
draw: grp-render-end,
|
||||||
start-i: i
|
start-i: i
|
||||||
),) +
|
),) +
|
||||||
elmts.slice(i+1)
|
elmts.slice(i+1)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
#import "/src/cetz.typ": draw
|
#import "/src/cetz.typ": draw
|
||||||
#import "consts.typ": *
|
#import "consts.typ": *
|
||||||
|
#import "core/draw/group.typ"
|
||||||
|
|
||||||
#let _grp(name, desc: none, type: "default", elmts) = {
|
#let _grp(name, desc: none, type: "default", elmts) = {
|
||||||
return ((
|
return ((
|
||||||
type: "grp",
|
type: "grp",
|
||||||
|
draw: group.render-start,
|
||||||
name: name,
|
name: name,
|
||||||
desc: desc,
|
desc: desc,
|
||||||
grp-type: type,
|
grp-type: type,
|
||||||
@ -20,6 +22,7 @@
|
|||||||
let else-elmts = args.at(i + 1, default: ())
|
let else-elmts = args.at(i + 1, default: ())
|
||||||
all-elmts.push((
|
all-elmts.push((
|
||||||
type: "else",
|
type: "else",
|
||||||
|
draw: group.render-else,
|
||||||
desc: else-desc
|
desc: else-desc
|
||||||
))
|
))
|
||||||
all-elmts += else-elmts
|
all-elmts += else-elmts
|
||||||
@ -40,60 +43,3 @@
|
|||||||
}
|
}
|
||||||
#let _opt(desc, elmts) = grp("opt", desc: desc, type: "opt", elmts)
|
#let _opt(desc, elmts) = grp("opt", desc: desc, type: "opt", elmts)
|
||||||
#let _break(desc, elmts) = grp("break", desc: desc, type: "break", elmts)
|
#let _break(desc, elmts) = grp("break", desc: desc, type: "break", elmts)
|
||||||
|
|
||||||
#let render(x0, x1, y0, y1, group) = {
|
|
||||||
let shapes = ()
|
|
||||||
let name = text(group.name, weight: "bold")
|
|
||||||
let m = measure(box(name))
|
|
||||||
let w = m.width / 1pt + 15
|
|
||||||
let h = m.height / 1pt + 6
|
|
||||||
shapes += draw.rect(
|
|
||||||
(x0, y0),
|
|
||||||
(x1, y1)
|
|
||||||
)
|
|
||||||
shapes += draw.merge-path(
|
|
||||||
fill: COL-GRP-NAME,
|
|
||||||
close: true,
|
|
||||||
{
|
|
||||||
draw.line(
|
|
||||||
(x0, y0),
|
|
||||||
(x0 + w, y0),
|
|
||||||
(x0 + w, y0 - h / 2),
|
|
||||||
(x0 + w - 5, y0 - h),
|
|
||||||
(x0, y0 - h)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
shapes += draw.content(
|
|
||||||
(x0, y0),
|
|
||||||
name,
|
|
||||||
anchor: "north-west",
|
|
||||||
padding: (left: 5pt, right: 10pt, top: 3pt, bottom: 3pt)
|
|
||||||
)
|
|
||||||
|
|
||||||
if group.desc != none {
|
|
||||||
shapes += draw.content(
|
|
||||||
(x0 + w, y0),
|
|
||||||
text([\[#group.desc\]], weight: "bold", size: .8em),
|
|
||||||
anchor: "north-west",
|
|
||||||
padding: 3pt
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return shapes
|
|
||||||
}
|
|
||||||
|
|
||||||
#let render-else(x0, x1, y, elmt) = {
|
|
||||||
let shapes = draw.line(
|
|
||||||
(x0, y),
|
|
||||||
(x1, y),
|
|
||||||
stroke: (dash: (2pt, 1pt), thickness: .5pt)
|
|
||||||
)
|
|
||||||
shapes += draw.content(
|
|
||||||
(x0, y),
|
|
||||||
text([\[#elmt.desc\]], weight: "bold", size: .8em),
|
|
||||||
anchor: "north-west",
|
|
||||||
padding: 3pt
|
|
||||||
)
|
|
||||||
return shapes
|
|
||||||
}
|
|
@ -1,9 +1,12 @@
|
|||||||
#import "/src/cetz.typ": draw
|
#import "/src/cetz.typ": draw
|
||||||
#import "consts.typ": *
|
#import "consts.typ": *
|
||||||
|
#import "core/draw/separator.typ"
|
||||||
|
#import "core/draw/delay.typ"
|
||||||
|
|
||||||
#let _sep(name) = {
|
#let _sep(name) = {
|
||||||
return ((
|
return ((
|
||||||
type: "sep",
|
type: "sep",
|
||||||
|
draw: separator.render,
|
||||||
name: name
|
name: name
|
||||||
),)
|
),)
|
||||||
}
|
}
|
||||||
@ -11,53 +14,8 @@
|
|||||||
#let _delay(name: none, size: 30) = {
|
#let _delay(name: none, size: 30) = {
|
||||||
return ((
|
return ((
|
||||||
type: "delay",
|
type: "delay",
|
||||||
|
draw: delay.render,
|
||||||
name: name,
|
name: name,
|
||||||
size: size
|
size: size
|
||||||
),)
|
),)
|
||||||
}
|
}
|
||||||
|
|
||||||
#let render(x-pos, elmt, y) = {
|
|
||||||
let shapes = ()
|
|
||||||
y -= Y-SPACE
|
|
||||||
|
|
||||||
let x0 = x-pos.first() - 20
|
|
||||||
let x1 = x-pos.last() + 20
|
|
||||||
let m = measure(
|
|
||||||
box(
|
|
||||||
elmt.name,
|
|
||||||
inset: (left: 3pt, right: 3pt, top: 5pt, bottom: 5pt)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
let w = m.width / 1pt
|
|
||||||
let h = m.height / 1pt
|
|
||||||
let cx = (x0 + x1) / 2
|
|
||||||
let xl = cx - w / 2
|
|
||||||
let xr = cx + w / 2
|
|
||||||
|
|
||||||
y -= h / 2
|
|
||||||
shapes += draw.rect(
|
|
||||||
(x0, y),
|
|
||||||
(x1, y - 3),
|
|
||||||
stroke: none,
|
|
||||||
fill: white
|
|
||||||
)
|
|
||||||
shapes += draw.line((x0, y), (x1, y))
|
|
||||||
//shapes += draw.line((x0, y), (xl, y))
|
|
||||||
//shapes += draw.line((xr, y), (x1, y))
|
|
||||||
y -= 3
|
|
||||||
shapes += draw.line((x0, y), (x1, y))
|
|
||||||
//shapes += draw.line((x0, y), (xl, y))
|
|
||||||
//shapes += draw.line((xr, y), (x1, y))
|
|
||||||
shapes += draw.content(
|
|
||||||
((x0 + x1) / 2, y + 1.5),
|
|
||||||
elmt.name,
|
|
||||||
anchor: "center",
|
|
||||||
padding: (5pt, 3pt),
|
|
||||||
frame: "rect",
|
|
||||||
fill: COL-SEP-NAME
|
|
||||||
)
|
|
||||||
y -= h / 2
|
|
||||||
|
|
||||||
let r = (y, shapes)
|
|
||||||
return r
|
|
||||||
}
|
|
Reference in New Issue
Block a user