Пример #1
0
class PartitionItem(ElementPresentation, Named):

    DELTA = 30

    def __init__(self, id=None, model=None):
        super().__init__(id, model)
        self._toplevel = False
        self._bottom = False
        self._subpart = False
        self._hdmax = 0  # maximum subpartition header height

        self.shape = Box(
            Text(
                text=lambda: stereotypes_str(
                    self.subject,
                    self.subject and self.subject.isExternal and ("external",) or (),
                ),
            ),
            Text(text=lambda: self.subject.name or ""),
            style={
                "min-width": 0,
                "min-height": 0,
                "line-width": 2.4,
                "vertical-align": VerticalAlign.TOP,
                "padding": (2, 2, 2, 2),
            },
            draw=self.draw_partition,
        )
        self.min_width = 100
        self.min_height = 300

    @property
    def toplevel(self):
        return self._toplevel

    def pre_update(self, context):
        assert self.canvas

        self._header_size = self.shape.size(
            SizeContext.from_context(context, self.style)
        )

        # get subpartitions
        children: List[PartitionItem] = list(
            k for k in self.canvas.get_children(self) if isinstance(k, PartitionItem)
        )

        self._toplevel = self.canvas.get_parent(self) is None
        self._subpart = len(children) > 0
        self._bottom = not self._toplevel and not self._subpart

        if self._toplevel:
            self._header_size = self._header_size[0], self.DELTA

        handles = self.handles()

        # toplevel partition controls the height
        # partitions at the very bottom control the width
        # middle partitions control nothing
        for h in handles:
            h.movable = False
            h.visible = False
        if self._bottom:
            h = handles[1]
            h.visible = h.movable = True
        if self._toplevel:
            h1, h2 = handles[2:4]
            h1.visible = h1.movable = True
            h2.visible = h2.movable = True

        if self._subpart:
            wsum: int = sum(sl.width for sl in children)
            self._hdmax = max(sl._header_size[1] for sl in children)

            # extend width of swimline due the children but keep the height
            # untouched
            self.width = wsum

            dp = 0
            for sl in self.canvas.get_children(self):
                x, y = sl.matrix[4], sl.matrix[5]

                x = dp - x
                y = -y + self._header_size[1] + self._hdmax - sl._header_size[1]
                sl.matrix.translate(x, y)

                sl.height = sl.min_height = max(0, self.height - self._header_size[1])
                dp += sl.width

    def draw_partition(self, box, context, bounding_box):
        """
        By default vertical partition is drawn. It is open on the bottom.
        """
        assert self.canvas

        cr = context.cairo
        cr.set_line_width(context.style["line-width"])

        if self.subject and not self.subject.isDimension and self._toplevel:
            cr.move_to(0, 0)
            cr.line_to(bounding_box.width, 0)

        h = self._header_size[1]

        # draw outside lines if this item is toplevel partition
        if self._toplevel:
            cr.move_to(0, bounding_box.height)
            cr.line_to(0, h)
            cr.line_to(bounding_box.width, h)
            cr.line_to(bounding_box.width, bounding_box.height)

        if self._subpart:
            # header line for all subparitions
            hd = h + self._hdmax
            cr.move_to(0, hd)
            cr.line_to(bounding_box.width, hd)

        if self._subpart:
            # draw inside lines for all children but last one
            dp = 0
            for sl in self.canvas.get_children(self)[:-1]:
                dp += sl.width
                cr.move_to(dp, h)
                cr.line_to(dp, bounding_box.height)

        stroke(context)

        if context.hovered or context.dropzone:
            with cairo_state(cr):
                cr.set_dash((1.0, 5.0), 0)
                cr.set_line_width(1.0)
                cr.rectangle(0, 0, bounding_box.width, bounding_box.height)
                draw_highlight(context)
                cr.stroke()
Пример #2
0
def test_box_size():
    box = Box()

    assert box.size(cr=None) == (0, 0)
Пример #3
0
def test_box_size(context):
    box = Box()

    assert box.size(context=context) == (0, 0)