Add zooming to image viewer in the Edit Dialog

This adds some basic zooming functionality to the image viewer used in
the Edit Dialog.

See issue #2029.
This commit is contained in:
Martin Kleusberg
2020-06-03 15:03:15 +02:00
parent d0978ef462
commit d3c69ad291
5 changed files with 149 additions and 4 deletions

View File

@@ -4,12 +4,14 @@
#include <QPrinter>
#include <QPrintPreviewDialog>
#include <QPainter>
#include <QScrollBar>
ImageViewer::ImageViewer(QWidget* parent) :
QWidget(parent),
ui(new Ui::ImageViewer)
{
ui->setupUi(this);
connect(ui->buttonOriginalSize, &QToolButton::clicked, [this]{ scaleImage(100); });
ui->labelView->addAction(ui->actionPrintImage);
}
@@ -27,6 +29,9 @@ void ImageViewer::resetImage()
void ImageViewer::setImage(const QImage& image)
{
ui->labelView->setPixmap(QPixmap::fromImage(image));
// Reset the scaling to show the image in its original size
scaleImage(100);
}
void ImageViewer::openPrintImageDialog()
@@ -46,3 +51,36 @@ void ImageViewer::openPrintImageDialog()
dialog.exec();
}
void ImageViewer::scaleToFitWindow(bool enabled)
{
// Enable/disable the automatic resizing of the label inside the scrollbar
ui->scrollArea->setWidgetResizable(enabled);
// When disabling the fit to window scaling, revert back to the original image size
if(!enabled)
scaleImage(100);
}
void ImageViewer::scaleImage(int scale)
{
// Make sure the slider is updated when this is called programatically
ui->sliderScale->setValue(scale);
// Update our scale factor
qreal factor_change = (scale / 100.0) / m_scale_factor;
m_scale_factor = scale / 100.0;
// Resize the image
ui->labelView->resize(m_scale_factor * ui->labelView->pixmap()->size());
// Uncheck the fit to window button
ui->buttonFitToWindow->setChecked(false);
// Fix scroll bars to zoom into center of viewport instead of tthe upper left corner
const auto adjust_scrollbar = [](QScrollBar* scroll_bar, qreal factor) {
scroll_bar->setValue(static_cast<int>(factor * scroll_bar->value() + ((factor - 1) * scroll_bar->pageStep() / 2)));
};
adjust_scrollbar(ui->scrollArea->horizontalScrollBar(), factor_change);
adjust_scrollbar(ui->scrollArea->verticalScrollBar(), factor_change);
}

View File

@@ -21,8 +21,14 @@ public:
public slots:
void openPrintImageDialog();
private slots:
void scaleToFitWindow(bool enabled);
void scaleImage(int scale);
private:
Ui::ImageViewer* ui;
qreal m_scale_factor;
};
#endif

View File

@@ -31,24 +31,88 @@
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QLabel" name="labelView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>431</width>
<height>305</height>
<height>280</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="sliderScale">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>800</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonOriginalSize">
<property name="toolTip">
<string>Reset the scaling to match the original size of the image.</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/view</normaloff>:/icons/view</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="buttonFitToWindow">
<property name="toolTip">
<string>Set the scaling to match the size of the viewport.</string>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/monitor_link.png</normaloff>:/icons/monitor_link.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<action name="actionPrintImage">
<property name="icon">
@@ -86,5 +150,41 @@
</hint>
</hints>
</connection>
<connection>
<sender>sliderScale</sender>
<signal>valueChanged(int)</signal>
<receiver>ImageViewer</receiver>
<slot>scaleImage(int)</slot>
<hints>
<hint type="sourcelabel">
<x>280</x>
<y>294</y>
</hint>
<hint type="destinationlabel">
<x>216</x>
<y>153</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonFitToWindow</sender>
<signal>toggled(bool)</signal>
<receiver>ImageViewer</receiver>
<slot>scaleToFitWindow(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>419</x>
<y>294</y>
</hint>
<hint type="destinationlabel">
<x>216</x>
<y>153</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>scaleImage(int)</slot>
<slot>scaleToFitWindow(bool)</slot>
</slots>
</ui>

View File

@@ -101,5 +101,6 @@
<file alias="open_in_app">application_link.png</file>
<file alias="document_link">document-link.png</file>
<file alias="open_data_in_app">application_go.png</file>
<file>monitor_link.png</file>
</qresource>
</RCC>

BIN
src/icons/monitor_link.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B