implemented aligned notes

This commit is contained in:
Louis Heredero 2024-06-21 17:26:50 +02:00
parent f08f30b9e2
commit 0cff9d6799
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
5 changed files with 94 additions and 12 deletions

Binary file not shown.

View File

@ -74,10 +74,19 @@
#chronos.diagram({ #chronos.diagram({
_par("a", display-name: "Alice") _par("a", display-name: "Alice")
_par("b", display-name: "Bob") _par("b", display-name: "Bob")
_par("c", display-name: "Charlie")
_par("d", display-name: "Donald")
_par("e", display-name: "Eddie")
_note("over", [initial state of Alice], pos: "a") _note("over", [initial state of Alice], pos: "a")
_note("over", [initial state of Bob], pos: "b", aligned: true) _note("over", [initial state of Bob the builder], pos: "b", aligned: true)
_seq("b", "a", comment: [hello])
_note("over", [Note 1], pos: "a")
_note("over", [Note 2], pos: "b", aligned: true)
_note("over", [Note 3], pos: "c", aligned: true)
_seq("a", "d")
_note("over", [this is an extremely long note], pos: ("d", "e"))
}) })
#pagebreak() #pagebreak()
@ -112,3 +121,18 @@
#underline([This is hosted], stroke: rgb("#FF33FF")) by #box(baseline: 50%, image("gitea.png", width: 1cm, height: 1cm, fit: "contain")) #underline([This is hosted], stroke: rgb("#FF33FF")) by #box(baseline: 50%, image("gitea.png", width: 1cm, height: 1cm, fit: "contain"))
], pos: ("a", "b")) ], pos: ("a", "b"))
}) })
// TODO
/*
#pagebreak()
#chronos.diagram({
_par("a", display-name: [Alice])
_par("b", display-name: [Bob])
_seq("a", "b", comment: [Hello])
_note("left", [This is a note])
_seq("[", "a", comment: [Test])
_note("left", [This is also a note])
})*/

View File

@ -58,6 +58,7 @@
// List participants // List participants
let linked = () let linked = ()
let last-seq = none let last-seq = none
let last-note = none
for (i, elmt) in elmts.enumerate() { for (i, elmt) in elmts.enumerate() {
if elmt.type == "par" { if elmt.type == "par" {
participants.push(elmt) participants.push(elmt)
@ -107,12 +108,21 @@
seq.insert("linked-note", elmt) seq.insert("linked-note", elmt)
elmts.at(last-seq.i) = seq elmts.at(last-seq.i) = seq
} }
if elmt.aligned {
let n = last-note.elmt
n.aligned-with = elmt
elmts.at(last-note.i) = n
}
elmts.at(i) = elmt elmts.at(i) = elmt
if elmt.side == "left" { if elmt.side == "left" {
linked.push("[") linked.push("[")
} else if elmt.side == "right" { } else if elmt.side == "right" {
linked.push("]") linked.push("]")
} }
last-note = (
elmt: elmt,
i: i
)
} }
} }
linked = linked.dedup() linked = linked.dedup()

View File

@ -15,6 +15,16 @@
) )
#let _note(side, content, pos: none, color: COL-NOTE, shape: "default", aligned: false) = { #let _note(side, content, pos: none, color: COL-NOTE, shape: "default", aligned: false) = {
if side == "over" {
if pos == none {
panic("Pos cannot be none with side 'over'")
}
}
if aligned {
if side != "over" {
panic("Aligned notes can only be over a participant (got side '" + side + "')")
}
}
return (( return ((
type: "note", type: "note",
side: side, side: side,
@ -22,7 +32,8 @@
pos: pos, pos: pos,
color: color, color: color,
shape: shape, shape: shape,
aligned: aligned aligned: aligned,
aligned-with: none
),) ),)
} }
@ -66,7 +77,7 @@
if note.side == "over" { if note.side == "over" {
if type(note.pos) == array { if type(note.pos) == array {
let xs = note.pos.map(par => x-pos.at(pars-i.at(par))) let xs = note.pos.map(par => x-pos.at(pars-i.at(par)))
return xs.sum() / xs.len() return (calc.min(..xs) + calc.max(..xs)) / 2
} }
} }
return x-pos.at(pars-i.at(note.pos)) return x-pos.at(pars-i.at(note.pos))
@ -162,7 +173,7 @@
anchor: "center" anchor: "center"
) )
if note.pos != none or note.side == "across" { if note.aligned-with == none and (note.pos != none or note.side == "across") {
y -= h y -= h
} }

View File

@ -65,23 +65,36 @@
} else if elmt.type == "note" { } else if elmt.type == "note" {
let (p1, p2) = (none, none) let (p1, p2) = (none, none)
let cell = none
if elmt.side == "left" { if elmt.side == "left" {
p1 = "[" p1 = "["
p2 = elmt.pos p2 = elmt.pos
cell = get-note-box(elmt)
} else if elmt.side == "right" { } else if elmt.side == "right" {
p1 = elmt.pos p1 = elmt.pos
p2 = "]" p2 = "]"
cell = get-note-box(elmt)
} else if elmt.side == "over" {
if elmt.aligned-with != none {
let box1 = get-note-box(elmt)
let box2 = get-note-box(elmt.aligned-with)
let m1 = measure(box1)
let m2 = measure(box2)
cell = box(width: (m1.width + m2.width) / 2, height: calc.max(m1.height, m2.height))
p1 = elmt.pos
p2 = elmt.aligned-with.pos
}
} }
if p1 != none and p2 != none { if p1 != none and p2 != none and cell != none {
let i1 = pars-i.at(p1) let i1 = pars-i.at(p1)
let i2 = pars-i.at(p2) let i2 = pars-i.at(p2)
cells.push( cells.push(
( (
elmt: elmt, elmt: elmt,
i1: i1, i1: calc.min(i1, i2),
i2: i2, i2: calc.max(i1, i2),
cell: get-note-box(elmt) cell: cell
) )
) )
} }
@ -101,6 +114,28 @@
widths.push(w1 / 2pt + w2 / 2pt + PAR-SPACE) widths.push(w1 / 2pt + w2 / 2pt + PAR-SPACE)
} }
// Compute minimum width for over notes
for n in elements.filter(e => (e.type == "note" and
e.side == "over" and
type(e.pos) == str)) {
let m = note.get-size(n)
let i = pars-i.at(n.pos)
if i < widths.len() {
widths.at(i) = calc.max(
widths.at(i),
m.width / 2 + NOTE-GAP
)
}
if i > 0 {
widths.at(i - 1) = calc.max(
widths.at(i - 1),
m.width / 2 + NOTE-GAP
)
}
}
// Compute minimum width for simple sequences (spanning 1 column) // Compute minimum width for simple sequences (spanning 1 column)
for cell in cells.filter(c => c.i2 - c.i1 == 1) { for cell in cells.filter(c => c.i2 - c.i1 == 1) {
let m = measure(cell.cell) let m = measure(cell.cell)
@ -111,7 +146,7 @@
} }
// Compute minimum width for self sequences // Compute minimum width for self sequences
for cell in cells.filter(c => c.i1 == c.i2) { for cell in cells.filter(c => c.elmt.type == "seq" and c.i1 == c.i2) {
let m = measure(cell.cell) let m = measure(cell.cell)
let i = cell.i1 let i = cell.i1
if cell.elmt.flip { if cell.elmt.flip {
@ -252,7 +287,9 @@
// Note // Note
} else if elmt.type == "note" { } else if elmt.type == "note" {
if not elmt.linked { if not elmt.linked {
y -= Y-SPACE if not elmt.aligned {
y -= Y-SPACE
}
let shps let shps
(y, shps) = draw-note(elmt, y, lifelines) (y, shps) = draw-note(elmt, y, lifelines)
shapes += shps shapes += shps