refactored notes rendering
This commit is contained in:
		| @@ -1,14 +1,51 @@ | ||||
| #import "/src/cetz.typ": draw | ||||
| #import "/src/cetz.typ": draw, styles | ||||
|  | ||||
| #import "/src/consts.typ": * | ||||
| #import "/src/core/utils.typ": get-ctx, set-ctx, expand-parent-group | ||||
| #import "/src/core/utils.typ": get-ctx, is-elmt, set-ctx, expand-parent-group, normalize-measure | ||||
|  | ||||
| #let note-default-style = ( | ||||
|   shape: "default", | ||||
|   fill: rgb("#FEFFDD"), | ||||
|   stroke: black + .5pt | ||||
| ) | ||||
|  | ||||
| #let resolve-style(ctx, note) = { | ||||
|   return styles.resolve( | ||||
|     ctx.style, | ||||
|     merge: note.style, | ||||
|     root: "note", | ||||
|     base: note-default-style | ||||
|   ) | ||||
| } | ||||
|  | ||||
| #let pre-resolve-styles() = get-ctx(ctx => { | ||||
|   let ctx = ctx | ||||
|   let notes = ctx.setup.notes | ||||
|  | ||||
|   for (i, elmt) in ctx.setup.elements.enumerate() { | ||||
|     if type(elmt) == function { | ||||
|       ctx = elmt(ctx).ctx | ||||
|     } else if is-elmt(elmt) { | ||||
|       if elmt.type == "note" { | ||||
|         let style = resolve-style(ctx, elmt) | ||||
|         notes.at(elmt.id).insert("resolved-style", style) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   set-ctx(c => { | ||||
|     c.setup.notes = notes | ||||
|     return c | ||||
|   }) | ||||
| }) | ||||
|  | ||||
| #let get-size(note) = { | ||||
|   let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD} | ||||
|   let style = note.resolved-style | ||||
|   let PAD = if style.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" { | ||||
|   if style.shape == "default" { | ||||
|     w += NOTE-CORNER-SIZE | ||||
|   } | ||||
|   return ( | ||||
| @@ -31,14 +68,15 @@ | ||||
| } | ||||
|  | ||||
| #let get-box(note) = { | ||||
|   let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD} | ||||
|   let style = note.resolved-style | ||||
|   let PAD = if style.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" { | ||||
|   if style.shape == "default" { | ||||
|     inset.right += NOTE-CORNER-SIZE * 1pt | ||||
|   } | ||||
|   if note.side == "left" { | ||||
| @@ -62,18 +100,21 @@ | ||||
|   } | ||||
|  | ||||
|   get-ctx(ctx => { | ||||
|     let note = ctx.notes.at(note.id) | ||||
|     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 style = note.resolved-style | ||||
|     let shape = style.shape | ||||
|      | ||||
|     let PAD = if shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD} | ||||
|     let m = normalize-measure(box(note.content)) | ||||
|     let w = m.width + PAD.last() * 2 | ||||
|     let h = m.height + PAD.first() * 2 | ||||
|     let total-w = w | ||||
|     if note.shape == "default" { | ||||
|     if shape == "default" { | ||||
|       total-w += NOTE-CORNER-SIZE | ||||
|     } | ||||
|  | ||||
| @@ -106,31 +147,31 @@ | ||||
|     } | ||||
|     let y1 = y0 - h | ||||
|  | ||||
|     if note.shape == "default" { | ||||
|     if shape == "default" { | ||||
|       draw.line( | ||||
|         (x0, y0), | ||||
|         (x1, y0), | ||||
|         (x2, y0 - NOTE-CORNER-SIZE), | ||||
|         (x2, y1), | ||||
|         (x0, y1), | ||||
|         stroke: black + .5pt, | ||||
|         fill: note.color, | ||||
|         stroke: style.stroke, | ||||
|         fill: style.fill, | ||||
|         close: true | ||||
|       ) | ||||
|       draw.line( | ||||
|         (x1, y0), | ||||
|         (x1, y0 - NOTE-CORNER-SIZE), | ||||
|         (x2, y0 - NOTE-CORNER-SIZE), | ||||
|         stroke: black + .5pt | ||||
|         stroke: style.stroke | ||||
|       ) | ||||
|     } else if note.shape == "rect" { | ||||
|     } else if shape == "rect" { | ||||
|       draw.rect( | ||||
|         (x0, y0), | ||||
|         (x2, y1), | ||||
|         stroke: black + .5pt, | ||||
|         fill: note.color | ||||
|         stroke: style.stroke, | ||||
|         fill: style.fill | ||||
|       ) | ||||
|     } else if note.shape == "hex" { | ||||
|     } else if shape == "hex" { | ||||
|       let lx = x0 + PAD.last() | ||||
|       let rx = x2 - PAD.last() | ||||
|       let my = (y0 + y1) / 2 | ||||
| @@ -141,8 +182,8 @@ | ||||
|         (rx, y1), | ||||
|         (lx, y1), | ||||
|         (x0, my), | ||||
|         stroke: black + .5pt, | ||||
|         fill: note.color, | ||||
|         stroke: style.stroke, | ||||
|         fill: style.fill, | ||||
|         close: true | ||||
|       ) | ||||
|     } | ||||
|   | ||||
| @@ -70,7 +70,8 @@ | ||||
|   h = calc.max( | ||||
|     h, | ||||
|     ..seq.linked-notes.map(n => { | ||||
|       note.get-size(n).height / 2 | ||||
|       let nt = ctx.notes.at(n.id) | ||||
|       note.get-size(nt).height / 2 | ||||
|     }) | ||||
|   ) | ||||
|   ctx.y -= h | ||||
| @@ -354,7 +355,8 @@ | ||||
|     end-info.y = calc.min( | ||||
|       end-info.y, | ||||
|       y0 - calc.max(..seq.linked-notes.map(n => { | ||||
|         let m = note.get-size(n) | ||||
|         let nt = ctx.notes.at(n.id) | ||||
|         let m = note.get-size(nt) | ||||
|         return m.height / 2 | ||||
|       })) | ||||
|     ) | ||||
|   | ||||
| @@ -87,7 +87,7 @@ | ||||
|   return participants | ||||
| } | ||||
|  | ||||
| #let note-get-cell(pars-i, n) = { | ||||
| #let note-get-cell(notes, pars-i, n) = { | ||||
|   let (p1, p2) = (none, none) | ||||
|   let cell = none | ||||
|   if n.side == "left" { | ||||
| @@ -99,8 +99,9 @@ | ||||
|     p2 = n.pos2 | ||||
|     cell = note.get-box(n) | ||||
|   } else if n.side == "over" and n.aligned-with != none { | ||||
|     let aligned-with = notes.at(n.aligned-with.id) | ||||
|     let box1 = note.get-box(n) | ||||
|     let box2 = note.get-box(n.aligned-with) | ||||
|     let box2 = note.get-box(aligned-with) | ||||
|     let m1 = measure(box1) | ||||
|     let m2 = measure(box2) | ||||
|     cell = box( | ||||
| @@ -144,7 +145,7 @@ | ||||
|       ) | ||||
|      | ||||
|     } else if elmt.type == "note" { | ||||
|       let cell = note-get-cell(pars-i, notes.at(elmt.id)) | ||||
|       let cell = note-get-cell(notes, pars-i, notes.at(elmt.id)) | ||||
|       if cell != none { | ||||
|         cells.push(cell) | ||||
|       } | ||||
| @@ -359,8 +360,8 @@ | ||||
|  | ||||
|   init-lifelines() | ||||
|   set-participants-i() | ||||
|  | ||||
|    | ||||
|   note.pre-resolve-styles() | ||||
|   compute-columns-width() | ||||
|  | ||||
|   set-ctx(c => { | ||||
| @@ -401,7 +402,7 @@ | ||||
|  | ||||
| #let render(participants, elements, notes) = context canvas(length: 1pt, { | ||||
|   setup-ctx(participants, elements, notes) | ||||
|    | ||||
|  | ||||
|   // Draw participants (start) | ||||
|   get-ctx(ctx => { | ||||
|     for p in ctx.participants { | ||||
|   | ||||
| @@ -150,6 +150,7 @@ | ||||
|     let n = ctx.last-note.note | ||||
|     n.aligned-with = note | ||||
|     ctx.elmts.at(ctx.last-note.i) = n | ||||
|     ctx.notes.at(ctx.last-note.note.id) = n | ||||
|   } | ||||
|  | ||||
|   if note.side in ("left", "right") { | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/note.typ
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/note.typ
									
									
									
									
									
								
							| @@ -18,10 +18,9 @@ | ||||
|   side, | ||||
|   content, | ||||
|   pos: none, | ||||
|   color: COL-NOTE, | ||||
|   shape: "default", | ||||
|   aligned: false, | ||||
|   allow-overlap: true | ||||
|   allow-overlap: true, | ||||
|   ..style | ||||
| ) = { | ||||
|   if side == "over" { | ||||
|     if pos == none { | ||||
| @@ -33,19 +32,15 @@ | ||||
|       panic("Aligned notes can only be over a participant (got side '" + side + "')") | ||||
|     } | ||||
|   } | ||||
|   if color == auto { | ||||
|     color = COL-NOTE | ||||
|   } | ||||
|   return (( | ||||
|     type: "note", | ||||
|     draw: note.render, | ||||
|     side: side, | ||||
|     content: content, | ||||
|     pos: pos, | ||||
|     color: color, | ||||
|     shape: shape, | ||||
|     aligned: aligned, | ||||
|     aligned-with: none, | ||||
|     allow-overlap: allow-overlap | ||||
|     allow-overlap: allow-overlap, | ||||
|     style: style.named() | ||||
|   ),) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user