From 46d2d7202ea6ec7ac5327d57a9369491415e5e2a Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Mon, 14 Jul 2025 17:02:16 +0200 Subject: [PATCH] refactored notes --- src/core/draw/note.typ | 169 +++++++++++++++++++++++++++++++++++++ src/core/draw/sequence.typ | 3 +- src/core/renderer.typ | 29 +------ src/core/setup.typ | 12 +-- src/note.typ | 146 +------------------------------- 5 files changed, 183 insertions(+), 176 deletions(-) create mode 100644 src/core/draw/note.typ diff --git a/src/core/draw/note.typ b/src/core/draw/note.typ new file mode 100644 index 0000000..af80923 --- /dev/null +++ b/src/core/draw/note.typ @@ -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 + }) + } + }) +} \ No newline at end of file diff --git a/src/core/draw/sequence.typ b/src/core/draw/sequence.typ index 0df14a3..17c5ffc 100644 --- a/src/core/draw/sequence.typ +++ b/src/core/draw/sequence.typ @@ -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 diff --git a/src/core/renderer.typ b/src/core/renderer.typ index d26a6ca..b09e9b7 100644 --- a/src/core/renderer.typ +++ b/src/core/renderer.typ @@ -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 - } } } diff --git a/src/core/setup.typ b/src/core/setup.typ index e8d07e9..bc899e7 100644 --- a/src/core/setup.typ +++ b/src/core/setup.typ @@ -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 ) diff --git a/src/note.typ b/src/note.typ index 14d3c98..0c62e5c 100644 --- a/src/note.typ +++ b/src/note.typ @@ -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 -} \ No newline at end of file