Esempio n. 1
0
def create_orthogonal_constraints(handles: Sequence[Handle],
                                  horizontal: bool) -> Iterable[Constraint]:
    rest = 1 if horizontal else 0
    for pos, (h0, h1) in enumerate(zip(handles, handles[1:])):
        p0 = h0.pos
        p1 = h1.pos
        if pos % 2 == rest:
            yield EqualsConstraint(a=p0.x, b=p1.x)
        else:
            yield EqualsConstraint(a=p0.y, b=p1.y)
Esempio n. 2
0
def test_juggle_error_is_raised_when_constraints_can_not_be_resolved():
    solver = Solver()
    a = Variable()
    b = Variable()
    c = Variable(40, strength=REQUIRED)
    d = Variable(30, strength=REQUIRED)

    solver.add_constraint(EqualsConstraint(a, b))
    solver.add_constraint(EqualsConstraint(a, c))
    solver.add_constraint(EqualsConstraint(b, d))

    with pytest.raises(JuggleError):
        solver.solve()
Esempio n. 3
0
def test_reconnect_item(connections):
    i = item.Line(connections)
    ii = item.Line(connections)

    cons1 = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)
    cons2 = EqualsConstraint(i.handles()[0].pos.y, i.handles()[0].pos.y)
    connections.connect_item(i, i.handles()[0], ii, ii.ports()[0], cons1)

    assert connections.get_connection(i.handles()[0]).constraint is cons1
    assert cons1 in connections.solver.constraints

    connections.reconnect_item(i, i.handles()[0], constraint=cons2)

    assert connections.get_connection(i.handles()[0]).constraint is cons2
    assert cons1 not in connections.solver.constraints
    assert cons2 in connections.solver.constraints
Esempio n. 4
0
def test_remove_item_constraint_when_item_is_disconnected(connections):
    i = item.Line(connections)
    c1 = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)

    connections.add_constraint(i, c1)
    connections.disconnect_item(i)

    assert list(connections.get_connections(item=i)) == []
Esempio n. 5
0
    def setup_canvas(self):
        super(LifelineItem, self).setup_canvas()

        top = self.lifetime.top
        bottom = self.lifetime.bottom

        # create constraints to:
        # - keep bottom handle below top handle
        # - keep top and bottom handle in the middle of the head
        c1 = CenterConstraint(self._handles[SW].pos.x, self._handles[SE].pos.x, bottom.pos.x)

        c2 = EqualsConstraint(top.pos.x, bottom.pos.x, delta=0.0)

        c3 = EqualsConstraint(self._handles[SW].pos.y, top.pos.y, delta=0.0)
        self.lifetime._c_min_length = LessThanConstraint(top.pos.y, bottom.pos.y, delta=LifetimeItem.MIN_LENGTH)
        self.__constraints = (c1, c2, c3, self.lifetime._c_min_length)

        list(map(self.canvas.solver.add_constraint, self.__constraints))
Esempio n. 6
0
    def setup_canvas(self):
        super().setup_canvas()

        h1, h2 = self._handles
        cadd = self.canvas.solver.add_constraint
        c1 = EqualsConstraint(a=h1.pos.x, b=h2.pos.x)
        c2 = LessThanConstraint(smaller=h1.pos.y, bigger=h2.pos.y, delta=30)
        self.__constraints = (cadd(c1), cadd(c2))
        list(map(self.canvas.solver.add_constraint, self.__constraints))
Esempio n. 7
0
    def setup_constraints(self):
        top = self.lifetime.top
        bottom = self.lifetime.bottom

        # create constraints to:
        # - keep bottom handle below top handle
        # - keep top and bottom handle in the middle of the head
        c1 = CenterConstraint(self._handles[SW].pos.x, self._handles[SE].pos.x,
                              bottom.pos.x)

        c2 = EqualsConstraint(top.pos.x, bottom.pos.x, delta=0.0)

        c3 = EqualsConstraint(self._handles[SW].pos.y, top.pos.y, delta=0.0)
        self.lifetime._c_min_length = LessThanConstraint(
            top.pos.y, bottom.pos.y, delta=LifetimeItem.MIN_LENGTH)

        for c in [c1, c2, c3, self.lifetime._c_min_length]:
            self._connections.add_constraint(self, c)
Esempio n. 8
0
def test_add_item_constraint(connections):
    i = item.Line(connections)
    c1 = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)

    connections.add_constraint(i, c1)

    cinfo = next(connections.get_connections(item=i))

    assert cinfo.item is i
    assert cinfo.constraint is c1
Esempio n. 9
0
def test_notify_on_constraint_solved(connections):
    events = []

    def on_notify(cinfo):
        events.append(cinfo)

    i = item.Line(connections)
    c = EqualsConstraint(i.handles()[0].pos.x, i.handles()[0].pos.x)
    connections.add_constraint(i, c)

    connections.add_handler(on_notify)
    connections.solve()

    assert events
    assert events[0].constraint is c
Esempio n. 10
0
    def test_min_size(self):
        """Test minimal size constraint"""
        solver = Solver()
        v1 = Variable(0)
        v2 = Variable(10)
        v3 = Variable(10)
        c1 = EqualsConstraint(a=v2, b=v3)
        c2 = LessThanConstraint(smaller=v1, bigger=v3, delta=10)
        solver.add_constraint(c1)
        solver.add_constraint(c2)

        # check everyting is ok on start
        solver.solve()
        self.assertEquals(0, v1)
        self.assertEquals(10, v2)
        self.assertEquals(10, v3)

        # change v1 to 2, after solve it should be 0 again due to LT
        # constraint
        v1.value = 2
        solver.solve()

        self.assertEquals(0, v1)
        self.assertEquals(10, v2)
        self.assertEquals(10, v3)

        # change v3 to 20, after solve v2 will follow thanks to EQ
        # constraint
        v3.value = 20
        solver.solve()

        self.assertEquals(0, v1)
        self.assertEquals(20, v2)
        self.assertEquals(20, v3)

        # change v3 to 0, after solve it shoul be 10 due to LT.delta = 10,
        # v2 should also be 10 due to EQ constraint
        v3.value = 0
        solver.solve()

        self.assertEquals(0, v1)
        self.assertEquals(10, v2)
        self.assertEquals(10, v3)
Esempio n. 11
0
def test_min_size(solv):
    """Test minimal size constraint.

    """
    v1 = Variable(0)
    v2 = Variable(10)
    v3 = Variable(10)
    c1 = EqualsConstraint(a=v2, b=v3)
    c2 = LessThanConstraint(smaller=v1, bigger=v3, delta=10)
    solv.solver.add_constraint(c1)
    solv.solver.add_constraint(c2)

    # Check everything is ok on start
    solv.solver.solve()
    assert 0 == v1
    assert 10 == v2
    assert 10 == v3

    # Change v1 to 2, after solve it should be 0 again due to LT constraint
    v1.value = 2
    solv.solver.solve()

    assert 0 == v1
    assert 10 == v2
    assert 10 == v3

    # Change v3 to 20, after solve v2 will follow thanks to EQ constraint
    v3.value = 20
    solv.solver.solve()

    assert 0 == v1
    assert 20 == v2
    assert 20 == v3

    # Change v3 to 0, after solve it should be 10 due to LT.delta = 10, v2
    # should also be 10 due to EQ constraint
    v3.value = 0
    solv.solver.solve()

    assert 0 == v1
    assert 10 == v2
    assert 10 == v3
Esempio n. 12
0
def test_notify_for_nested_constraint():
    events = []
    solver = Solver()
    a = Variable()
    b = Variable()
    nested = EqualsConstraint(a, b)
    multi = MultiConstraint(nested)

    solver.add_constraint(multi)
    solver.solve()

    def handler(constraint):
        events.append(constraint)

    solver.add_handler(handler)

    a.value = 10

    solver.solve()

    assert multi in events
    assert nested not in events
Esempio n. 13
0
    def constraint(
        self,
        horizontal=None,
        vertical=None,
        left_of=None,
        above=None,
        line=None,
        delta=0.0,
        align=None,
    ):
        """
        Utility (factory) method to create item's internal constraint
        between two positions or between a position and a line.

        Position is a tuple of coordinates, i.e. ``(2, 4)``.

        Line is a tuple of positions, i.e. ``((2, 3), (4, 2))``.

        This method shall not be used to create constraints between
        two different items.

        Created constraint is returned.

        :Parameters:
         horizontal=(p1, p2)
            Keep positions ``p1`` and ``p2`` aligned horizontally.
         vertical=(p1, p2)
            Keep positions ``p1`` and ``p2`` aligned vertically.
         left_of=(p1, p2)
            Keep position ``p1`` on the left side of position ``p2``.
         above=(p1, p2)
            Keep position ``p1`` above position ``p2``.
         line=(p, l)
            Keep position ``p`` on line ``l``.
        """
        cc = None  # created constraint
        if horizontal:
            p1, p2 = horizontal
            cc = EqualsConstraint(p1[1], p2[1], delta)
        elif vertical:
            p1, p2 = vertical
            cc = EqualsConstraint(p1[0], p2[0], delta)
        elif left_of:
            p1, p2 = left_of
            cc = LessThanConstraint(p1[0], p2[0], delta)
        elif above:
            p1, p2 = above
            cc = LessThanConstraint(p1[1], p2[1], delta)
        elif line:
            pos, l = line
            if align is None:
                cc = LineConstraint(line=l, point=pos)
            else:
                cc = LineAlignConstraint(line=l,
                                         point=pos,
                                         align=align,
                                         delta=delta)
        else:
            raise ValueError("Constraint incorrectly specified")
        assert cc is not None
        self._constraints.append(cc)
        return cc