diff --git a/src/calibre/gui2/image_popup.py b/src/calibre/gui2/image_popup.py index 8f5c90582c..780617d58a 100644 --- a/src/calibre/gui2/image_popup.py +++ b/src/calibre/gui2/image_popup.py @@ -38,6 +38,7 @@ def render_svg(widget, path): class Label(QLabel): toggle_fit = pyqtSignal() + zoom_requested = pyqtSignal(bool) def __init__(self, scrollarea): super().__init__(scrollarea) @@ -48,6 +49,7 @@ class Label(QLabel): self.in_drag = False self.prev_drag_position = None self.scrollarea = scrollarea + self.current_wheel_angle_delta = 0 @property def is_pannable(self): @@ -74,6 +76,17 @@ class Label(QLabel): self.dragged(pos.x() - p.x(), pos.y() - p.y()) return super().mouseMoveEvent(ev) + def wheelEvent(self, ev): + if ev.modifiers() == Qt.KeyboardModifier.ControlModifier: + ad = ev.angleDelta().y() + if ad * self.current_wheel_angle_delta < 0: + self.current_wheel_angle_delta = 0 + self.current_wheel_angle_delta += ad + if abs(self.current_wheel_angle_delta) >= 120: + self.zoom_requested.emit(self.current_wheel_angle_delta < 0) + self.current_wheel_angle_delta = 0 + ev.accept() + def dragged(self, dx, dy): h = self.scrollarea.horizontalScrollBar() if h.isVisible(): @@ -111,6 +124,7 @@ class ImageView(QDialog): sa.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter) sa.setBackgroundRole(QPalette.ColorRole.Dark) self.label = l = Label(sa) + l.zoom_requested.connect(self.zoom_requested) sa.toggle_fit.connect(self.toggle_fit) sa.setWidget(l) @@ -178,6 +192,10 @@ class ImageView(QDialog): actual_height = self.current_img.size().height() return scaled_height / actual_height + def zoom_requested(self, zoom_out): + if (zoom_out and self.zo_button.isEnabled()) or (not zoom_out and self.zi_button.isEnabled()): + (self.zoom_out if zoom_out else self.zoom_in)() + def zoom_in(self): if self.fit_image.isChecked(): factor = self.factor_from_fit() @@ -285,12 +303,6 @@ class ImageView(QDialog): else: self.showNormal() - def wheelEvent(self, event): - d = event.angleDelta().y() - if abs(d) > 0 and not self.scrollarea.verticalScrollBar().isVisible(): - event.accept() - (self.zoom_out if d < 0 else self.zoom_in)() - class ImagePopup: