Skip to content

Commit 722a5c0

Browse files
authored
Merge pull request #123 from pablogventura/fix/output-reload-preserve-zoom-21
fix(ui): preserve Output preview zoom on parameter reload (#21)
2 parents 5669ab1 + 6dba21f commit 722a5c0

2 files changed

Lines changed: 78 additions & 6 deletions

File tree

src/app/MainWindow.cpp

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ MainWindow::MainWindow()
106106
m_interactiveQueue(std::make_unique<ProcessingTaskQueue>()),
107107
m_outOfMemoryDialog(std::make_unique<OutOfMemoryDialog>()),
108108
m_curFilter(0),
109-
m_savedZoomLevel(1.0),
109+
m_savedMainAreaViewState(),
110110
m_ignoreSelectionChanges(0),
111111
m_ignorePageOrderingChanges(0),
112112
m_debug(false),
@@ -710,6 +710,54 @@ void MainWindow::setOptionsWidget(FilterOptionsWidget* widget, const Ownership o
710710
connect(widget, SIGNAL(fixDpiRequested()), this, SLOT(fixDpiDialogRequested()));
711711
} // MainWindow::setOptionsWidget
712712

713+
ImageViewBase* MainWindow::findPrimaryImageView(QWidget* root) {
714+
if (!root) {
715+
return nullptr;
716+
}
717+
if (auto* tabs = qobject_cast<output::TabbedImageView*>(root)) {
718+
QWidget* const page = tabs->currentWidget();
719+
if (page) {
720+
return Utils::castOrFindChild<ImageViewBase*>(page);
721+
}
722+
return nullptr;
723+
}
724+
return Utils::castOrFindChild<ImageViewBase*>(root);
725+
}
726+
727+
void MainWindow::applySavedMainAreaViewState(ImageViewBase* view, const SavedMainAreaViewState& state) {
728+
if (!view) {
729+
return;
730+
}
731+
view->setZoomLevel(state.zoom);
732+
if (!state.hasScrollNorm) {
733+
return;
734+
}
735+
QScrollBar* const h = view->horizontalScrollBar();
736+
QScrollBar* const v = view->verticalScrollBar();
737+
const int hr = h->maximum() - h->minimum();
738+
const int vr = v->maximum() - v->minimum();
739+
if (hr <= 0 || vr <= 0) {
740+
return;
741+
}
742+
const double nx = qBound(0.0, state.scrollNormX, 1.0);
743+
const double ny = qBound(0.0, state.scrollNormY, 1.0);
744+
h->setValue(h->minimum() + qRound(nx * hr));
745+
v->setValue(v->minimum() + qRound(ny * vr));
746+
}
747+
748+
void MainWindow::scheduleSavedMainAreaViewStateRestore(const QPointer<ImageViewBase>& view) {
749+
if (view.isNull()) {
750+
return;
751+
}
752+
const SavedMainAreaViewState state = m_savedMainAreaViewState;
753+
QTimer::singleShot(0, this, [view, state]() {
754+
if (view.isNull()) {
755+
return;
756+
}
757+
MainWindow::applySavedMainAreaViewState(view.data(), state);
758+
});
759+
}
760+
713761
void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, DebugImages* debugImages, bool overlay) {
714762
if (isBatchProcessingInProgress() && (widget != m_batchProcessingWidget.get())) {
715763
if (ownership == TRANSFER_OWNERSHIP) {
@@ -720,8 +768,19 @@ void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, Debu
720768

721769
if (!overlay && m_imageFrameLayout->count() > 0) {
722770
QWidget* oldW = m_imageFrameLayout->widget(0);
723-
if (ImageViewBase* oldView = Utils::castOrFindChild<ImageViewBase*>(oldW)) {
724-
m_savedZoomLevel = oldView->zoomLevel();
771+
if (ImageViewBase* oldView = findPrimaryImageView(oldW)) {
772+
m_savedMainAreaViewState.zoom = oldView->zoomLevel();
773+
QScrollBar* const h = oldView->horizontalScrollBar();
774+
QScrollBar* const v = oldView->verticalScrollBar();
775+
const int hr = h->maximum() - h->minimum();
776+
const int vr = v->maximum() - v->minimum();
777+
if (hr > 0 && vr > 0) {
778+
m_savedMainAreaViewState.hasScrollNorm = true;
779+
m_savedMainAreaViewState.scrollNormX = double(h->value() - h->minimum()) / hr;
780+
m_savedMainAreaViewState.scrollNormY = double(v->value() - v->minimum()) / vr;
781+
} else {
782+
m_savedMainAreaViewState.hasScrollNorm = false;
783+
}
725784
}
726785
}
727786

@@ -739,8 +798,8 @@ void MainWindow::setImageWidget(QWidget* widget, const Ownership ownership, Debu
739798
if (overlay) {
740799
m_imageFrameLayout->setCurrentWidget(widget);
741800
}
742-
if (ImageViewBase* newView = Utils::castOrFindChild<ImageViewBase*>(widget)) {
743-
newView->setZoomLevel(m_savedZoomLevel);
801+
if (ImageViewBase* newView = findPrimaryImageView(widget)) {
802+
scheduleSavedMainAreaViewStateRestore(QPointer<ImageViewBase>(newView));
744803
}
745804
}
746805
} else {

src/app/MainWindow.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,19 @@ class MainWindow : public QMainWindow, private FilterUiInterface, private Ui::Ma
195195

196196
static void removeWidgetsFromLayout(QLayout* layout);
197197

198+
struct SavedMainAreaViewState {
199+
double zoom = 1.0;
200+
bool hasScrollNorm = false;
201+
double scrollNormX = 0.5;
202+
double scrollNormY = 0.5;
203+
};
204+
205+
static ImageViewBase* findPrimaryImageView(QWidget* root);
206+
207+
static void applySavedMainAreaViewState(ImageViewBase* view, const SavedMainAreaViewState& state);
208+
209+
void scheduleSavedMainAreaViewStateRestore(const QPointer<ImageViewBase>& view);
210+
198211
void setOptionsWidget(FilterOptionsWidget* widget, Ownership ownership) override;
199212

200213
void setImageWidget(QWidget* widget,
@@ -323,7 +336,7 @@ class MainWindow : public QMainWindow, private FilterUiInterface, private Ui::Ma
323336
QObjectCleanupHandler m_imageWidgetCleanup;
324337
std::unique_ptr<OutOfMemoryDialog> m_outOfMemoryDialog;
325338
int m_curFilter;
326-
double m_savedZoomLevel;
339+
SavedMainAreaViewState m_savedMainAreaViewState;
327340
int m_ignoreSelectionChanges;
328341
int m_ignorePageOrderingChanges;
329342
bool m_debug;

0 commit comments

Comments
 (0)