Fix notes width not taken into account #16
| @@ -5,13 +5,15 @@ | |||||||
| /// - color (color): The note's color | /// - color (color): The note's color | ||||||
| /// - shape (str): The note's shape (see @@SHAPES for accepted values) | /// - shape (str): The note's shape (see @@SHAPES for accepted values) | ||||||
| /// - aligned (bool): True if the note is aligned with another note, in which case `side` must be `"over"`, false otherwise | /// - aligned (bool): True if the note is aligned with another note, in which case `side` must be `"over"`, false otherwise | ||||||
|  | /// - allow-overlap (bool): If set to `false`, the note will try to reserve space in the column to avoid overlapping with neighboring participants. If set to `true`, the not will overlap other participants | ||||||
| #let _note( | #let _note( | ||||||
|   side, |   side, | ||||||
|   content, |   content, | ||||||
|   pos: none, |   pos: none, | ||||||
|   color: rgb("#FEFFDD"), |   color: rgb("#FEFFDD"), | ||||||
|   shape: "default", |   shape: "default", | ||||||
|   aligned: false |   aligned: false, | ||||||
|  |   allow-overlap: true | ||||||
| ) = {} | ) = {} | ||||||
|  |  | ||||||
| /// Accepted values for `shape` argument of @@_note() | /// Accepted values for `shape` argument of @@_note() | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								manual.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								manual.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| #import "/src/cetz.typ": draw | #import "/src/cetz.typ": draw | ||||||
|  |  | ||||||
| #import "/src/consts.typ": * | #import "/src/consts.typ": * | ||||||
| #import "/src/core/utils.typ": get-ctx, set-ctx | #import "/src/core/utils.typ": get-ctx, set-ctx, expand-parent-group | ||||||
|  |  | ||||||
| #let render-start(grp) = get-ctx(ctx => { | #let render-start(grp) = get-ctx(ctx => { | ||||||
|   let grp = grp |   let grp = grp | ||||||
| @@ -18,14 +18,21 @@ | |||||||
|     ) |     ) | ||||||
|   ) |   ) | ||||||
|   ctx.groups = ctx.groups.map(g => { |   ctx.groups = ctx.groups.map(g => { | ||||||
|     if g.at(1).min-i == grp.min-i { g.at(2) += 1 } |     if g.group.min-i == grp.min-i { g.start-lvl += 1 } | ||||||
|     if g.at(1).max-i == grp.max-i { g.at(3) += 1 } |     if g.group.max-i == grp.max-i { g.end-lvl += 1 } | ||||||
|     g |     g | ||||||
|   }) |   }) | ||||||
|   if grp.grp-type == "alt" { |   if grp.grp-type == "alt" { | ||||||
|     grp.insert("elses", ()) |     grp.insert("elses", ()) | ||||||
|   } |   } | ||||||
|   ctx.groups.push((ctx.y, grp, 0, 0)) |   ctx.groups.push(( | ||||||
|  |     start-y: ctx.y, | ||||||
|  |     group: grp, | ||||||
|  |     start-lvl: 0, | ||||||
|  |     end-lvl: 0, | ||||||
|  |     min-x: ctx.x-pos.at(grp.min-i) - 10, | ||||||
|  |     max-x: ctx.x-pos.at(grp.max-i) + 10 | ||||||
|  |   )) | ||||||
|   ctx.y -= m.height / 1pt |   ctx.y -= m.height / 1pt | ||||||
|  |  | ||||||
|   set-ctx(c => { |   set-ctx(c => { | ||||||
| @@ -87,9 +94,16 @@ | |||||||
|  |  | ||||||
| #let render-end(group) = get-ctx(ctx => { | #let render-end(group) = get-ctx(ctx => { | ||||||
|   ctx.y -= Y-SPACE |   ctx.y -= Y-SPACE | ||||||
|   let (start-y, group, start-lvl, end-lvl) = ctx.groups.pop() |   let ( | ||||||
|   let x0 = ctx.x-pos.at(group.min-i) - start-lvl * 10 - 20 |     start-y, | ||||||
|   let x1 = ctx.x-pos.at(group.max-i) + end-lvl * 10 + 20 |     group, | ||||||
|  |     start-lvl, | ||||||
|  |     end-lvl, | ||||||
|  |     min-x, | ||||||
|  |     max-x | ||||||
|  |   ) = ctx.groups.pop() | ||||||
|  |   let x0 = min-x - 10 | ||||||
|  |   let x1 = max-x + 10 | ||||||
|    |    | ||||||
|   draw-group(x0, x1, start-y, ctx.y, group) |   draw-group(x0, x1, start-y, ctx.y, group) | ||||||
|  |  | ||||||
| @@ -104,12 +118,14 @@ | |||||||
|     c.groups = ctx.groups |     c.groups = ctx.groups | ||||||
|     return c |     return c | ||||||
|   }) |   }) | ||||||
|  |  | ||||||
|  |   expand-parent-group(x0, x1) | ||||||
| }) | }) | ||||||
|  |  | ||||||
| #let render-else(else_) = set-ctx(ctx => { | #let render-else(else_) = set-ctx(ctx => { | ||||||
|   ctx.y -= Y-SPACE |   ctx.y -= Y-SPACE | ||||||
|   let m = measure(text([\[#else_.desc\]], weight: "bold", size: .8em)) |   let m = measure(text([\[#else_.desc\]], weight: "bold", size: .8em)) | ||||||
|   ctx.groups.last().at(1).elses.push(( |   ctx.groups.last().group.elses.push(( | ||||||
|     ctx.y, else_ |     ctx.y, else_ | ||||||
|   )) |   )) | ||||||
|   ctx.y -= m.height / 1pt |   ctx.y -= m.height / 1pt | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #import "/src/cetz.typ": draw | #import "/src/cetz.typ": draw | ||||||
|  |  | ||||||
| #import "/src/consts.typ": * | #import "/src/consts.typ": * | ||||||
| #import "/src/core/utils.typ": get-ctx, set-ctx | #import "/src/core/utils.typ": get-ctx, set-ctx, expand-parent-group | ||||||
|  |  | ||||||
| #let get-size(note) = { | #let get-size(note) = { | ||||||
|   let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD} |   let PAD = if note.shape == "hex" {NOTE-HEX-PAD} else {NOTE-PAD} | ||||||
| @@ -159,5 +159,7 @@ | |||||||
|         return c |         return c | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     expand-parent-group(x0, x2) | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
| @@ -67,9 +67,12 @@ | |||||||
|   if comment != none { |   if comment != none { | ||||||
|     h = calc.max(h, measure(comment).height / 1pt + 6) |     h = calc.max(h, measure(comment).height / 1pt + 6) | ||||||
|   } |   } | ||||||
|   if "linked-note" in seq { |   h = calc.max( | ||||||
|     h = calc.max(h, note.get-size(seq.linked-note).height / 2) |     h, | ||||||
|   } |     ..seq.linked-notes.map(n => { | ||||||
|  |       note.get-size(n).height / 2 | ||||||
|  |     }) | ||||||
|  |   ) | ||||||
|   ctx.y -= h |   ctx.y -= h | ||||||
|  |  | ||||||
|   let start-info = ( |   let start-info = ( | ||||||
| @@ -165,9 +168,8 @@ | |||||||
|   ) |   ) | ||||||
|  |  | ||||||
|   let y0 = start-info.y |   let y0 = start-info.y | ||||||
|   if "linked-note" in seq { |   for n in seq.linked-notes { | ||||||
|     // TODO: adapt note.render |     (n.draw)(n, y: start-info.y, forced: true) | ||||||
|     (seq.linked-note.draw)(seq.linked-note, y: start-info.y, forced: true) |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   let flip-mark = end-info.i <= start-info.i |   let flip-mark = end-info.i <= start-info.i | ||||||
| @@ -348,9 +350,14 @@ | |||||||
|     ctx.lifelines.at(i2) = dst-line |     ctx.lifelines.at(i2) = dst-line | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if "linked-note" in seq { |   if seq.linked-notes.len() != 0 { | ||||||
|     let m = note.get-size(seq.linked-note) |     end-info.y = calc.min( | ||||||
|     end-info.y = calc.min(end-info.y, y0 - m.height / 2) |       end-info.y, | ||||||
|  |       y0 - calc.max(..seq.linked-notes.map(n => { | ||||||
|  |         let m = note.get-size(n) | ||||||
|  |         return m.height / 2 | ||||||
|  |       })) | ||||||
|  |     ) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   set-ctx(c => { |   set-ctx(c => { | ||||||
|   | |||||||
| @@ -82,12 +82,12 @@ | |||||||
|   let (p1, p2) = (none, none) |   let (p1, p2) = (none, none) | ||||||
|   let cell = none |   let cell = none | ||||||
|   if note.side == "left" { |   if note.side == "left" { | ||||||
|     p1 = "[" |     p1 = note.pos2 | ||||||
|     p2 = note.pos |     p2 = note.pos | ||||||
|     cell = get-note-box(note) |     cell = get-note-box(note) | ||||||
|   } else if note.side == "right" { |   } else if note.side == "right" { | ||||||
|     p1 = note.pos |     p1 = note.pos | ||||||
|     p2 = "]" |     p2 = note.pos2 | ||||||
|     cell = get-note-box(note) |     cell = get-note-box(note) | ||||||
|   } else if note.side == "over" and note.aligned-with != none { |   } else if note.side == "over" and note.aligned-with != none { | ||||||
|     let box1 = get-note-box(note) |     let box1 = get-note-box(note) | ||||||
| @@ -220,7 +220,7 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| /// Compute remaining widths for longer sequences (spanning multiple columns) | /// Compute remaining widths for longer sequences (spanning multiple columns) | ||||||
| #let long-seq-min-col-widths(cells, widths) = { | #let long-seq-min-col-widths(participants, cells, widths) = { | ||||||
|   let widths = widths |   let widths = widths | ||||||
|   let multicol-cells = cells.filter(c => c.i2 - c.i1 > 1) |   let multicol-cells = cells.filter(c => c.i2 - c.i1 > 1) | ||||||
|   multicol-cells = multicol-cells.sorted(key: c => { |   multicol-cells = multicol-cells.sorted(key: c => { | ||||||
| @@ -228,13 +228,23 @@ | |||||||
|   }) |   }) | ||||||
|   for cell in multicol-cells { |   for cell in multicol-cells { | ||||||
|     let m = measure(cell.cell) |     let m = measure(cell.cell) | ||||||
|  |  | ||||||
|  |     let i1 = cell.i1 | ||||||
|  |     let i2 = cell.i2 - 1 | ||||||
|  |     let i = i2 | ||||||
|  |     if cell.i1 == 0 and participants.at(0).name == "[" { | ||||||
|  |       i = 0 | ||||||
|  |       i1 += 1 | ||||||
|  |       i2 += 1 | ||||||
|  |     } | ||||||
|     let width = ( |     let width = ( | ||||||
|       m.width / 1pt + |       m.width / 1pt + | ||||||
|       COMMENT-PAD - |       COMMENT-PAD - | ||||||
|       widths.slice(cell.i1, cell.i2 - 1).sum() |       widths.slice(i1, i2).sum() | ||||||
|     ) |     ) | ||||||
|     widths.at(cell.i2 - 1) = calc.max( |      | ||||||
|       widths.at(cell.i2 - 1), width |     widths.at(i) = calc.max( | ||||||
|  |       widths.at(i), width | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
|   return widths |   return widths | ||||||
| @@ -307,7 +317,7 @@ | |||||||
|   widths = notes-min-col-widths(elements, widths, pars-i) |   widths = notes-min-col-widths(elements, widths, pars-i) | ||||||
|   widths = simple-seq-min-col-widths(cells, widths) |   widths = simple-seq-min-col-widths(cells, widths) | ||||||
|   widths = self-seq-min-col-widths(cells, widths) |   widths = self-seq-min-col-widths(cells, widths) | ||||||
|   widths = long-seq-min-col-widths(cells, widths) |   widths = long-seq-min-col-widths(participants, cells, widths) | ||||||
|   widths = col-widths-add-lifelines(participants, widths) |   widths = col-widths-add-lifelines(participants, widths) | ||||||
|   widths = process-col-elements(elements, widths, pars-i) |   widths = process-col-elements(elements, widths, pars-i) | ||||||
|   return widths |   return widths | ||||||
|   | |||||||
| @@ -126,8 +126,8 @@ | |||||||
|     "linked", |     "linked", | ||||||
|     note.pos == none and note.side != "across" |     note.pos == none and note.side != "across" | ||||||
|   ) |   ) | ||||||
|  |   let names = ctx.participants.map(p => p.name) | ||||||
|   if note.pos == none and note.side != "across" { |   if note.pos == none and note.side != "across" { | ||||||
|     let names = ctx.participants.map(p => p.name) |  | ||||||
|     let i1 = names.position(n => n == ctx.last-seq.p1) |     let i1 = names.position(n => n == ctx.last-seq.p1) | ||||||
|     let i2 = names.position(n => n == ctx.last-seq.p2) |     let i2 = names.position(n => n == ctx.last-seq.p2) | ||||||
|     let pars = ( |     let pars = ( | ||||||
| @@ -141,8 +141,8 @@ | |||||||
|       note.pos = pars.last().last() |       note.pos = pars.last().last() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let seq = ctx.last-seq.seq |     let seq = ctx.elmts.at(ctx.last-seq.i) | ||||||
|     seq.insert("linked-note", note) |     seq.linked-notes.push(note) | ||||||
|     ctx.elmts.at(ctx.last-seq.i) = seq |     ctx.elmts.at(ctx.last-seq.i) = seq | ||||||
|   } |   } | ||||||
|   if note.aligned { |   if note.aligned { | ||||||
| @@ -150,10 +150,26 @@ | |||||||
|     n.aligned-with = note |     n.aligned-with = note | ||||||
|     ctx.elmts.at(ctx.last-note.i) = n |     ctx.elmts.at(ctx.last-note.i) = n | ||||||
|   } |   } | ||||||
|   if note.side == "left" { |  | ||||||
|     ctx.linked.push("[") |   if note.side in ("left", "right") { | ||||||
|   } else if note.side == "right" { |     let i = names.position(n => n == note.pos) | ||||||
|     ctx.linked.push("]") |     let pos2 = note.pos | ||||||
|  |     if note.side == "left" { | ||||||
|  |       if i <= 0 or note.allow-overlap { | ||||||
|  |         ctx.linked.push("[") | ||||||
|  |         pos2 = "[" | ||||||
|  |       } else { | ||||||
|  |         pos2 = names.at(i - 1) | ||||||
|  |       } | ||||||
|  |     } else if note.side == "right" { | ||||||
|  |       if i >= names.len() - 1 or note.allow-overlap { | ||||||
|  |         ctx.linked.push("]") | ||||||
|  |         pos2 = "]" | ||||||
|  |       } else { | ||||||
|  |         pos2 = names.at(i + 1) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     note.insert("pos2", pos2) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   let pars = none |   let pars = none | ||||||
|   | |||||||
| @@ -105,3 +105,13 @@ | |||||||
|   let ctx = c.shared-state.chronos |   let ctx = c.shared-state.chronos | ||||||
|   func(ctx) |   func(ctx) | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | #let expand-parent-group(x0, x1) = set-ctx(ctx => { | ||||||
|  |   if ctx.groups.len() != 0 { | ||||||
|  |     let group = ctx.groups.last() | ||||||
|  |     group.min-x = calc.min(group.min-x, x0) | ||||||
|  |     group.max-x = calc.max(group.max-x, x1) | ||||||
|  |     ctx.groups.last() = group | ||||||
|  |   } | ||||||
|  |   return ctx | ||||||
|  | }) | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| #import "core/draw/delay.typ" | #import "core/draw/delay.typ" | ||||||
|  | #import "core/draw/event.typ": render as evt-render | ||||||
| #import "core/draw/separator.typ" | #import "core/draw/separator.typ" | ||||||
| #import "core/draw/sync.typ" | #import "core/draw/sync.typ" | ||||||
| #import "core/utils.typ": set-ctx | #import "core/utils.typ": set-ctx | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								src/note.typ
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/note.typ
									
									
									
									
									
								
							| @@ -14,7 +14,15 @@ | |||||||
|   "hex" |   "hex" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| #let _note(side, content, pos: none, color: COL-NOTE, shape: "default", aligned: false) = { | #let _note( | ||||||
|  |   side, | ||||||
|  |   content, | ||||||
|  |   pos: none, | ||||||
|  |   color: COL-NOTE, | ||||||
|  |   shape: "default", | ||||||
|  |   aligned: false, | ||||||
|  |   allow-overlap: true | ||||||
|  | ) = { | ||||||
|   if side == "over" { |   if side == "over" { | ||||||
|     if pos == none { |     if pos == none { | ||||||
|       panic("Pos cannot be none with side 'over'") |       panic("Pos cannot be none with side 'over'") | ||||||
| @@ -37,6 +45,7 @@ | |||||||
|     color: color, |     color: color, | ||||||
|     shape: shape, |     shape: shape, | ||||||
|     aligned: aligned, |     aligned: aligned, | ||||||
|     aligned-with: none |     aligned-with: none, | ||||||
|  |     allow-overlap: allow-overlap | ||||||
|   ),) |   ),) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -38,7 +38,8 @@ | |||||||
|     disable-src: disable-src, |     disable-src: disable-src, | ||||||
|     destroy-src: destroy-src, |     destroy-src: destroy-src, | ||||||
|     lifeline-style: lifeline-style, |     lifeline-style: lifeline-style, | ||||||
|     slant: slant |     slant: slant, | ||||||
|  |     linked-notes: () | ||||||
|   ),) |   ),) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB | 
		Reference in New Issue
	
	Block a user