refactored notes

This commit is contained in:
2025-07-14 17:02:16 +02:00
parent 3cc600d058
commit 46d2d7202e
5 changed files with 183 additions and 176 deletions

169
src/core/draw/note.typ Normal file
View File

@ -0,0 +1,169 @@
#import "../../consts.typ": *
#import "../utils.typ": get-ctx, set-ctx
#import "../../cetz.typ": draw
#let get-size(note) = {
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let m = measure(box(note.content))
let w = m.width / 1pt + PAD.last() * 2
let h = m.height / 1pt + PAD.first() * 2
if note.shape == "default" {
w += NOTE-CORNER-SIZE
}
return (
width: w,
height: h
)
}
#let get-base-x(pars-i, x-pos, note) = {
if note.side == "across" {
return (x-pos.first() + x-pos.last()) / 2
}
if note.side == "over" {
if type(note.pos) == array {
let xs = note.pos.map(par => x-pos.at(pars-i.at(par)))
return (calc.min(..xs) + calc.max(..xs)) / 2
}
}
return x-pos.at(pars-i.at(note.pos))
}
#let get-box(note) = {
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let inset = (
left: PAD.last() * 1pt,
right: PAD.last() * 1pt,
top: PAD.first() * 1pt,
bottom: PAD.first() * 1pt,
)
if note.shape == "default" {
inset.right += NOTE-CORNER-SIZE * 1pt
}
if note.side == "left" {
inset.right += NOTE-GAP * 1pt
} else if note.side == "right" {
inset.left += NOTE-GAP * 1pt
}
return box(note.content, inset: inset)
}
#let pre-render(note) = {
}
#let render(note, y: auto, forced: false) = {
if not note.linked {
if not note.aligned {
set-ctx(c => {
c.y -= Y-SPACE
return c
})
}
} else if not forced {
return ()
}
get-ctx(ctx => {
let y = y
if y == auto {
y = ctx.y
}
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let m = measure(box(note.content))
let w = m.width / 1pt + PAD.last() * 2
let h = m.height / 1pt + PAD.first() * 2
let total-w = w
if note.shape == "default" {
total-w += NOTE-CORNER-SIZE
}
let base-x = get-base-x(ctx.pars-i, ctx.x-pos, note)
let i = none
if note.pos != none and type(note.pos) == str {
i = ctx.pars-i.at(note.pos)
}
let x0 = base-x
if note.side == "left" {
x0 -= NOTE-GAP
x0 -= total-w
if ctx.lifelines.at(i).level != 0 {
x0 -= LIFELINE-W / 2
}
} else if note.side == "right" {
x0 += NOTE-GAP
x0 += ctx.lifelines.at(i).level * LIFELINE-W / 2
} else if note.side == "over" or note.side == "across" {
x0 -= total-w / 2
}
let x1 = x0 + w
let x2 = x0 + total-w
let y0 = y
if note.linked {
y0 += h / 2
}
let y1 = y0 - h
if note.shape == "default" {
draw.merge-path(
stroke: black + .5pt,
fill: note.color,
close: true,
{
draw.line(
(x0, y0),
(x1, y0),
(x2, y0 - NOTE-CORNER-SIZE),
(x2, y1),
(x0, y1)
)
}
)
draw.line((x1, y0), (x1, y0 - NOTE-CORNER-SIZE), (x2, y0 - NOTE-CORNER-SIZE), stroke: black + .5pt)
} else if note.shape == "rect" {
draw.rect(
(x0, y0),
(x2, y1),
stroke: black + .5pt,
fill: note.color
)
} else if note.shape == "hex" {
let lx = x0 + PAD.last()
let rx = x2 - PAD.last()
let my = (y0 + y1) / 2
draw.merge-path(
stroke: black + .5pt,
fill: note.color,
close: true,
{
draw.line(
(lx, y0),
(rx, y0),
(x2, my),
(rx, y1),
(lx, y1),
(x0, my),
)
}
)
}
draw.content(
((x0 + x1)/2, (y0 + y1)/2),
note.content,
anchor: "center"
)
if note.aligned-with == none and (note.pos != none or note.side == "across") {
set-ctx(c => {
c.y -= h
return c
})
}
})
}

View File

@ -1,6 +1,7 @@
#import "../utils.typ": get-ctx, set-ctx
#import "../../consts.typ": *
#import "../../cetz.typ": draw, vector
#import "note.typ"
#let get-arrow-marks(sym, color) = {
@ -166,7 +167,7 @@
let y0 = start-info.y
if "linked-note" in seq {
// TODO: adapt note.render
note.render(seq.linked-note, y: start-info.y)
(seq.linked-note.draw)(seq.linked-note, y: start-info.y, forced: true)
}
let flip-mark = end-info.i <= start-info.i

View File

@ -8,7 +8,7 @@
#import "../separator.typ"
#import "../sync.typ"
#import "../consts.typ": *
#import "../note.typ" as note: get-note-box
#import "draw/note.typ": get-box as get-note-box, get-size as get-note-size
#let DEBUG-INVISIBLE = false
@ -83,7 +83,7 @@
return participants
}
#let note-get-cell(note) = {
#let note-get-cell(pars-i, note) = {
let (p1, p2) = (none, none)
let cell = none
if note.side == "left" {
@ -140,7 +140,7 @@
)
} else if elmt.type == "note" {
let cell = note-get-cell(elmt)
let cell = note-get-cell(pars-i, elmt)
if cell != none {
cells.push(cell)
}
@ -172,7 +172,7 @@
for n in notes.filter(e => (e.side == "over" and
type(e.pos) == str)) {
let m = note.get-size(n)
let m = get-note-size(n)
let i = pars-i.at(n.pos)
if i < widths.len() {
@ -356,16 +356,6 @@
#let render(participants, elements) = context canvas(length: 1pt, {
let shapes = ()
setup-ctx(participants, elements)
/*
let draw-seq = sequence.render.with(pars-i, x-pos, participants)
let draw-group = group.render.with()
let draw-else = group.render-else.with()
let draw-sep = separator.render.with(x-pos)
//let draw-par = participant.render.with(x-pos)
let draw-note = note.render.with(pars-i, x-pos)
let draw-sync = sync.render.with(pars-i, x-pos, participants)
*/
// Draw participants (start)
get-ctx(ctx => {
@ -456,17 +446,6 @@
)
}
y = y1
// Note
} else if elmt.type == "note" {
if not elmt.linked {
if not elmt.aligned {
y -= Y-SPACE
}
let shps
(y, shps) = draw-note(elmt, y, lifelines)
shapes += shps
}
}
}

View File

@ -108,7 +108,7 @@
ctx.linked.push(p1)
ctx.linked.push(p2)
ctx.last-seq = (
elmt: seq,
seq: seq,
i: ctx.i,
p1: p1,
p2: p2
@ -138,14 +138,14 @@
note.pos = pars.last().last()
}
let seq = last-seq.note
let seq = ctx.last-seq.seq
seq.insert("linked-note", note)
ctx.elmts.at(last-seq.i) = seq
ctx.elmts.at(ctx.last-seq.i) = seq
}
if note.aligned {
let n = last-note.note
let n = ctx.last-note.note
n.aligned-with = note
ctx.elmts.at(last-note.i) = n
ctx.elmts.at(ctx.last-note.i) = n
}
if note.side == "left" {
ctx.linked.push("[")
@ -170,7 +170,7 @@
ctx.elmts.at(ctx.i) = note
ctx.last-note = (
elmt: note,
note: note,
i: ctx.i
)

View File

@ -1,5 +1,6 @@
#import "/src/cetz.typ": draw
#import "consts.typ": *
#import "core/draw/note.typ"
#let SIDES = (
"left",
@ -30,6 +31,7 @@
}
return ((
type: "note",
draw: note.render,
side: side,
content: content,
pos: pos,
@ -39,147 +41,3 @@
aligned-with: none
),)
}
#let get-note-box(note) = {
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let inset = (
left: PAD.last() * 1pt,
right: PAD.last() * 1pt,
top: PAD.first() * 1pt,
bottom: PAD.first() * 1pt,
)
if note.shape == "default" {
inset.right += NOTE-CORNER-SIZE * 1pt
}
if note.side == "left" {
inset.right += NOTE-GAP * 1pt
} else if note.side == "right" {
inset.left += NOTE-GAP * 1pt
}
return box(note.content, inset: inset)
}
#let get-size(note) = {
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let m = measure(box(note.content))
let w = m.width / 1pt + PAD.last() * 2
let h = m.height / 1pt + PAD.first() * 2
if note.shape == "default" {
w += NOTE-CORNER-SIZE
}
return (
width: w,
height: h
)
}
#let _get-base-x(pars-i, x-pos, note) = {
if note.side == "across" {
return (x-pos.first() + x-pos.last()) / 2
}
if note.side == "over" {
if type(note.pos) == array {
let xs = note.pos.map(par => x-pos.at(pars-i.at(par)))
return (calc.min(..xs) + calc.max(..xs)) / 2
}
}
return x-pos.at(pars-i.at(note.pos))
}
#let render(pars-i, x-pos, note, y, lifelines) = {
let shapes = ()
let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD}
let m = measure(box(note.content))
let w = m.width / 1pt + PAD.last() * 2
let h = m.height / 1pt + PAD.first() * 2
let total-w = w
if note.shape == "default" {
total-w += NOTE-CORNER-SIZE
}
let base-x = _get-base-x(pars-i, x-pos, note)
let i = none
if note.pos != none and type(note.pos) == str {
i = pars-i.at(note.pos)
}
let x0 = base-x
if note.side == "left" {
x0 -= NOTE-GAP
x0 -= total-w
if lifelines.at(i).level != 0 {
x0 -= LIFELINE-W / 2
}
} else if note.side == "right" {
x0 += NOTE-GAP
x0 += lifelines.at(i).level * LIFELINE-W / 2
} else if note.side == "over" or note.side == "across" {
x0 -= total-w / 2
}
let x1 = x0 + w
let x2 = x0 + total-w
let y0 = y
if note.linked {
y0 += h / 2
}
let y1 = y0 - h
if note.shape == "default" {
shapes += draw.merge-path(
stroke: black + .5pt,
fill: note.color,
close: true,
{
draw.line(
(x0, y0),
(x1, y0),
(x2, y0 - NOTE-CORNER-SIZE),
(x2, y1),
(x0, y1)
)
}
)
shapes += draw.line((x1, y0), (x1, y0 - NOTE-CORNER-SIZE), (x2, y0 - NOTE-CORNER-SIZE), stroke: black + .5pt)
} else if note.shape == "rect" {
shapes += draw.rect(
(x0, y0),
(x2, y1),
stroke: black + .5pt,
fill: note.color
)
} else if note.shape == "hex" {
let lx = x0 + PAD.last()
let rx = x2 - PAD.last()
let my = (y0 + y1) / 2
shapes += draw.merge-path(
stroke: black + .5pt,
fill: note.color,
close: true,
{
draw.line(
(lx, y0),
(rx, y0),
(x2, my),
(rx, y1),
(lx, y1),
(x0, my),
)
}
)
}
shapes += draw.content(
((x0 + x1)/2, (y0 + y1)/2),
note.content,
anchor: "center"
)
if note.aligned-with == none and (note.pos != none or note.side == "across") {
y -= h
}
let r = (y, shapes)
return r
}