Skip to content

Commit 456da21

Browse files
committed
main: Preserve image view position as much as possible
This makes it so the current scroll percentage on both axes is saved by most calls of refreshPreviews() prior to calling resetPreviewLayout(). Fixes issue #14.
1 parent 5cc4c18 commit 456da21

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-13
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Version 0.5.1
1111

1212
### Bug fixes
1313

14+
* The image view no longer scrolls back to the center of the image when zooming in/out, selecting a different color range/palette/transform type, or closing Preferences (#14).
1415
* Fixed QuaZip-related build errors with Qt 6.7.2 and later when using `ENABLE_BUILTIN_IMAGE_PLUGINS`.
1516

1617
### Other changes

src/mainwindow.cpp

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ void MainWindow::dropEvent(QDropEvent* event)
949949
updateWindowTitle(true, {}, ImageOriginDrop);
950950
}
951951

952-
refreshPreviews();
952+
refreshPreviews(false, false);
953953
enableWorkArea(true);
954954
}
955955

@@ -1072,7 +1072,7 @@ void MainWindow::openFile(const QString& fileName)
10721072
MosCurrentConfig().addRecentFile(imagePath_, originalImage_);
10731073
updateRecentFilesMenu();
10741074
updateWindowTitle(true, imagePath_);
1075-
refreshPreviews();
1075+
refreshPreviews(false, false);
10761076

10771077
enableWorkArea(true);
10781078
}
@@ -1091,11 +1091,28 @@ void MainWindow::doReloadFile()
10911091
refreshPreviews();
10921092
}
10931093

1094-
void MainWindow::refreshPreviews(bool skipRerender)
1094+
void MainWindow::refreshPreviews(bool skipRerender, bool keepPos)
10951095
{
10961096
if (!hasImage() || signalsBlocked())
10971097
return;
10981098

1099+
QPointF previewPos{50.0, 50.0};
1100+
1101+
if (keepPos) {
1102+
switch (viewMode_)
1103+
{
1104+
case MosConfig::ImageViewSwipe:
1105+
case MosConfig::ImageViewOnionSkin:
1106+
previewPos = currentScrollPercent(ui->previewCompositeContainer);
1107+
break;
1108+
default:
1109+
// In reality we only need one container's position, as the other
1110+
// one will be automatically adjusted in tandem with whichever we
1111+
// choose to modify next
1112+
previewPos = currentScrollPercent(ui->previewOriginalContainer);
1113+
}
1114+
}
1115+
10991116
if (!skipRerender) {
11001117
switch (rcMode_)
11011118
{
@@ -1134,7 +1151,7 @@ void MainWindow::refreshPreviews(bool skipRerender)
11341151
case MosConfig::ImageViewSwipe:
11351152
case MosConfig::ImageViewOnionSkin:
11361153
ui->previewComposite->setImages(originalImage_, transformedImage_);
1137-
resetPreviewLayout(ui->previewCompositeContainer, ui->previewComposite);
1154+
resetPreviewLayout(ui->previewCompositeContainer, ui->previewComposite, previewPos);
11381155

11391156
ui->previewOriginal->clear();
11401157
ui->previewRc->clear();
@@ -1145,13 +1162,37 @@ void MainWindow::refreshPreviews(bool skipRerender)
11451162

11461163
ui->previewOriginal->setImage(originalImage_);
11471164
ui->previewRc->setImage(transformedImage_);
1148-
resetPreviewLayout(ui->previewOriginalContainer, ui->previewOriginal);
1149-
resetPreviewLayout(ui->previewRcContainer, ui->previewRc);
1165+
resetPreviewLayout(ui->previewOriginalContainer, ui->previewOriginal, previewPos);
1166+
resetPreviewLayout(ui->previewRcContainer, ui->previewRc, previewPos);
11501167
}
11511168
}
11521169

1170+
QPointF MainWindow::currentScrollPercent(QAbstractScrollArea* scrollArea) const
1171+
{
1172+
QPointF res{50.0, 50.0};
1173+
1174+
if (!scrollArea)
1175+
return res;
1176+
1177+
auto* hScroll = scrollArea->horizontalScrollBar();
1178+
auto* vScroll = scrollArea->verticalScrollBar();
1179+
1180+
// If the scrollbars are locked because the image hasn't been zoomed in
1181+
// enough to allow scrolling, pretend that they are set to the halfway
1182+
// point on the relevant axis. This prevents zooming in from scrolling the
1183+
// view to the top left corner of the image every time.
1184+
1185+
if (hScroll && hScroll->minimum() != hScroll->maximum())
1186+
res.setX(100.0 * hScroll->value() / hScroll->maximum());
1187+
if (vScroll && vScroll->minimum() != vScroll->maximum())
1188+
res.setY(100.0 * vScroll->value() / vScroll->maximum());
1189+
1190+
return res;
1191+
}
1192+
11531193
void MainWindow::resetPreviewLayout(QAbstractScrollArea* scrollArea,
1154-
QWidget* previewWidget)
1194+
QWidget* previewWidget,
1195+
QPointF scrollPercent)
11551196
{
11561197
if (!scrollArea || !previewWidget)
11571198
return;
@@ -1164,8 +1205,11 @@ void MainWindow::resetPreviewLayout(QAbstractScrollArea* scrollArea,
11641205
auto* hScroll = scrollArea->horizontalScrollBar();
11651206
auto* vScroll = scrollArea->verticalScrollBar();
11661207

1167-
hScroll->setValue(hScroll->maximum() / 2);
1168-
vScroll->setValue(vScroll->maximum() / 2);
1208+
auto hPerc = qBound(0.0, scrollPercent.x(), 100.0);
1209+
auto vPerc = qBound(0.0, scrollPercent.y(), 100.0);
1210+
1211+
hScroll->setValue(hScroll->maximum() * hPerc / 100.0);
1212+
vScroll->setValue(vScroll->maximum() * vPerc / 100.0);
11691213
}
11701214

11711215
void MainWindow::doSaveFile()
@@ -1281,7 +1325,7 @@ void MainWindow::setViewMode(MainWindow::ViewMode newViewMode)
12811325
ui->cbxViewMode->setCurrentIndex(viewMode_);
12821326

12831327
// Update preview widgets if applicable
1284-
refreshPreviews(true);
1328+
refreshPreviews(true, false);
12851329
}
12861330

12871331
void MainWindow::setRcMode(MainWindow::RcMode newRcMode)
@@ -1923,7 +1967,7 @@ void MainWindow::on_actionPaste_triggered()
19231967
imagePath_ = tr("Clipboard image") % ".png";
19241968
updateWindowTitle(true, {}, ImageOriginClipboard);
19251969

1926-
refreshPreviews();
1970+
refreshPreviews(false, false);
19271971
enableWorkArea(true);
19281972
}
19291973

src/mainwindow.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class MainWindow : public QMainWindow {
191191
QStringList doSaveColorBlend(const QString& dirPath);
192192
QStringList doSaveColorShift(const QString& dirPath);
193193

194-
void refreshPreviews(bool skipRerender = false);
194+
void refreshPreviews(bool skipRerender = false, bool keepPos = true);
195195

196196
QString currentPaletteName(bool paletteSwitchMode = false) const;
197197
ColorList currentPalette(bool paletteSwitchMode = false) const;
@@ -200,8 +200,11 @@ class MainWindow : public QMainWindow {
200200

201201
void setPreviewBackgroundColor(const QString& colorName);
202202

203+
QPointF currentScrollPercent(QAbstractScrollArea* scrollArea) const;
204+
203205
void resetPreviewLayout(QAbstractScrollArea* scrollArea,
204-
QWidget* previewWidget);
206+
QWidget* previewWidget,
207+
QPointF scrollPercent);
205208

206209
void doCustomPreviewBgSelect();
207210
void updateCustomPreviewBgIcon();

0 commit comments

Comments
 (0)