예제 #1
0
    def zoom_to_items(self, items):
        """Centres view on the centre of the items and, if view is set to
        'fit to view', sets the zoom level to encompass items.
        Emits viewport_changed.
        """
        united = unite_rects(i.sceneBoundingRect() for i in items)
        if 'whole_scene' == self.zoom_mode:
            debug_print('Ensuring [{0}] items visible'.format(len(items)))
            self.ensureVisible(united)
            self.viewport_changed.emit(self.normalised_scene_rect())
        else:
            debug_print('Showing [{0}] items'.format(len(items)))
            # Add some padding around the selection
            padding = 20
            if 'follow_selection' == self.zoom_mode:
                # Update zoom
                united.adjust(-padding, -padding, 2 * padding, 2 * padding)
                self.fitInView(united, Qt.KeepAspectRatio)

                if self.absolute_zoom > self.MAXIMUM_ZOOM:
                    # new_absolute_zoom() emits viewport_changed
                    self.new_absolute_zoom(self.MAXIMUM_ZOOM)
                else:
                    self.viewport_changed.emit(self.normalised_scene_rect())
            else:
                # zoom_mode == fixed
                self.ensureVisible(united, xMargin=padding, yMargin=padding)
예제 #2
0
    def zoom_to_items(self, items):
        """Centres view on the centre of the items and, if view is set to
        'fit to view', sets the zoom level to encompass items.
        Emits viewport_changed.
        """
        united = unite_rects(i.sceneBoundingRect() for i in items)
        if 'whole_scene' == self.zoom_mode:
            debug_print('Ensuring [{0}] items visible'.format(len(items)))
            self.ensureVisible(united)
            self.viewport_changed.emit(self.normalised_scene_rect())
        else:
            debug_print('Showing [{0}] items'.format(len(items)))
            # Add some padding around the selection
            padding = 20
            if 'follow_selection' == self.zoom_mode:
                # Update zoom
                united.adjust(-padding, -padding, 2 * padding, 2 * padding)
                self.fitInView(united, Qt.KeepAspectRatio)

                if self.absolute_zoom > self.MAXIMUM_ZOOM:
                    # new_absolute_zoom() emits viewport_changed
                    self.new_absolute_zoom(self.MAXIMUM_ZOOM)
                else:
                    self.viewport_changed.emit(self.normalised_scene_rect())
            else:
                # zoom_mode == fixed
                self.ensureVisible(united, xMargin=padding, yMargin=padding)
예제 #3
0
    def new_absolute_zoom(self, factor):
        """Sets a new absolute zoom
        """
        f = factor
        scene_rect = self.scene().sceneRect()  # Scene
        view_rect = self.viewport().rect()  # Available space
        # The size of the scene if the new transform is applied
        t_scene_rect = QtGui.QTransform.fromScale(f, f).mapRect(scene_rect)

        if (t_scene_rect.width() < view_rect.width()
                and t_scene_rect.height() < view_rect.height()):
            # The user wants to zoom out so that the image is smaller than the
            # view
            self.zoom_home()
        else:
            f = min(self.MAXIMUM_ZOOM, f)
            msg = 'Change absolute zoom from [{0}] to [{1}]'
            debug_print(msg.format(self.absolute_zoom, f))

            self.setTransform(QtGui.QTransform.fromScale(f, f))
            self.fit_to_view = False

            selected = self.scene().selectedItems()
            if selected:
                # Centre on selected items
                #self.ensureVisible(unite_rects([i.rect() for i in selected]))
                self.centerOn(
                    unite_rects([i.rect() for i in selected]).center())
예제 #4
0
    def selectionChanged(self, selected, deselected):
        """QAbstractItemView virtual
        """
        # Tell the scene about the new selection
        # TODO LH Use a timer to implement a delayed refresh
        if not self.handling_selection_update:
            # TODO Context for this
            debug_print('GraphicsItemView.selectionChanged')
            self.handling_selection_update = True
            try:
                current = set(self.scene.selectedItems())
                new = set(self._rows[i.row()]
                          for i in self.selectionModel().selectedIndexes())

                for item in new.difference(current):
                    item.setSelected(True)
                    item.update()

                for item in current.difference(new):
                    item.setSelected(False)
                    item.update()

                if 1 == len(new):
                    rect = new.pop().rect()
                    for view in self.scene.views():
                        view.centerOn(rect.center())
                elif 1 < len(new):
                    # Ensure that the selected items are visible
                    rect = unite_rects([i.rect() for i in new])
                    debug_print('GraphicsItemView will make visible', rect)
                    new.pop().ensureVisible(rect)
            finally:
                self.handling_selection_update = False
예제 #5
0
    def new_absolute_zoom(self, factor):
        """Sets a new absolute zoom and emits viewport_changed.
        """
        f = factor
        scene_rect = self.scene().sceneRect()   # Scene
        view_rect = self.viewport().rect()      # Available space
        # The size of the scene if the new transform is applied
        t_scene_rect = QTransform.fromScale(f, f).mapRect(scene_rect)

        if (t_scene_rect.width() < view_rect.width() and
                t_scene_rect.height() < view_rect.height()):
            # The user wants to zoom out so that the image is smaller than the
            # view
            self.zoom_home()
        else:
            f = min(self.MAXIMUM_ZOOM, f)
            msg = 'Change absolute zoom from [{0}] to [{1}]'
            debug_print(msg.format(self.absolute_zoom, f))

            selected = self.scene().selectedItems()
            if not selected:
                # No selection so we want to centre on the mouse cursor, if it
                # is within the view. We need to get the mouse position in
                # scene coords before applying the zoom.
                mouse_pos = self.mapFromGlobal(QCursor.pos())
                if self.rect().contains(mouse_pos, proper=True):
                    mouse_pos = self.mapToScene(mouse_pos)
                else:
                    mouse_pos = None

            self.setTransform(QTransform.fromScale(f, f))

            if selected:
                # Centre on selected items
                self.centerOn(
                    unite_rects(i.sceneBoundingRect() for i in selected).center()
                )
            elif mouse_pos:
                # Centre on mouse position
                self.centerOn(mouse_pos)
            else:
                # Default behaviour is fine
                pass

        self.viewport_changed.emit(self.normalised_scene_rect())
예제 #6
0
    def new_absolute_zoom(self, factor):
        """Sets a new absolute zoom and emits viewport_changed.
        """
        f = factor
        scene_rect = self.scene().sceneRect()  # Scene
        view_rect = self.viewport().rect()  # Available space
        # The size of the scene if the new transform is applied
        t_scene_rect = QTransform.fromScale(f, f).mapRect(scene_rect)

        if (t_scene_rect.width() < view_rect.width()
                and t_scene_rect.height() < view_rect.height()):
            # The user wants to zoom out so that the image is smaller than the
            # view
            self.zoom_home()
        else:
            f = min(self.MAXIMUM_ZOOM, f)
            msg = 'Change absolute zoom from [{0}] to [{1}]'
            debug_print(msg.format(self.absolute_zoom, f))

            selected = self.scene().selectedItems()
            if not selected:
                # No selection so we want to centre on the mouse cursor, if it
                # is within the view. We need to get the mouse position in
                # scene coords before applying the zoom.
                mouse_pos = self.mapFromGlobal(QCursor.pos())
                if self.rect().contains(mouse_pos, proper=True):
                    mouse_pos = self.mapToScene(mouse_pos)
                else:
                    mouse_pos = None

            self.setTransform(QTransform.fromScale(f, f))

            if selected:
                # Centre on selected items
                self.centerOn(
                    unite_rects(i.sceneBoundingRect()
                                for i in selected).center())
            elif mouse_pos:
                # Centre on mouse position
                self.centerOn(mouse_pos)
            else:
                # Default behaviour is fine
                pass

        self.viewport_changed.emit(self.normalised_scene_rect())
예제 #7
0
    def zoom_to_items(self, items):
        """Centres view on the centre of the items and, if view is set to
        'fit to view', sets the zoom level to encompass items.
        """
        united = unite_rects(i.sceneBoundingRect() for i in items)
        if self.fit_to_view:
            debug_print('Ensuring [{0}] items visible'.format(len(items)))
            self.ensureVisible(united)
        else:
            # Some space
            # TODO LH Space should be in visible units
            debug_print('Zooming on [{0}] items'.format(len(items)))
            united.adjust(-20, -20, 40, 40)
            self.fitInView(united, Qt.KeepAspectRatio)

            # TODO LH Need a better solution
            if self.absolute_zoom > self.MAXIMUM_ZOOM:
                self.new_absolute_zoom(self.MAXIMUM_ZOOM)
예제 #8
0
    def toggle_zoom(self):
        """Toggles between 'fit to screen' and a mild zoom / zoom to selected
        """
        if self.fit_to_view:
            selected = self.scene().selectedItems()
            if selected:
                r = unite_rects([i.rect() for i in selected])

                # Some space
                r.adjust(-20, -20, 40, 40)
                self.fitInView(r, Qt.KeepAspectRatio)
                self.fit_to_view = False
                # TODO LH Need a better solution
                if self.absolute_zoom > self.MAXIMUM_ZOOM:
                    self.new_absolute_zoom(self.MAXIMUM_ZOOM)
            else:
                self.new_relative_zoom(4.0)
        else:
            self.zoom_home()