Skip to content

Commit be7d6b5

Browse files
committed
Zoomed images now stay centered during resize
1 parent 003a62a commit be7d6b5

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

src/viewer/scalable_image_label.cpp

+28-3
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@ ScalableImageLabel::ScalableImageLabel(QScrollArea* parent) : QLabel(parent), pa
4545
void ScalableImageLabel::setImage(const QImage& image)
4646
{
4747
fullSizePixmap = QPixmap::fromImage(image);
48+
imageLoaded = true;
49+
setPixmap(fullSizePixmap);
4850
fillMode = true;
4951
setBarsEnabled(false);
50-
setPixmap(fullSizePixmap);
51-
imageLoaded = true;
52+
imageCenter = QPoint();
5253
setHandCursor(true);
5354
}
5455

@@ -60,6 +61,7 @@ void ScalableImageLabel::clearImage()
6061
fullSizePixmap = QPixmap();
6162
setPixmap(QPixmap());
6263
imageLoaded = false;
64+
imageCenter = QPoint();
6365
setNormalCursor();
6466
}
6567

@@ -135,6 +137,12 @@ void ScalableImageLabel::wheelEvent(QWheelEvent* event)
135137
int newMaxScrollY = newImageHeight - availableArea.height();
136138
setMaxScroll(newMaxScrollX, newMaxScrollY);
137139
setScroll(newScrollX, newScrollY);
140+
141+
// Calculate and save new center position
142+
saveNewImageCenter();
143+
}
144+
else {
145+
imageCenter = QPoint();
138146
}
139147

140148
event->accept();
@@ -156,7 +164,7 @@ void ScalableImageLabel::paintEvent(QPaintEvent* event)
156164
if (!imageLoaded) return;
157165
QSize availableArea = parent->maximumViewportSize();
158166
bool resize = false;
159-
167+
160168
// Resize if max-zoomed image is smaller than the available area
161169
resize |= MAX_ZOOM_RATIO * fullSizePixmap.width() < availableArea.width() && MAX_ZOOM_RATIO * fullSizePixmap.height() < availableArea.height();
162170
// Resize if fill mode is active but the image is bigger than the available area
@@ -172,6 +180,13 @@ void ScalableImageLabel::paintEvent(QPaintEvent* event)
172180
}
173181
}
174182

183+
if (!fillMode) {
184+
// Make sure image stays centered
185+
int moveX = getScrollX() + availableArea.width() / 2 - imageCenter.x();
186+
int moveY = getScrollY() + availableArea.height() / 2 - imageCenter.y();
187+
if (moveX || moveY) scrollRelative(QPoint(moveX, moveY));
188+
}
189+
175190
QLabel::paintEvent(event);
176191
}
177192

@@ -207,6 +222,7 @@ void ScalableImageLabel::mouseMoveEvent(QMouseEvent* event)
207222
if (!imageLoaded || fillMode || mousePressedAt.isNull()) return;
208223
QPoint mouseMove = event->globalPosition().toPoint() - mousePressedAt;
209224
scrollRelative(mouseMove);
225+
saveNewImageCenter();
210226
mousePressedAt = event->globalPosition().toPoint();
211227
}
212228

@@ -229,6 +245,15 @@ void ScalableImageLabel::mouseReleaseEvent(QMouseEvent* event)
229245

230246

231247

248+
void ScalableImageLabel::saveNewImageCenter()
249+
{
250+
QSize availableArea = parent->maximumViewportSize();
251+
int centerX = getScrollX() + availableArea.width () / 2;
252+
int centerY = getScrollY() + availableArea.height() / 2;
253+
imageCenter = QPoint(centerX, centerY);
254+
}
255+
256+
232257
/**
233258
* Sets the enabled status of the parent QScrollArea's scroll bars.
234259
*

src/viewer/scalable_image_label.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,19 @@ class ScalableImageLabel : public QLabel
4343

4444
/** The parent QScrollArea. */
4545
QScrollArea* parent;
46-
/** The image to display in full available resolution. */
47-
QPixmap fullSizePixmap;
4846
/** Indicates whether an image is currently loaded and displayed. */
4947
bool imageLoaded;
48+
/** The image to display in full available resolution. */
49+
QPixmap fullSizePixmap;
5050
/**
5151
* Indicates whether the image should be scaled to fill the available space.
5252
* This mode is enabled by default, whenever the full-size image is smaller than the available
5353
* space and when the user has zoomed all the way back out.
5454
*/
5555
bool fillMode;
5656

57+
/** When fill mode is inactive, indicates where in the current size of the image the center of the displayed area is. */
58+
QPoint imageCenter;
5759
/** The location where the mouse was last registered after being pressed over the image. Used for dragging. */
5860
QPoint mousePressedAt;
5961

@@ -78,6 +80,8 @@ private slots:
7880
void mouseReleaseEvent(QMouseEvent* event) override;
7981

8082
private:
83+
void saveNewImageCenter();
84+
8185
void setBarsEnabled(bool enabled) const;
8286
int getScrollX() const;
8387
int getScrollY() const;

0 commit comments

Comments
 (0)