@@ -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+
11531193void 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
11711215void 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
12871331void 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
0 commit comments