forked from HEL/chronos
		
	refactored groups, separators and delays
This commit is contained in:
		
							
								
								
									
										27
									
								
								src/core/draw/delay.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/core/draw/delay.typ
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
#import "../utils.typ": get-ctx, set-ctx
 | 
			
		||||
#import "../../cetz.typ": draw
 | 
			
		||||
 | 
			
		||||
#let render(delay) = get-ctx(ctx => {
 | 
			
		||||
  let y0 = ctx.y
 | 
			
		||||
  let y1 = ctx.y - delay.size
 | 
			
		||||
  for (i, line) in ctx.lifelines.enumerate() {
 | 
			
		||||
    line.lines.push(("delay-start", y0))
 | 
			
		||||
    line.lines.push(("delay-end", y1))
 | 
			
		||||
    ctx.lifelines.at(i) = line
 | 
			
		||||
  }
 | 
			
		||||
  if delay.name != none {
 | 
			
		||||
    let x0 = ctx.x-pos.first()
 | 
			
		||||
    let x1 = ctx.x-pos.last()
 | 
			
		||||
    draw.content(
 | 
			
		||||
      ((x0 + x1) / 2, (y0 + y1) / 2),
 | 
			
		||||
      anchor: "center",
 | 
			
		||||
      delay.name
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
  ctx.y = y1
 | 
			
		||||
  set-ctx(c => {
 | 
			
		||||
    c.y = ctx.y
 | 
			
		||||
    c.lifelines = ctx.lifelines
 | 
			
		||||
    return c
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										120
									
								
								src/core/draw/group.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/core/draw/group.typ
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
#import "../utils.typ": get-ctx, set-ctx
 | 
			
		||||
#import "../../consts.typ": *
 | 
			
		||||
#import "../../cetz.typ": draw
 | 
			
		||||
 | 
			
		||||
#let render-start(grp) = get-ctx(ctx => {
 | 
			
		||||
  let grp = grp
 | 
			
		||||
  ctx.y -= Y-SPACE
 | 
			
		||||
  let m = measure(
 | 
			
		||||
    box(
 | 
			
		||||
      grp.name,
 | 
			
		||||
      inset: (
 | 
			
		||||
        left: 5pt,
 | 
			
		||||
        right: 5pt,
 | 
			
		||||
        top: 3pt,
 | 
			
		||||
        bottom: 3pt
 | 
			
		||||
      ),
 | 
			
		||||
    )
 | 
			
		||||
  )
 | 
			
		||||
  ctx.groups = ctx.groups.map(g => {
 | 
			
		||||
    if g.at(1).min-i == grp.min-i { g.at(2) += 1 }
 | 
			
		||||
    if g.at(1).max-i == grp.max-i { g.at(3) += 1 }
 | 
			
		||||
    g
 | 
			
		||||
  })
 | 
			
		||||
  if grp.grp-type == "alt" {
 | 
			
		||||
    grp.insert("elses", ())
 | 
			
		||||
  }
 | 
			
		||||
  ctx.groups.push((ctx.y, grp, 0, 0))
 | 
			
		||||
  ctx.y -= m.height / 1pt
 | 
			
		||||
 | 
			
		||||
  set-ctx(c => {
 | 
			
		||||
    c.y = ctx.y
 | 
			
		||||
    c.groups = ctx.groups
 | 
			
		||||
    return c
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#let draw-group(x0, x1, y0, y1, group) = {
 | 
			
		||||
  let name = text(group.name, weight: "bold")
 | 
			
		||||
  let m = measure(box(name))
 | 
			
		||||
  let w = m.width / 1pt + 15
 | 
			
		||||
  let h = m.height / 1pt + 6
 | 
			
		||||
  draw.rect(
 | 
			
		||||
    (x0, y0),
 | 
			
		||||
    (x1, y1)
 | 
			
		||||
  )
 | 
			
		||||
  draw.merge-path(
 | 
			
		||||
    fill: COL-GRP-NAME,
 | 
			
		||||
    close: true,
 | 
			
		||||
    {
 | 
			
		||||
      draw.line(
 | 
			
		||||
        (x0, y0),
 | 
			
		||||
        (x0 + w, y0),
 | 
			
		||||
        (x0 + w, y0 - h / 2),
 | 
			
		||||
        (x0 + w - 5, y0 - h),
 | 
			
		||||
        (x0, y0 - h)
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
  draw.content(
 | 
			
		||||
    (x0, y0),
 | 
			
		||||
    name,
 | 
			
		||||
    anchor: "north-west",
 | 
			
		||||
    padding: (left: 5pt, right: 10pt, top: 3pt, bottom: 3pt)
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  if group.desc != none {
 | 
			
		||||
    draw.content(
 | 
			
		||||
      (x0 + w, y0),
 | 
			
		||||
      text([\[#group.desc\]], weight: "bold", size: .8em),
 | 
			
		||||
      anchor: "north-west",
 | 
			
		||||
      padding: 3pt
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#let draw-else(x0, x1, y, elmt) = {
 | 
			
		||||
  draw.line(
 | 
			
		||||
    (x0, y),
 | 
			
		||||
    (x1, y),
 | 
			
		||||
    stroke: (dash: (2pt, 1pt), thickness: .5pt)
 | 
			
		||||
  )
 | 
			
		||||
  draw.content(
 | 
			
		||||
    (x0, y),
 | 
			
		||||
    text([\[#elmt.desc\]], weight: "bold", size: .8em),
 | 
			
		||||
    anchor: "north-west",
 | 
			
		||||
    padding: 3pt
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#let render-end(group) = get-ctx(ctx => {
 | 
			
		||||
  ctx.y -= Y-SPACE
 | 
			
		||||
  let (start-y, group, start-lvl, end-lvl) = ctx.groups.pop()
 | 
			
		||||
  let x0 = ctx.x-pos.at(group.min-i) - start-lvl * 10 - 20
 | 
			
		||||
  let x1 = ctx.x-pos.at(group.max-i) + end-lvl * 10 + 20
 | 
			
		||||
  
 | 
			
		||||
  draw-group(x0, x1, start-y, ctx.y, group)
 | 
			
		||||
 | 
			
		||||
  if group.grp-type == "alt" {
 | 
			
		||||
    for (else-y, else-elmt) in group.elses {
 | 
			
		||||
      draw-else(x0, x1, else-y, else-elmt)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set-ctx(c => {
 | 
			
		||||
    c.y = ctx.y
 | 
			
		||||
    c.groups = ctx.groups
 | 
			
		||||
    return c
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
#let render-else(else_) = set-ctx(ctx => {
 | 
			
		||||
  ctx.y -= Y-SPACE
 | 
			
		||||
  let m = measure(text([\[#else_.desc\]], weight: "bold", size: .8em))
 | 
			
		||||
  ctx.groups.last().at(1).elses.push((
 | 
			
		||||
    ctx.y, else_
 | 
			
		||||
  ))
 | 
			
		||||
  ctx.y -= m.height / 1pt
 | 
			
		||||
  return ctx
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										46
									
								
								src/core/draw/separator.typ
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/core/draw/separator.typ
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#import "../utils.typ": get-ctx, set-ctx
 | 
			
		||||
#import "../../consts.typ": *
 | 
			
		||||
#import "../../cetz.typ": draw
 | 
			
		||||
 | 
			
		||||
#let render(sep) = get-ctx(ctx => {
 | 
			
		||||
  ctx.y -= Y-SPACE
 | 
			
		||||
 | 
			
		||||
  let x0 = ctx.x-pos.first() - 20
 | 
			
		||||
  let x1 = ctx.x-pos.last() + 20
 | 
			
		||||
  let m = measure(
 | 
			
		||||
    box(
 | 
			
		||||
      sep.name,
 | 
			
		||||
      inset: (left: 3pt, right: 3pt, top: 5pt, bottom: 5pt)
 | 
			
		||||
    )
 | 
			
		||||
  )
 | 
			
		||||
  let w = m.width / 1pt
 | 
			
		||||
  let h = m.height / 1pt
 | 
			
		||||
  let cx = (x0 + x1) / 2
 | 
			
		||||
  let xl = cx - w / 2
 | 
			
		||||
  let xr = cx + w / 2
 | 
			
		||||
 | 
			
		||||
  ctx.y -= h / 2
 | 
			
		||||
  draw.rect(
 | 
			
		||||
    (x0, ctx.y),
 | 
			
		||||
    (x1, ctx.y - 3),
 | 
			
		||||
    stroke: none,
 | 
			
		||||
    fill: white
 | 
			
		||||
  )
 | 
			
		||||
  draw.line((x0, ctx.y), (x1, ctx.y))
 | 
			
		||||
  ctx.y -= 3
 | 
			
		||||
  draw.line((x0, ctx.y), (x1, ctx.y))
 | 
			
		||||
  draw.content(
 | 
			
		||||
    ((x0 + x1) / 2, ctx.y + 1.5),
 | 
			
		||||
    sep.name,
 | 
			
		||||
    anchor: "center",
 | 
			
		||||
    padding: (5pt, 3pt),
 | 
			
		||||
    frame: "rect",
 | 
			
		||||
    fill: COL-SEP-NAME
 | 
			
		||||
  )
 | 
			
		||||
  ctx.y -= h / 2
 | 
			
		||||
 | 
			
		||||
  set-ctx(c => {
 | 
			
		||||
    c.y = ctx.y
 | 
			
		||||
    return c
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
@@ -354,7 +354,6 @@
 | 
			
		||||
},)
 | 
			
		||||
 | 
			
		||||
#let render(participants, elements) = context canvas(length: 1pt, {
 | 
			
		||||
  let shapes = ()
 | 
			
		||||
  setup-ctx(participants, elements)
 | 
			
		||||
  
 | 
			
		||||
  // Draw participants (start)
 | 
			
		||||
@@ -372,80 +371,6 @@
 | 
			
		||||
      (elmt,)
 | 
			
		||||
    } else if "draw" in elmt and elmt.type != "par" {
 | 
			
		||||
      (elmt.draw)(elmt)
 | 
			
		||||
 | 
			
		||||
    // Groups (start) -> reserve space for labels + store position
 | 
			
		||||
    } else if elmt.type == "grp" {
 | 
			
		||||
      y -= Y-SPACE
 | 
			
		||||
      let m = measure(
 | 
			
		||||
        box(
 | 
			
		||||
          elmt.name,
 | 
			
		||||
          inset: (
 | 
			
		||||
            left: 5pt,
 | 
			
		||||
            right: 5pt,
 | 
			
		||||
            top: 3pt,
 | 
			
		||||
            bottom: 3pt
 | 
			
		||||
          ),
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
      groups = groups.map(g => {
 | 
			
		||||
        if g.at(1).min-i == elmt.min-i { g.at(2) += 1 }
 | 
			
		||||
        if g.at(1).max-i == elmt.max-i { g.at(3) += 1 }
 | 
			
		||||
        g
 | 
			
		||||
      })
 | 
			
		||||
      if elmt.grp-type == "alt" {
 | 
			
		||||
        elmt.insert("elses", ())
 | 
			
		||||
      }
 | 
			
		||||
      groups.push((y, elmt, 0, 0))
 | 
			
		||||
      y -= m.height / 1pt
 | 
			
		||||
    
 | 
			
		||||
    // Groups (end) -> actual drawing
 | 
			
		||||
    } else if elmt.type == "grp-end" {
 | 
			
		||||
      y -= Y-SPACE
 | 
			
		||||
      let (start-y, group, start-lvl, end-lvl) = groups.pop()
 | 
			
		||||
      let x0 = x-pos.at(group.min-i) - start-lvl * 10 - 20
 | 
			
		||||
      let x1 = x-pos.at(group.max-i) + end-lvl * 10 + 20
 | 
			
		||||
      shapes += draw-group(x0, x1, start-y, y, group)
 | 
			
		||||
 | 
			
		||||
      if group.grp-type == "alt" {
 | 
			
		||||
        for (else-y, else-elmt) in group.elses {
 | 
			
		||||
          shapes += draw-else(x0, x1, else-y, else-elmt)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    // Alt's elses -> reserve space for label + store position
 | 
			
		||||
    } else if elmt.type == "else" {
 | 
			
		||||
      y -= Y-SPACE
 | 
			
		||||
      let m = measure(text([\[#elmt.desc\]], weight: "bold", size: .8em))
 | 
			
		||||
      groups.last().at(1).elses.push((
 | 
			
		||||
        y, elmt
 | 
			
		||||
      ))
 | 
			
		||||
      y -= m.height / 1pt
 | 
			
		||||
 | 
			
		||||
    // Separator
 | 
			
		||||
    } else if elmt.type == "sep" {
 | 
			
		||||
      let shps
 | 
			
		||||
      (y, shps) = draw-sep(elmt, y)
 | 
			
		||||
      shapes += shps
 | 
			
		||||
 | 
			
		||||
    // Delay
 | 
			
		||||
    } else if elmt.type == "delay" {
 | 
			
		||||
      let y0 = y
 | 
			
		||||
      let y1 = y - elmt.size
 | 
			
		||||
      for (i, line) in lifelines.enumerate() {
 | 
			
		||||
        line.lines.push(("delay-start", y0))
 | 
			
		||||
        line.lines.push(("delay-end", y1))
 | 
			
		||||
        lifelines.at(i) = line
 | 
			
		||||
      }
 | 
			
		||||
      if elmt.name != none {
 | 
			
		||||
        let x0 = x-pos.first()
 | 
			
		||||
        let x1 = x-pos.last()
 | 
			
		||||
        shapes += draw.content(
 | 
			
		||||
          ((x0 + x1) / 2, (y0 + y1) / 2),
 | 
			
		||||
          anchor: "center",
 | 
			
		||||
          elmt.name
 | 
			
		||||
        )
 | 
			
		||||
      }
 | 
			
		||||
      y = y1
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -476,6 +401,4 @@
 | 
			
		||||
    
 | 
			
		||||
    participant.render-lifelines()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  shapes
 | 
			
		||||
})
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
#import "utils.typ": is-elmt, get-group-span
 | 
			
		||||
#import "../participant.typ": _exists as par-exists, _par
 | 
			
		||||
#import "draw/group.typ": render-end as grp-render-end
 | 
			
		||||
 | 
			
		||||
#let flatten-group(elmts, i) = {
 | 
			
		||||
  let group = elmts.at(i)
 | 
			
		||||
@@ -9,6 +10,7 @@
 | 
			
		||||
    group.elmts +
 | 
			
		||||
    ((
 | 
			
		||||
      type: "grp-end",
 | 
			
		||||
      draw: grp-render-end,
 | 
			
		||||
      start-i: i
 | 
			
		||||
    ),) +
 | 
			
		||||
    elmts.slice(i+1)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user