Пример #1
0
    def __init__(self,
                 model: Optional[Model] = None,
                 selection: Selection = None):
        """Create a new view.

        Args:
            model (Model): optional model to be set on construction time.
            selection (Selection): optional selection object, in case the default
                selection object (hover/select/focus) is not enough.
        """
        Gtk.DrawingArea.__init__(self)

        self._dirty_items: Set[Item] = set()

        self._back_buffer: Optional[cairo.Surface] = None
        self._back_buffer_needs_resizing = True

        self._controllers: Set[Gtk.EventController] = set()

        self.set_can_focus(True)
        if Gtk.get_major_version() == 3:
            self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK
                            | Gdk.EventMask.BUTTON_RELEASE_MASK
                            | Gdk.EventMask.POINTER_MOTION_MASK
                            | Gdk.EventMask.KEY_PRESS_MASK
                            | Gdk.EventMask.KEY_RELEASE_MASK
                            | Gdk.EventMask.SCROLL_MASK
                            | Gdk.EventMask.STRUCTURE_MASK)
            self.set_app_paintable(True)
        else:
            self.set_draw_func(GtkView.do_draw)
            self.connect_after("resize", GtkView.on_resize)

        def alignment_updated(matrix: Matrix) -> None:
            if self._model:
                self._matrix *= matrix  # type: ignore[misc]

        self._scrolling = Scrolling(alignment_updated)

        self._selection = selection or Selection()

        self._matrix = Matrix()
        self._painter: Painter = DefaultPainter(self)
        self._bounding_box_painter: ItemPainterType = ItemPainter(
            self._selection)
        self._matrix_changed = False

        self._qtree: Quadtree[Item, Tuple[float, float, float,
                                          float]] = Quadtree()

        self._model: Optional[Model] = None
        if model:
            self.model = model

        self._selection.add_handler(self.on_selection_update)
        self._matrix.add_handler(self.on_matrix_update)
Пример #2
0
    def test_lookups(self):
        qtree = Quadtree((0, 0, 100, 100))
        for i in range(100, 10):
            for j in range(100, 10):
                qtree.add("%dx%d" % (i, j), (i, j, 10, 10))

        for i in range(100, 10):
            for j in range(100, 10):
                assert qtree.find_intersect((i+1, j+1, 1, 1)) == ['%dx%d' % (i, j)], \
                        qtree.find_intersect((i+1, j+1, 1, 1))
Пример #3
0
    def test_get_data(self):
        """
        Extra data may be added to a node:
        """
        qtree = Quadtree((0, 0, 100, 100))
        for i in range(0, 100, 10):
            for j in range(0, 100, 10):
                qtree.add("%dx%d" % (i, j), (i, j, 10, 10), i+j)

        for i in range(0, 100, 10):
            for j in range(0, 100, 10):
                assert i+j == qtree.get_data("%dx%d" % (i, j))
Пример #4
0
    def test_with_rectangles(self):
        from gaphas.geometry import Rectangle

        qtree = Quadtree((0, 0, 100, 100))
        for i in range(0, 100, 10):
            for j in range(0, 100, 10):
                qtree.add("%dx%d" % (i, j), Rectangle(i, j, 10, 10))
        assert len(qtree._ids) == 100, len(qtree._ids)

        for i in range(100, 10):
            for j in range(100, 10):
                assert qtree.find_intersect((i+1, j+1, 1, 1)) == ['%dx%d' % (i, j)], \
                        qtree.find_intersect((i+1, j+1, 1, 1))
Пример #5
0
    def __init__(self, canvas=None):
        self._matrix = cairo.Matrix()
        self._painter = DefaultPainter(self)
        self._bounding_box_painter = BoundingBoxPainter(self)

        # Handling selections.
        # TODO: Move this to a context?
        self._selected_items = set()
        self._focused_item = None
        self._hovered_item = None
        self._dropzone_item = None

        self._qtree = Quadtree()
        self._bounds = Rectangle(0, 0, 0, 0)

        self._canvas = None
        if canvas:
            self._set_canvas(canvas)
Пример #6
0
    def test_moving_items(self):
        qtree = Quadtree((0, 0, 100, 100), capacity=10)
        for i in range(0, 100, 10):
            for j in range(0, 100, 10):
                qtree.add("%dx%d" % (i, j), (i, j, 10, 10))
        assert len(qtree._ids) == 100, len(qtree._ids)
        assert qtree._bucket._buckets, qtree._bucket._buckets
        for i in range(4):
            assert qtree._bucket._buckets[i]._buckets
            for j in range(4):
                assert not qtree._bucket._buckets[i]._buckets[j]._buckets

        # Check contents:
        # First sub-level contains 9 items. second level contains 4 items
        # ==> 4 * (9 + (4 * 4)) = 100
        assert len(qtree._bucket.items) == 0, qtree._bucket.items
        for i in range(4):
            assert len(qtree._bucket._buckets[i].items) == 9
            for item, bounds in qtree._bucket._buckets[i].items.iteritems():
                assert qtree._bucket.find_bucket(bounds) is qtree._bucket._buckets[i]
            for j in range(4):
                assert len(qtree._bucket._buckets[i]._buckets[j].items) == 4

        assert qtree.get_bounds('0x0')
        # Now move item '0x0' to the center of the first quadrant (20, 20)
        qtree.add('0x0', (20, 20, 10, 10))
        assert len(qtree._bucket.items) == 0
        assert len(qtree._bucket._buckets[0]._buckets[0].items) == 3, \
                qtree._bucket._buckets[0]._buckets[0].items
        assert len(qtree._bucket._buckets[0].items) == 10, \
                qtree._bucket._buckets[0].items

        # Now move item '0x0' to the second quadrant (70, 20)
        qtree.add('0x0', (70, 20, 10, 10))
        assert len(qtree._bucket.items) == 0
        assert len(qtree._bucket._buckets[0]._buckets[0].items) == 3, \
                qtree._bucket._buckets[0]._buckets[0].items
        assert len(qtree._bucket._buckets[0].items) == 9, \
                qtree._bucket._buckets[0].items
        assert len(qtree._bucket._buckets[1].items) == 10, \
                qtree._bucket._buckets[1].items
Пример #7
0
def qtree():
    qtree = Quadtree((0, 0, 100, 100))
    for i in range(0, 100, 10):
        for j in range(0, 100, 10):
            qtree.add(item=f"{i:d}x{j:d}", bounds=Rectangle(i, j, 10, 10))
    return qtree
Пример #8
0
 def test_clipped_bounds(self):
     qtree = Quadtree((0, 0, 100, 100), capacity=10)
     qtree.add(1, (-100, -100, 120, 120))
     self.assertEquals((0, 0, 20, 20), qtree.get_clipped_bounds(1))
Пример #9
0
def test_many_items_on_same_position():
    capacity = 10
    qtree: Quadtree[int, None] = Quadtree((0, 0, 0, 0), capacity=10)

    for i in range(0, capacity + 2):
        qtree.add(item=i, bounds=(0, 0, 10, 10), data=None)
Пример #10
0
def qtree():
    qtree: Quadtree[str, None] = Quadtree((0, 0, 100, 100))
    for i in range(0, 100, 10):
        for j in range(0, 100, 10):
            qtree.add(item=f"{i:d}x{j:d}", bounds=(i, j, 10, 10), data=None)
    return qtree
Пример #11
0
def qtree():
    qtree = Quadtree((0, 0, 100, 100))
    for i in range(0, 100, 10):
        for j in range(0, 100, 10):
            qtree.add(item="%dx%d" % (i, j), bounds=Rectangle(i, j, 10, 10))
    return qtree