diff --git a/booru_viewer/gui/grid.py b/booru_viewer/gui/grid.py index ee9ef70..6cf6d04 100644 --- a/booru_viewer/gui/grid.py +++ b/booru_viewer/gui/grid.py @@ -27,6 +27,7 @@ class ThumbnailWidget(QWidget): clicked = Signal(int, object) # index, QMouseEvent double_clicked = Signal(int) right_clicked = Signal(int, object) # index, QPoint + padding_clicked = Signal(object) # QMouseEvent — click missed the pixmap # QSS-controllable dot colors _saved_color = QColor("#22cc22") @@ -306,7 +307,7 @@ class ThumbnailWidget(QWidget): def mousePressEvent(self, event) -> None: if event.button() == Qt.MouseButton.LeftButton: if not self._hit_pixmap(event.position().toPoint()): - event.ignore() + self.padding_clicked.emit(event) return self._drag_start = event.position().toPoint() self.clicked.emit(self.index, event) @@ -320,7 +321,7 @@ class ThumbnailWidget(QWidget): self._drag_start = None if event.button() == Qt.MouseButton.LeftButton: if not self._hit_pixmap(event.position().toPoint()): - event.ignore() + self.padding_clicked.emit(event) return self.double_clicked.emit(self.index) @@ -471,6 +472,7 @@ class ThumbnailGrid(QScrollArea): thumb.clicked.connect(self._on_thumb_click) thumb.double_clicked.connect(self._on_thumb_double_click) thumb.right_clicked.connect(self._on_thumb_right_click) + thumb.padding_clicked.connect(self._on_padding_click) self._flow.add_widget(thumb) self._thumbs.append(thumb) @@ -485,6 +487,7 @@ class ThumbnailGrid(QScrollArea): thumb.clicked.connect(self._on_thumb_click) thumb.double_clicked.connect(self._on_thumb_double_click) thumb.right_clicked.connect(self._on_thumb_right_click) + thumb.padding_clicked.connect(self._on_padding_click) self._flow.add_widget(thumb) self._thumbs.append(thumb) new_thumbs.append(thumb) @@ -565,22 +568,28 @@ class ThumbnailGrid(QScrollArea): self.ensureWidgetVisible(self._thumbs[index]) self.context_requested.emit(index, pos) + def _start_rubber_band(self, pos: QPoint) -> None: + """Start a rubber band selection and deselect.""" + self._rb_origin = pos + if not self._rubber_band: + self._rubber_band = QRubberBand(QRubberBand.Shape.Rectangle, self.viewport()) + self._rubber_band.setGeometry(QRect(self._rb_origin, QSize())) + self._rubber_band.show() + self.clear_selection() + + def _on_padding_click(self, event: QMouseEvent) -> None: + """Cell padding click — treat as empty space.""" + # Map the event position from the ThumbnailWidget to the viewport + thumb = self.sender() + if thumb: + vp_pos = self.viewport().mapFrom(thumb, event.position().toPoint()) + self._start_rubber_band(vp_pos) + def mousePressEvent(self, event: QMouseEvent) -> None: if event.button() == Qt.MouseButton.LeftButton: child = self.childAt(event.position().toPoint()) - # Empty space: flow layout, viewport, or cell padding (missed pixmap) - is_empty = child is self.widget() or child is self.viewport() - if not is_empty and isinstance(child, ThumbnailWidget): - local = child.mapFrom(self, event.position().toPoint()) - if not child._hit_pixmap(local): - is_empty = True - if is_empty: - self._rb_origin = event.position().toPoint() - if not self._rubber_band: - self._rubber_band = QRubberBand(QRubberBand.Shape.Rectangle, self.viewport()) - self._rubber_band.setGeometry(QRect(self._rb_origin, QSize())) - self._rubber_band.show() - self.clear_selection() + if child is self.widget() or child is self.viewport(): + self._start_rubber_band(event.position().toPoint()) return super().mousePressEvent(event)