diff --git a/beeref/items.py b/beeref/items.py index 238b9ef..f09d2e3 100644 --- a/beeref/items.py +++ b/beeref/items.py @@ -539,9 +539,42 @@ def mousePressEvent(self, event): self.crop_mode_event_start = event.pos() self.crop_mode_move = edge return + if self.crop_temp.contains(event.pos()): + self.crop_mode_event_start = event.pos() + self.crop_mode_move = self.crop_temp + return # Click not in handle, end cropping mode: - self.exit_crop_mode( - confirm=self.crop_temp.contains(event.pos())) + self.exit_crop_mode(confirm=True) + + def mouseDoubleClickEvent(self, event): + if not self.crop_mode: + return super().mouseDoubleClickEvent(event) + + event.accept() + if self.crop_temp.contains(event.pos()): + self.exit_crop_mode(confirm=True) + + def ensure_crop_box_is_inside(self, point): + """Returns the modified point that ensures that the crop rectangle is + still withint the pixmap. + + The point passed is assumed to be the top + left crop rectangle position. + """ + + max_x_pos = self.pixmap().size().width() - self.crop_temp.width() + max_y_pos = self.pixmap().size().height() - self.crop_temp.height() + + if point.x() < 0: + point.setX(0) + elif point.x() > max_x_pos: + point.setX(max_x_pos) + + if point.y() < 0: + point.setY(0) + elif point.y() > max_y_pos: + point.setY(max_y_pos) + return point def ensure_point_within_crop_bounds(self, point, handle): """Returns the point, or the nearest point within the pixmap.""" @@ -549,31 +582,31 @@ def ensure_point_within_crop_bounds(self, point, handle): if handle == self.crop_handle_topleft: topleft = QtCore.QPointF(0, 0) bottomright = self.crop_temp.bottomRight() - if handle == self.crop_handle_bottomleft: + elif handle == self.crop_handle_bottomleft: topleft = QtCore.QPointF(0, self.crop_temp.top()) bottomright = QtCore.QPointF( self.crop_temp.right(), self.pixmap().size().height()) - if handle == self.crop_handle_bottomright: + elif handle == self.crop_handle_bottomright: topleft = self.crop_temp.topLeft() bottomright = QtCore.QPointF( self.pixmap().size().width(), self.pixmap().size().height()) - if handle == self.crop_handle_topright: + elif handle == self.crop_handle_topright: topleft = QtCore.QPointF(self.crop_temp.left(), 0) bottomright = QtCore.QPointF( self.pixmap().size().width(), self.crop_temp.bottom()) - if handle == self.crop_edge_top: + elif handle == self.crop_edge_top: topleft = QtCore.QPointF(0, 0) bottomright = QtCore.QPointF( self.pixmap().size().width(), self.crop_temp.bottom()) - if handle == self.crop_edge_bottom: + elif handle == self.crop_edge_bottom: topleft = QtCore.QPointF(0, self.crop_temp.top()) bottomright = QtCore.QPointF( self.pixmap().size().width(), self.pixmap().size().height()) - if handle == self.crop_edge_left: + elif handle == self.crop_edge_left: topleft = QtCore.QPointF(0, 0) bottomright = QtCore.QPointF( self.crop_temp.right(), self.pixmap().size().height()) - if handle == self.crop_edge_right: + elif handle == self.crop_edge_right: topleft = QtCore.QPointF(self.crop_temp.left(), 0) bottomright = QtCore.QPointF( self.pixmap().size().width(), self.pixmap().size().height()) @@ -586,35 +619,38 @@ def ensure_point_within_crop_bounds(self, point, handle): def mouseMoveEvent(self, event): if self.crop_mode: diff = event.pos() - self.crop_mode_event_start + if self.crop_mode_move == self.crop_temp: + new = self.ensure_crop_box_is_inside(self.crop_temp.topLeft() + diff) + self.crop_temp.moveTo(new) if self.crop_mode_move == self.crop_handle_topleft: new = self.ensure_point_within_crop_bounds( self.crop_temp.topLeft() + diff, self.crop_mode_move) self.crop_temp.setTopLeft(new) - if self.crop_mode_move == self.crop_handle_bottomleft: + elif self.crop_mode_move == self.crop_handle_bottomleft: new = self.ensure_point_within_crop_bounds( self.crop_temp.bottomLeft() + diff, self.crop_mode_move) self.crop_temp.setBottomLeft(new) - if self.crop_mode_move == self.crop_handle_bottomright: + elif self.crop_mode_move == self.crop_handle_bottomright: new = self.ensure_point_within_crop_bounds( self.crop_temp.bottomRight() + diff, self.crop_mode_move) self.crop_temp.setBottomRight(new) - if self.crop_mode_move == self.crop_handle_topright: + elif self.crop_mode_move == self.crop_handle_topright: new = self.ensure_point_within_crop_bounds( self.crop_temp.topRight() + diff, self.crop_mode_move) self.crop_temp.setTopRight(new) - if self.crop_mode_move == self.crop_edge_top: + elif self.crop_mode_move == self.crop_edge_top: new = self.ensure_point_within_crop_bounds( self.crop_temp.topLeft() + diff, self.crop_mode_move) self.crop_temp.setTop(new.y()) - if self.crop_mode_move == self.crop_edge_left: + elif self.crop_mode_move == self.crop_edge_left: new = self.ensure_point_within_crop_bounds( self.crop_temp.topLeft() + diff, self.crop_mode_move) self.crop_temp.setLeft(new.x()) - if self.crop_mode_move == self.crop_edge_bottom: + elif self.crop_mode_move == self.crop_edge_bottom: new = self.ensure_point_within_crop_bounds( self.crop_temp.bottomLeft() + diff, self.crop_mode_move) self.crop_temp.setBottom(new.y()) - if self.crop_mode_move == self.crop_edge_right: + elif self.crop_mode_move == self.crop_edge_right: new = self.ensure_point_within_crop_bounds( self.crop_temp.topRight() + diff, self.crop_mode_move) self.crop_temp.setRight(new.x()) diff --git a/beeref/scene.py b/beeref/scene.py index 56325c2..9a3e456 100644 --- a/beeref/scene.py +++ b/beeref/scene.py @@ -87,7 +87,7 @@ def end_rubberband_mode(self): def cancel_crop_mode(self): """Cancels an ongoing crop mode, if there is any.""" if self.crop_item: - self.crop_item.exit_crop_mode(confirm=False) + self.crop_item.exit_crop_mode(confirm=True) def copy_selection_to_internal_clipboard(self): self.internal_clipboard = [] @@ -394,6 +394,10 @@ def mousePressEvent(self, event): super().mousePressEvent(event) def mouseDoubleClickEvent(self, event): + if self.crop_item: + super().mouseDoubleClickEvent(event) + return + self.cancel_active_modes() item = self.itemAt(event.scenePos(), self.views()[0].transform()) if item: