refactored notes
This commit is contained in:
		
							
								
								
									
										169
									
								
								src/core/draw/note.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/core/draw/note.typ
									
									
									
									
									
										Normal 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 | ||||
|       }) | ||||
|     } | ||||
|   }) | ||||
| } | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   ) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user