Skip to content

Commit d62ccb1

Browse files
committed
ImageViewer: Added mouse pan mode
1 parent f97d101 commit d62ccb1

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/ImageViewer.cpp

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
#include "ImageViewer.h"
22
#include "ui_ImageViewer.h"
33

4+
#include <cmath>
45
#include <QPrinter>
56
#include <QPrintPreviewDialog>
67
#include <QPainter>
78
#include <QScrollBar>
9+
#include <QResizeEvent>
10+
#include <QMouseEvent>
811

912
ImageViewer::ImageViewer(QWidget* parent) :
1013
QWidget(parent),
1114
ui(new Ui::ImageViewer),
12-
m_image_size(0, 0)
15+
m_image_size(0, 0),
16+
m_pan_mode{false}
1317
{
1418
ui->setupUi(this);
19+
ui->scrollArea->installEventFilter(this);
1520
connect(ui->buttonOriginalSize, &QToolButton::clicked, this, [this]{ scaleImage(100); });
1621

1722
ui->labelView->addAction(ui->actionPrintImage);
@@ -37,12 +42,50 @@ void ImageViewer::setImage(const QImage& image)
3742

3843
// If the image is larger than the viewport scale it to fit the viewport.
3944
// If the image is smaller than the viewport show it in its original size.
40-
if(image.size().width() > widget_size.width() || image.size().height() > widget_size.height())
45+
if(!isQSizeCovered(m_image_size))
4146
ui->buttonFitToWindow->setChecked(true);
4247
else
4348
scaleImage(100);
4449
}
4550

51+
bool ImageViewer::isQSizeCovered(QSize rect)
52+
{
53+
auto widget_size = ui->scrollArea->size();
54+
return widget_size.width() >= rect.width() && widget_size.height() >= rect.height();
55+
}
56+
57+
bool ImageViewer::eventFilter(QObject *obj, QEvent *e) {
58+
auto e_type = e->type();
59+
if (ui->buttonFitToWindow->isChecked()) {
60+
if (e_type == QEvent::Resize)
61+
scaleToFitWindow(true);
62+
} else if (e_type >= QEvent::MouseButtonPress && e_type <= QEvent::MouseMove) {
63+
auto *mouse_event = static_cast<QMouseEvent*>(e);
64+
if (e_type == QEvent::MouseButtonPress && mouse_event->button() == Qt::LeftButton &&
65+
!isQSizeCovered(ui->labelView->size())) {
66+
m_mouse_down = mouse_event->globalPos();
67+
m_pan_mode = true;
68+
ui->scrollArea->setCursor(Qt::ClosedHandCursor);
69+
} else if (e_type == QEvent::MouseMove && m_pan_mode) {
70+
auto dx = mouse_event->globalX() - m_mouse_down.x();
71+
auto dy = mouse_event->globalY() - m_mouse_down.y();
72+
if (dx != 0) {
73+
ui->scrollArea->horizontalScrollBar()->setValue(ui->scrollArea->horizontalScrollBar()->value() - dx);
74+
m_mouse_down.setX(mouse_event->globalX());
75+
}
76+
77+
if (dy != 0) {
78+
ui->scrollArea->verticalScrollBar()->setValue(ui->scrollArea->verticalScrollBar()->value() - dy);
79+
m_mouse_down.setY(mouse_event->globalY());
80+
}
81+
} else if (e_type == QEvent::MouseButtonRelease && mouse_event->button() == Qt::LeftButton) {
82+
m_pan_mode = false;
83+
ui->scrollArea->setCursor(Qt::ArrowCursor);
84+
}
85+
}
86+
return false;
87+
}
88+
4689
void ImageViewer::openPrintImageDialog()
4790
{
4891
QPrinter printer;
@@ -73,10 +116,11 @@ void ImageViewer::scaleToFitWindow(bool enabled)
73116
ui->scrollArea->setWidgetResizable(enabled);
74117

75118
// When disabling the fit to window scaling, revert back to the original image size
76-
if(!enabled)
119+
if(!enabled) {
77120
scaleImage(100);
78-
else
121+
} else {
79122
ui->labelView->setMaximumSize(m_image_size.scaled(ui->scrollArea->size(), Qt::KeepAspectRatio));
123+
}
80124
}
81125

82126
void ImageViewer::scaleImage(int scale)
@@ -91,7 +135,7 @@ void ImageViewer::scaleImage(int scale)
91135
auto max_size_old = ui->labelView->maximumSize();
92136
ui->labelView->setMaximumSize(m_image_size * scale_factor);
93137
ui->labelView->resize(ui->labelView->maximumSize());
94-
auto factor_change = ui->labelView->maximumSize().width() / double(max_size_old.width());
138+
auto factor_change = ui->labelView->maximumSize().width() / static_cast<double>(max_size_old.width());
95139

96140
// Uncheck the fit to window button
97141
ui->buttonFitToWindow->setChecked(false);

src/ImageViewer.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ private slots:
2727

2828
private:
2929
Ui::ImageViewer* ui;
30-
3130
QSize m_image_size;
31+
bool m_pan_mode;
32+
QPoint m_mouse_down;
33+
34+
bool eventFilter(QObject *obj, QEvent *e) override;
35+
bool isQSizeCovered(QSize rect);
3236
};
3337

3438
#endif

0 commit comments

Comments
 (0)