mirror of
https://github.com/arsenetar/dupeguru.git
synced 2025-03-10 05:34:36 +00:00
Fix resize of top frame not updating scaled pixmap
* Also limit viewing features such as zoom levels when files have different dimensions * GraphicsViewImageViewer is still a bit buggy: the scrollbars are toggled on when the pixmap is null in the reference viewer (we do not use that class right anyway)
This commit is contained in:
parent
733b3b0ed4
commit
ac941037ff
@ -4,10 +4,10 @@
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
from PyQt5.QtCore import Qt, QSize
|
||||
from PyQt5.QtCore import Qt, QSize, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QAbstractItemView, QSizePolicy, QGridLayout, QSplitter, QFrame)
|
||||
|
||||
from PyQt5.QtGui import QResizeEvent
|
||||
from hscommon.trans import trget
|
||||
from hscommon.plat import ISWINDOWS
|
||||
from ..details_dialog import DetailsDialog as DetailsDialogBase
|
||||
@ -27,7 +27,7 @@ class DetailsDialog(DetailsDialogBase):
|
||||
self.resize(502, 502)
|
||||
self.setMinimumSize(QSize(250, 250))
|
||||
self.splitter = QSplitter(Qt.Vertical)
|
||||
self.topFrame = QFrame()
|
||||
self.topFrame = EmittingFrame()
|
||||
self.topFrame.setFrameShape(QFrame.StyledPanel)
|
||||
self.horizontalLayout = QGridLayout()
|
||||
# Minimum width for the toolbar in the middle:
|
||||
@ -76,6 +76,8 @@ class DetailsDialog(DetailsDialogBase):
|
||||
# self.setCentralWidget(self.splitter) # only as QMainWindow
|
||||
self.setWidget(self.splitter) # only as QDockWidget
|
||||
|
||||
self.topFrame.resized.connect(self.resizeEvent)
|
||||
|
||||
def _update(self):
|
||||
if self.vController is None: # Not yet constructed!
|
||||
return
|
||||
@ -90,6 +92,7 @@ class DetailsDialog(DetailsDialogBase):
|
||||
self.vController.updateView(ref, dupe, group)
|
||||
|
||||
# --- Override
|
||||
@pyqtSlot(QResizeEvent)
|
||||
def resizeEvent(self, event):
|
||||
self.ensure_same_sizes()
|
||||
if self.vController is None or not self.vController.bestFit:
|
||||
@ -136,3 +139,11 @@ class DetailsDialog(DetailsDialogBase):
|
||||
DetailsDialogBase.refresh(self)
|
||||
if self.isVisible():
|
||||
self._update()
|
||||
|
||||
|
||||
class EmittingFrame(QFrame):
|
||||
"""Emits a signal whenever is resized"""
|
||||
resized = pyqtSignal(QResizeEvent)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
self.resized.emit(event)
|
||||
|
@ -149,6 +149,7 @@ class BaseController(QObject):
|
||||
self.bestFit = True
|
||||
self.parent = parent # To change buttons' states
|
||||
self.cached_group = None
|
||||
self.same_dimensions = True
|
||||
|
||||
def setupViewers(self, selectedViewer, referenceViewer):
|
||||
self.selectedViewer = selectedViewer
|
||||
@ -163,6 +164,8 @@ class BaseController(QObject):
|
||||
|
||||
def updateView(self, ref, dupe, group):
|
||||
# To keep current scale accross dupes from the same group
|
||||
previous_same_dimensions = self.same_dimensions
|
||||
self.same_dimensions = True
|
||||
same_group = True
|
||||
if group != self.cached_group:
|
||||
same_group = False
|
||||
@ -171,6 +174,7 @@ class BaseController(QObject):
|
||||
|
||||
self.selectedPixmap = QPixmap(str(dupe.path))
|
||||
if ref is dupe: # currently selected file is the actual reference file
|
||||
# self.same_dimensions = False
|
||||
self.referencePixmap = QPixmap()
|
||||
self.scaledReferencePixmap = QPixmap()
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(False)
|
||||
@ -179,9 +183,9 @@ class BaseController(QObject):
|
||||
self.referencePixmap = QPixmap(str(ref.path))
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(True)
|
||||
if ref.dimensions != dupe.dimensions:
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(False)
|
||||
else:
|
||||
self.same_dimensions = False
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
self.updateButtonsAsPerDimensions(previous_same_dimensions)
|
||||
self.updateBothImages(same_group)
|
||||
self.centerViews(same_group and self.referencePixmap.isNull())
|
||||
|
||||
@ -217,11 +221,11 @@ class BaseController(QObject):
|
||||
# zoomed in state, expand
|
||||
# only if not same_group, we need full update
|
||||
scaledpixmap = pixmap.scaled(
|
||||
target_size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
|
||||
target_size, Qt.KeepAspectRatioByExpanding, Qt.FastTransformation)
|
||||
else:
|
||||
# best fit, keep ratio always
|
||||
scaledpixmap = pixmap.scaled(
|
||||
target_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||
target_size, Qt.KeepAspectRatio, Qt.FastTransformation)
|
||||
viewer.setImage(scaledpixmap)
|
||||
return target_size
|
||||
|
||||
@ -304,6 +308,22 @@ class BaseController(QObject):
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(round(self.current_scale, 1) != 1.0)
|
||||
self.parent.verticalToolBar.buttonBestFit.setEnabled(self.bestFit is False)
|
||||
|
||||
def updateButtonsAsPerDimensions(self, previous_same_dimensions):
|
||||
if not self.same_dimensions:
|
||||
self.parent.verticalToolBar.buttonZoomIn.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonZoomOut.setEnabled(False)
|
||||
if not self.bestFit:
|
||||
self.zoomBestFit()
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
if not self.referencePixmap.isNull():
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(True)
|
||||
return
|
||||
if not self.bestFit and not previous_same_dimensions:
|
||||
self.zoomBestFit()
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
if self.referencePixmap.isNull():
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(False)
|
||||
|
||||
@pyqtSlot()
|
||||
def zoomBestFit(self):
|
||||
"""Setup before scaling to bestfit"""
|
||||
@ -330,6 +350,7 @@ class BaseController(QObject):
|
||||
self.parent.verticalToolBar.buttonZoomOut.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
self.parent.verticalToolBar.buttonBestFit.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(True)
|
||||
|
||||
def setBestFit(self, value):
|
||||
self.bestFit = value
|
||||
@ -349,8 +370,12 @@ class BaseController(QObject):
|
||||
self.selectedViewer.scaleToNormalSize()
|
||||
self.referenceViewer.scaleToNormalSize()
|
||||
|
||||
if self.same_dimensions:
|
||||
self.parent.verticalToolBar.buttonZoomIn.setEnabled(True)
|
||||
self.parent.verticalToolBar.buttonZoomOut.setEnabled(True)
|
||||
else:
|
||||
# we can't allow swapping pixmaps of different dimensions
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonBestFit.setEnabled(True)
|
||||
|
||||
@ -371,8 +396,16 @@ class QWidgetController(BaseController):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
|
||||
def _updateImage(self, *args):
|
||||
ret = super()._updateImage(*args)
|
||||
# Fix alignment when resizing window
|
||||
self.centerViews()
|
||||
return ret
|
||||
|
||||
@pyqtSlot(QPointF)
|
||||
def onDraggedMouse(self, delta):
|
||||
if not self.same_dimensions:
|
||||
return
|
||||
if self.sender() is self.referenceViewer:
|
||||
self.selectedViewer.onDraggedMouse(delta)
|
||||
else:
|
||||
@ -410,8 +443,14 @@ class ScrollAreaController(BaseController):
|
||||
self.selectedViewer.ignore_signal = True
|
||||
self.referenceViewer.ignore_signal = True
|
||||
|
||||
if self.same_dimensions:
|
||||
self.selectedViewer.onDraggedMouse(delta)
|
||||
self.referenceViewer.onDraggedMouse(delta)
|
||||
else:
|
||||
if self.sender() is self.selectedViewer:
|
||||
self.selectedViewer.onDraggedMouse(delta)
|
||||
else:
|
||||
self.referenceViewer.onDraggedMouse(delta)
|
||||
|
||||
self.selectedViewer.ignore_signal = False
|
||||
self.referenceViewer.ignore_signal = False
|
||||
@ -432,6 +471,8 @@ class ScrollAreaController(BaseController):
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onVScrollBarChanged(self, value):
|
||||
if not self.same_dimensions:
|
||||
return
|
||||
if self.sender() is self.referenceViewer._verticalScrollBar:
|
||||
if not self.selectedViewer.ignore_signal:
|
||||
self.selectedViewer._verticalScrollBar.setValue(value)
|
||||
@ -441,6 +482,8 @@ class ScrollAreaController(BaseController):
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onHScrollBarChanged(self, value):
|
||||
if not self.same_dimensions:
|
||||
return
|
||||
if self.sender() is self.referenceViewer._horizontalScrollBar:
|
||||
if not self.selectedViewer.ignore_signal:
|
||||
self.selectedViewer._horizontalScrollBar.setValue(value)
|
||||
@ -458,6 +501,8 @@ class ScrollAreaController(BaseController):
|
||||
def zoomBestFit(self):
|
||||
# Disable scrollbars to avoid GridLayout size rounding glitch
|
||||
super().zoomBestFit()
|
||||
if self.referencePixmap.isNull():
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(False)
|
||||
self.selectedViewer.toggleScrollBars()
|
||||
self.referenceViewer.toggleScrollBars()
|
||||
|
||||
@ -494,6 +539,8 @@ class GraphicsViewController(BaseController):
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onVScrollBarChanged(self, value):
|
||||
if not self.same_dimensions:
|
||||
return
|
||||
if self.sender() is self.referenceViewer._verticalScrollBar:
|
||||
if not self.selectedViewer.ignore_signal:
|
||||
self.selectedViewer._verticalScrollBar.setValue(value)
|
||||
@ -503,6 +550,8 @@ class GraphicsViewController(BaseController):
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onHScrollBarChanged(self, value):
|
||||
if not self.same_dimensions:
|
||||
return
|
||||
if self.sender() is self.referenceViewer._horizontalScrollBar:
|
||||
if not self.selectedViewer.ignore_signal:
|
||||
self.selectedViewer._horizontalScrollBar.setValue(value)
|
||||
@ -528,9 +577,16 @@ class GraphicsViewController(BaseController):
|
||||
self.parent.verticalToolBar.buttonZoomOut.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonZoomIn.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
if not self.referencePixmap.isNull():
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(True)
|
||||
# else:
|
||||
# self.referenceViewer.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
# self.referenceViewer.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
|
||||
def updateView(self, ref, dupe, group):
|
||||
# Keep current scale accross dupes from the same group
|
||||
previous_same_dimensions = self.same_dimensions
|
||||
self.same_dimensions = True
|
||||
same_group = True
|
||||
if group != self.cached_group:
|
||||
same_group = False
|
||||
@ -539,16 +595,19 @@ class GraphicsViewController(BaseController):
|
||||
|
||||
self.selectedPixmap = QPixmap(str(dupe.path))
|
||||
if ref is dupe: # currently selected file is the actual reference file
|
||||
self.same_dimensions = False
|
||||
self.referencePixmap = QPixmap()
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(False)
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
else:
|
||||
self.referencePixmap = QPixmap(str(ref.path))
|
||||
self.parent.verticalToolBar.buttonImgSwap.setEnabled(True)
|
||||
if ref.dimensions != dupe.dimensions:
|
||||
self.same_dimensions = False
|
||||
self.parent.verticalToolBar.buttonNormalSize.setEnabled(True)
|
||||
|
||||
self.selectedViewer.setImage(self.selectedPixmap)
|
||||
self.referenceViewer.setImage(self.referencePixmap)
|
||||
# self.selectedViewer.setImage(self.selectedPixmap)
|
||||
# self.referenceViewer.setImage(self.referencePixmap)
|
||||
self.updateButtonsAsPerDimensions(previous_same_dimensions)
|
||||
self.updateBothImages(same_group)
|
||||
|
||||
def updateBothImages(self, same_group=False):
|
||||
@ -567,7 +626,9 @@ class GraphicsViewController(BaseController):
|
||||
|
||||
def _updateFitImage(self, pixmap, viewer):
|
||||
# If not same_group, we need full update"""
|
||||
viewer.setImage(pixmap)
|
||||
if pixmap.isNull():
|
||||
# viewer._item = None
|
||||
return
|
||||
if viewer.bestFit:
|
||||
viewer.fitScale()
|
||||
@ -727,7 +788,7 @@ class QWidgetImageViewer(QWidget):
|
||||
self.setMouseTracking(False)
|
||||
|
||||
def wheelEvent(self, event):
|
||||
if self.bestFit or not self.isEnabled():
|
||||
if self.bestFit or not self.controller.same_dimensions or not self.isEnabled():
|
||||
event.ignore()
|
||||
return
|
||||
|
||||
@ -920,7 +981,7 @@ class ScrollAreaImageViewer(QScrollArea):
|
||||
super().mouseReleaseEvent(event)
|
||||
|
||||
def wheelEvent(self, event):
|
||||
if self.bestFit:
|
||||
if self.bestFit or not self.controller.same_dimensions:
|
||||
event.ignore()
|
||||
return
|
||||
oldScale = self.current_scale
|
||||
@ -1044,7 +1105,7 @@ class ScrollAreaImageViewer(QScrollArea):
|
||||
|
||||
|
||||
class GraphicsViewViewer(QGraphicsView):
|
||||
"""Re-Implementation using a more full fledged class."""
|
||||
"""Re-Implementation a full-fledged GraphicsView but is a bit buggy."""
|
||||
mouseDragged = pyqtSignal()
|
||||
mouseWheeled = pyqtSignal(float, QPointF)
|
||||
|
||||
@ -1173,7 +1234,7 @@ class GraphicsViewViewer(QGraphicsView):
|
||||
self._centerPoint = self.mapToScene(self.rect().center())
|
||||
|
||||
def wheelEvent(self, event):
|
||||
if self.bestFit or MIN_SCALE > self.current_scale > MAX_SCALE:
|
||||
if self.bestFit or MIN_SCALE > self.current_scale > MAX_SCALE or not self.controller.same_dimensions:
|
||||
event.ignore()
|
||||
return
|
||||
pointBeforeScale = QPointF(self.mapToScene(self.mapFromGlobal(QCursor.pos())))
|
||||
@ -1196,6 +1257,10 @@ class GraphicsViewViewer(QGraphicsView):
|
||||
self.other_viewer.ignore_signal = False
|
||||
|
||||
def setImage(self, pixmap):
|
||||
if pixmap.isNull():
|
||||
self.ignore_signal = True
|
||||
elif self.ignore_signal:
|
||||
self.ignore_signal = False
|
||||
self._pixmap = pixmap
|
||||
self._item.setPixmap(pixmap)
|
||||
self.translate(1, 1)
|
||||
@ -1251,7 +1316,7 @@ class GraphicsViewViewer(QGraphicsView):
|
||||
"""Called when the pixmap is set back to original size."""
|
||||
self.bestFit = False
|
||||
self.scaleAt(1.0)
|
||||
self.toggleScrollBars()
|
||||
self.toggleScrollBars(True)
|
||||
self.update()
|
||||
|
||||
def adjustScrollBarsScaled(self, delta):
|
||||
|
Loading…
x
Reference in New Issue
Block a user