Files
chronos/src/sequence.typ
T
2024-06-18 23:01:53 +02:00

180 lines
3.7 KiB
Typst

#import "@preview/cetz:0.2.2": draw
#import "consts.typ": *
#import "participant.typ"
#let _seq(
p1,
p2,
comment: none,
dashed: false,
tip: "default",
color: black,
flip: false,
enable-dst: false,
create-dst: false,
disable-dst: false,
destroy-dst: false,
disable-src: false,
destroy-src: false,
lifeline-style: auto
) = {
return ((
type: "seq",
p1: p1,
p2: p2,
comment: comment,
dashed: dashed,
tip: tip,
color: color,
flip: flip,
enable-dst: enable-dst,
create-dst: create-dst,
disable-dst: disable-dst,
destroy-dst: destroy-dst,
disable-src: disable-src,
destroy-src: destroy-src,
lifeline-style: lifeline-style,
),)
}
#let render(pars-i, x-pos, participants, elmt, y, lifelines) = {
let shapes = ()
// Reserve space for comment
if elmt.comment != none {
y -= measure(box(elmt.comment)).height / 1pt + 6
}
let i1 = pars-i.at(elmt.p1)
let i2 = pars-i.at(elmt.p2)
let start-info = (
i: i1,
x: x-pos.at(i1),
y: y,
ll-lvl: lifelines.at(i1).level * LIFELINE-W / 2
)
let end-info = (
i: i2,
x: x-pos.at(i2),
y: y,
ll-lvl: lifelines.at(i2).level * LIFELINE-W / 2
)
let ll-lvl1 = lifelines.at(i1).level * LIFELINE-W / 2
let x1 = x-pos.at(i1)
let x2 = x-pos.at(i2)
if elmt.disable-src {
let src-line = lifelines.at(i1)
src-line.level -= 1
src-line.lines.push(("disable", y))
lifelines.at(i1) = src-line
}
if elmt.destroy-src {
let src-line = lifelines.at(i1)
src-line.lines.push(("destroy", y))
lifelines.at(i1) = src-line
}
if elmt.disable-dst {
let dst-line = lifelines.at(i2)
dst-line.level -= 1
dst-line.lines.push(("disable", y))
lifelines.at(i2) = dst-line
}
if elmt.destroy-dst {
let dst-line = lifelines.at(i2)
dst-line.lines.push(("destroy", y))
lifelines.at(i2) = dst-line
}
if elmt.enable-dst {
let dst-line = lifelines.at(i2)
dst-line.level += 1
lifelines.at(i2) = dst-line
}
if elmt.create-dst {
let par = participants.at(i2)
let m = measure(box(par.display-name))
x2 -= (m.width + PAR-PAD.last() * 2) / 2pt
shapes += participant.render(x-pos, par, y: y)
}
end-info.ll-lvl = lifelines.at(i2).level * LIFELINE-W / 2
let ll-lvl2 = lifelines.at(i2).level * LIFELINE-W / 2
let f = if elmt.flip {-1} else {1}
if i1 <= i2 {
x1 += ll-lvl1 * f
x2 -= ll-lvl2 * f
} else {
x1 -= ll-lvl1 * f
x2 += ll-lvl2 * f
}
let style = (
mark: (end: "straight"),
stroke: (
dash: if elmt.dashed {"dashed"} else {"solid"},
paint: elmt.color
)
)
if elmt.p1 == elmt.p2 {
let x3 = x1 - ll-lvl1 + ll-lvl2
x2 = if elmt.flip {x1 - 20} else {x1 + 20}
if elmt.comment != none {
shapes += draw.content(
(x1, y),
elmt.comment,
anchor: if elmt.flip {"south-east"} else {"south-west"},
padding: 3pt
)
}
shapes += draw.line(
(x1, y),
(x2, y),
(x2, y - 10),
(x3, y - 10),
..style
)
y -= 10
} else {
if elmt.comment != none {
let x = calc.min(x1, x2)
if x2 < x1 {
x += COMMENT-PAD
}
shapes += draw.content(
(x, y),
elmt.comment,
anchor: "south-west",
padding: 3pt
)
}
shapes += draw.line(
(x1, y),
(x2, y),
..style
)
}
if elmt.enable-dst {
let dst-line = lifelines.at(i2)
dst-line.lines.push(("enable", y, elmt.lifeline-style))
lifelines.at(i2) = dst-line
}
if elmt.create-dst {
let dst-line = lifelines.at(i2)
dst-line.lines.push(("create", y))
lifelines.at(i2) = dst-line
}
y -= Y-SPACE
let r = (y, lifelines, shapes)
return r
}