diff --git a/boxes/__init__.py b/boxes/__init__.py index c5b43927..fd6e4fb6 100755 --- a/boxes/__init__.py +++ b/boxes/__init__.py @@ -1217,7 +1217,7 @@ def move(self, x, y, where, before=False, label=""): self.moveTo(x, 0) self.ctx.scale(-1, 1) self.moveTo(self.spacing / 2.0, self.spacing / 2.0) - self.ctx.new_part() + self.ctx.new_part(previous_part_name=label) return dontdraw diff --git a/boxes/drawing.py b/boxes/drawing.py index da1e78c2..31192c1f 100644 --- a/boxes/drawing.py +++ b/boxes/drawing.py @@ -87,7 +87,17 @@ def transform(self, f, m, invert_y=False): for p in self.parts: p.transform(f, m, invert_y) - def new_part(self, name="part"): + def new_part(self, name="part", previous_part_name=None): + """Insert a new part into the surface; any subsequent drawing commands + will be grouped into this part, and the previously active part is + closed. + + previous_part_name allows naming the part that is being closed. This + allows parts created by the Boxes.move mechanism to obtain their + names.""" + if previous_part_name is not None: + assert self.parts, "previous_part_name can not be set for the first part on a surface" + self.parts[-1].name = previous_part_name if self.parts and len(self.parts[-1].pathes) == 0: return self._p p = Part(name) @@ -115,6 +125,7 @@ def extents(self): class Part: def __init__(self, name) -> None: + self.name: str = name self.pathes: list[Any] = [] self.path: list[Any] = [] @@ -402,8 +413,8 @@ def flush(self): # self.stroke() ## additional methods - def new_part(self): - self._dwg.new_part() + def new_part(self, *args, **kwargs): + self._dwg.new_part(*args, **kwargs) class SVGSurface(Surface): @@ -525,6 +536,8 @@ def finish(self, inner_corners="loop"): continue g = ET.SubElement(svg, "g", id=f"p-{i}", style="fill:none;stroke-linecap:round;stroke-linejoin:round;") + if part.name: + ET.SubElement(g, "title").text = part.name g.text = "\n " g.tail = "\n" for j, path in enumerate(part.pathes):