forked from HEL/chronos
		
	added notes
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								gallery/gitea.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gallery/gitea.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 17 KiB | 
							
								
								
									
										
											BIN
										
									
								
								gallery/notes.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gallery/notes.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										114
									
								
								gallery/notes.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								gallery/notes.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | |||||||
|  | #import "/src/lib.typ" as chronos: * | ||||||
|  |  | ||||||
|  | #set page(width: auto, height: auto) | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: "Alice") | ||||||
|  |   _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  |   _seq("a", "b", comment: [hello]) | ||||||
|  |   _note("left", [this is a first note]) | ||||||
|  |  | ||||||
|  |   _seq("b", "a", comment: [ok]) | ||||||
|  |   _note("right", [this is another note]) | ||||||
|  |  | ||||||
|  |   _seq("b", "b", comment: [I am thinking]) | ||||||
|  |   _note("left", [a note\ can also be defined\ on several lines]) | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #pagebreak() | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: "Alice") | ||||||
|  |   _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  |   _note("left", [This is displayed\ left of Alice.], pos: "a", color: rgb("#00FFFF")) | ||||||
|  |   _note("right", [This is displayed right of Alice.], pos: "a") | ||||||
|  |   _note("over", [This is displayed over Alice.], pos: "a") | ||||||
|  |   _note("over", [This is displayed\ over Bob and Alice.], pos: ("a", "b"), color: rgb("#FFAAAA")) | ||||||
|  |   _note("over", [This is yet another\ example of\ a long note.], pos: ("a", "b")) | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #pagebreak() | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("caller") | ||||||
|  |   _par("server") | ||||||
|  |  | ||||||
|  |   _seq("caller", "server", comment: [conReq]) | ||||||
|  |   _note("over", [idle], pos: "caller", shape: "hex") | ||||||
|  |   _seq("server", "caller", comment: [conConf]) | ||||||
|  |   _note("over", ["r" as rectangle\ "h" as hexagon], pos: "server", shape: "rect") | ||||||
|  |   _note("over", [this is\ on several\ lines], pos: "server", shape: "rect") | ||||||
|  |   _note("over", [this is\ on several\ lines], pos: "caller", shape: "hex") | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #pagebreak() | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: "Alice") | ||||||
|  |   _par("b", display-name: "Bob") | ||||||
|  |   _par("c", display-name: "Charlie") | ||||||
|  |  | ||||||
|  |   _seq("a", "b", comment: [m1]) | ||||||
|  |   _seq("b", "c", comment: [m2]) | ||||||
|  |  | ||||||
|  |   _note("over", [Old method for note over all part. with:\ `note over FirstPart, LastPart`.], pos: ("a", "c")) | ||||||
|  |   _note("across", [New method with:\ `note across`.]) | ||||||
|  |  | ||||||
|  |   _seq("b", "a") | ||||||
|  |  | ||||||
|  |   _note("across", [Note across all part.], shape: "hex") | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #pagebreak() | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: "Alice") | ||||||
|  |   _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  |   _note("over", [initial state of Alice], pos: "a") | ||||||
|  |   _note("over", [initial state of Bob], pos: "b") | ||||||
|  |   _seq("b", "a", comment: [hello]) | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: "Alice") | ||||||
|  |   _par("b", display-name: "Bob") | ||||||
|  |  | ||||||
|  |   _note("over", [initial state of Alice], pos: "a") | ||||||
|  |   _note("over", [initial state of Bob], pos: "b", aligned: true) | ||||||
|  |   _seq("b", "a", comment: [hello]) | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | #pagebreak() | ||||||
|  |  | ||||||
|  | #chronos.diagram({ | ||||||
|  |   _par("a", display-name: [Alice]) | ||||||
|  |   _par("b", display-name: [The *Famous* Bob]) | ||||||
|  |  | ||||||
|  |   _seq("a", "b", comment: [hello #strike([there])]) | ||||||
|  |  | ||||||
|  |   _gap() | ||||||
|  |   _seq("b", "a", comment: [ok]) | ||||||
|  |   _note("left", [ | ||||||
|  |     This is *bold*\ | ||||||
|  |     This is _italics_\ | ||||||
|  |     This is `monospaced`\ | ||||||
|  |     This is #strike([stroked])\ | ||||||
|  |     This is #underline([underlined])\ | ||||||
|  |     This is #underline([waved])\ | ||||||
|  |   ]) | ||||||
|  |  | ||||||
|  |   _seq("a", "b", comment: [A _well formatted_ message]) | ||||||
|  |   _note("right", [ | ||||||
|  |     This is #box(text([displayed], size: 18pt), fill: rgb("#5F9EA0"))\ | ||||||
|  |     #underline([left of]) Alice. | ||||||
|  |   ], pos: "a") | ||||||
|  |   _note("left", [ | ||||||
|  |     #underline([This], stroke: red) is #text([displayed], fill: rgb("#118888"))\ | ||||||
|  |     *#text([left of], fill: rgb("#800080")) #strike([Alice], stroke: red) Bob.* | ||||||
|  |   ], pos: "b") | ||||||
|  |   _note("over", [ | ||||||
|  |     #underline([This is hosted], stroke: rgb("#FF33FF")) by #box(baseline: 50%, image("gitea.png", width: 1cm, height: 1cm, fit: "contain")) | ||||||
|  |   ], pos: ("a", "b")) | ||||||
|  | }) | ||||||
| @@ -15,6 +15,12 @@ | |||||||
| #let COLLECTIONS-DY = 3 | #let COLLECTIONS-DY = 3 | ||||||
| #let QUEUE-PAD = (5pt, 3pt) | #let QUEUE-PAD = (5pt, 3pt) | ||||||
|  |  | ||||||
|  | #let NOTE-PAD = (6, 3) | ||||||
|  | #let NOTE-CORNER-SIZE = 6 | ||||||
|  | #let NOTE-GAP = 3 | ||||||
|  | #let NOTE-HEX-PAD = (6, 8) | ||||||
|  |  | ||||||
| #let COL-DESTRUCTION = rgb("#A80238") | #let COL-DESTRUCTION = rgb("#A80238") | ||||||
| #let COL-GRP-NAME = rgb("#EEEEEE") | #let COL-GRP-NAME = rgb("#EEEEEE") | ||||||
| #let COL-SEP-NAME = rgb("#EEEEEE") | #let COL-SEP-NAME = rgb("#EEEEEE") | ||||||
|  | #let COL-NOTE = rgb("#FEFFDD") | ||||||
| @@ -57,7 +57,8 @@ | |||||||
|  |  | ||||||
|   // List participants |   // List participants | ||||||
|   let linked = () |   let linked = () | ||||||
|   for elmt in elmts { |   let last-seq = none | ||||||
|  |   for (i, elmt) in elmts.enumerate() { | ||||||
|     if elmt.type == "par" { |     if elmt.type == "par" { | ||||||
|       participants.push(elmt) |       participants.push(elmt) | ||||||
|     } else if elmt.type == "seq" { |     } else if elmt.type == "seq" { | ||||||
| @@ -73,15 +74,44 @@ | |||||||
|         participants.at(i).from-start = false |         participants.at(i).from-start = false | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       let p1 = elmt.p1 | ||||||
|  |       let p2 = elmt.p2 | ||||||
|       if elmt.p1 == "?" { |       if elmt.p1 == "?" { | ||||||
|         linked.push("?" + elmt.p2) |         p1 = "?" + elmt.p2 | ||||||
|       } else { |  | ||||||
|         linked.push(elmt.p1) |  | ||||||
|       } |       } | ||||||
|       if elmt.p2 == "?" { |       if elmt.p2 == "?" { | ||||||
|         linked.push(elmt.p1 + "?") |         p2 = elmt.p1 + "?" | ||||||
|       } else { |       } | ||||||
|         linked.push(elmt.p2) |       linked.push(p1) | ||||||
|  |       linked.push(p2) | ||||||
|  |       last-seq = ( | ||||||
|  |         elmt: elmt, | ||||||
|  |         i: i, | ||||||
|  |         p1: p1, | ||||||
|  |         p2: p2 | ||||||
|  |       ) | ||||||
|  |     } else if elmt.type == "note" { | ||||||
|  |       elmt.insert("linked", elmt.pos == none and elmt.side != "across") | ||||||
|  |       if elmt.pos == none and elmt.side != "across" { | ||||||
|  |         let names = participants.map(p => p.name) | ||||||
|  |         let i1 = names.position(n => n == last-seq.p1) | ||||||
|  |         let i2 = names.position(n => n == last-seq.p2) | ||||||
|  |         let pars = ((i1, last-seq.p1), (i2, last-seq.p2)).sorted(key: p => p.first()) | ||||||
|  |         if elmt.side == "left" { | ||||||
|  |           elmt.pos = pars.first().last() | ||||||
|  |         } else if elmt.side == "right" { | ||||||
|  |           elmt.pos = pars.last().last() | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let seq = last-seq.elmt | ||||||
|  |         seq.insert("linked-note", elmt) | ||||||
|  |         elmts.at(last-seq.i) = seq | ||||||
|  |       } | ||||||
|  |       elmts.at(i) = elmt | ||||||
|  |       if elmt.side == "left" { | ||||||
|  |         linked.push("[") | ||||||
|  |       } else if elmt.side == "right" { | ||||||
|  |         linked.push("]") | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -137,6 +167,7 @@ | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   set text(font: "Source Sans 3") | ||||||
|   render(participants, elmts) |   render(participants, elmts) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,3 +4,4 @@ | |||||||
| #import "group.typ": _grp | #import "group.typ": _grp | ||||||
| #import "participant.typ": _par | #import "participant.typ": _par | ||||||
| #import "separator.typ": _sep | #import "separator.typ": _sep | ||||||
|  | #import "note.typ": _note | ||||||
							
								
								
									
										171
									
								
								src/note.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/note.typ
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,171 @@ | |||||||
|  | #import "@preview/cetz:0.2.2": draw | ||||||
|  | #import "consts.typ": * | ||||||
|  |  | ||||||
|  | #let SIDES = ( | ||||||
|  |   "left", | ||||||
|  |   "right", | ||||||
|  |   "over", | ||||||
|  |   "across" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #let SHAPES = ( | ||||||
|  |   "default", | ||||||
|  |   "rect", | ||||||
|  |   "hex" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | #let _note(side, content, pos: none, color: COL-NOTE, shape: "default", aligned: false) = { | ||||||
|  |   return (( | ||||||
|  |     type: "note", | ||||||
|  |     side: side, | ||||||
|  |     content: content, | ||||||
|  |     pos: pos, | ||||||
|  |     color: color, | ||||||
|  |     shape: shape, | ||||||
|  |     aligned: aligned | ||||||
|  |   ),) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #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 xs.sum() / xs.len() | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   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.pos != none or note.side == "across" { | ||||||
|  |     y -= h | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   let r = (y, shapes) | ||||||
|  |   return r | ||||||
|  | } | ||||||
| @@ -6,6 +6,7 @@ | |||||||
| #import "sequence.typ" | #import "sequence.typ" | ||||||
| #import "separator.typ" | #import "separator.typ" | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
|  | #import "note.typ" as note: get-note-box | ||||||
|  |  | ||||||
| #let DEBUG-INVISIBLE = false | #let DEBUG-INVISIBLE = false | ||||||
|  |  | ||||||
| @@ -61,6 +62,29 @@ | |||||||
|         par.max-lifelines = calc.max(par.max-lifelines, par.lifeline-lvl) |         par.max-lifelines = calc.max(par.max-lifelines, par.lifeline-lvl) | ||||||
|       } |       } | ||||||
|       participants.at(i) = par |       participants.at(i) = par | ||||||
|  |      | ||||||
|  |     } else if elmt.type == "note" { | ||||||
|  |       let (p1, p2) = (none, none) | ||||||
|  |       if elmt.side == "left" { | ||||||
|  |         p1 = "[" | ||||||
|  |         p2 = elmt.pos | ||||||
|  |       } else if elmt.side == "right" { | ||||||
|  |         p1 = elmt.pos | ||||||
|  |         p2 = "]" | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if p1 != none and p2 != none { | ||||||
|  |         let i1 = pars-i.at(p1) | ||||||
|  |         let i2 = pars-i.at(p2) | ||||||
|  |         cells.push( | ||||||
|  |           ( | ||||||
|  |             elmt: elmt, | ||||||
|  |             i1: i1, | ||||||
|  |             i2: i2, | ||||||
|  |             cell: get-note-box(elmt) | ||||||
|  |           ) | ||||||
|  |         ) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -143,6 +167,7 @@ | |||||||
|   let draw-group = group.render.with() |   let draw-group = group.render.with() | ||||||
|   let draw-sep = separator.render.with(x-pos) |   let draw-sep = separator.render.with(x-pos) | ||||||
|   let draw-par = participant.render.with(x-pos) |   let draw-par = participant.render.with(x-pos) | ||||||
|  |   let draw-note = note.render.with(pars-i, x-pos) | ||||||
|    |    | ||||||
|   // Draw participants (start) |   // Draw participants (start) | ||||||
|   for p in participants { |   for p in participants { | ||||||
| @@ -223,6 +248,15 @@ | |||||||
|         line.lines.push(("create", y)) |         line.lines.push(("create", y)) | ||||||
|       } |       } | ||||||
|       lifelines.at(i) = line |       lifelines.at(i) = line | ||||||
|  |      | ||||||
|  |     // Note | ||||||
|  |     } else if elmt.type == "note" { | ||||||
|  |       if not elmt.linked { | ||||||
|  |         y -= Y-SPACE | ||||||
|  |         let shps | ||||||
|  |         (y, shps) = draw-note(elmt, y, lifelines) | ||||||
|  |         shapes += shps | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| #import "@preview/cetz:0.2.2": draw | #import "@preview/cetz:0.2.2": draw | ||||||
| #import "consts.typ": * | #import "consts.typ": * | ||||||
| #import "participant.typ" | #import "participant.typ" | ||||||
|  | #import "note.typ" | ||||||
|  |  | ||||||
| #let get-arrow-marks(sym, color) = { | #let get-arrow-marks(sym, color) = { | ||||||
|   if type(sym) == array { |   if type(sym) == array { | ||||||
| @@ -61,10 +62,15 @@ | |||||||
|  |  | ||||||
|   y -= Y-SPACE |   y -= Y-SPACE | ||||||
|  |  | ||||||
|  |   let h = 0 | ||||||
|   // Reserve space for comment |   // Reserve space for comment | ||||||
|   if elmt.comment != none { |   if elmt.comment != none { | ||||||
|     y -= measure(box(elmt.comment)).height / 1pt + 6 |     h = calc.max(h, measure(box(elmt.comment)).height / 1pt + 6) | ||||||
|   } |   } | ||||||
|  |   if "linked-note" in elmt { | ||||||
|  |     h = calc.max(h, note.get-size(elmt.linked-note).height / 2) | ||||||
|  |   } | ||||||
|  |   y -= h | ||||||
|  |  | ||||||
|   let i1 = pars-i.at(elmt.p1) |   let i1 = pars-i.at(elmt.p1) | ||||||
|   let i2 = pars-i.at(elmt.p2) |   let i2 = pars-i.at(elmt.p2) | ||||||
| @@ -148,6 +154,12 @@ | |||||||
|     ) |     ) | ||||||
|   ) |   ) | ||||||
|  |  | ||||||
|  |   let y0 = y | ||||||
|  |   if "linked-note" in elmt { | ||||||
|  |     let shps = note.render(pars-i, x-pos, elmt.linked-note, y, lifelines).last() | ||||||
|  |     shapes += shps | ||||||
|  |   } | ||||||
|  |  | ||||||
|   if elmt.p1 == elmt.p2 { |   if elmt.p1 == elmt.p2 { | ||||||
|     if elmt.flip { |     if elmt.flip { | ||||||
|       x1 = start-info.lx |       x1 = start-info.lx | ||||||
| @@ -210,6 +222,11 @@ | |||||||
|     lifelines.at(i2) = dst-line |     lifelines.at(i2) = dst-line | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   if "linked-note" in elmt { | ||||||
|  |     let m = note.get-size(elmt.linked-note) | ||||||
|  |     y = calc.min(y, y0 - m.height / 2) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   let r = (y, lifelines, shapes) |   let r = (y, lifelines, shapes) | ||||||
|   return r |   return r | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user