diff --git a/src/widgets/dialogs/autotests/showimagewidgettest.cpp b/src/widgets/dialogs/autotests/showimagewidgettest.cpp index 4c207f95..65f91414 100644 --- a/src/widgets/dialogs/autotests/showimagewidgettest.cpp +++ b/src/widgets/dialogs/autotests/showimagewidgettest.cpp @@ -1,64 +1,88 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "showimagewidgettest.h" #include "dialogs/showimagewidget.h" + #include #include #include #include #include +#include + QTEST_MAIN(ShowImageWidgetTest) ShowImageWidgetTest::ShowImageWidgetTest(QObject *parent) : QObject(parent) { } void ShowImageWidgetTest::shouldHaveDefaultValues() { ShowImageWidget w; + const auto pixmap = QPixmap(QStringLiteral(":/icons/systray.png")); + auto pixmapSize = pixmap.size(); + w.setImage(pixmap); auto *mainLayout = w.findChild(QStringLiteral("mainLayout")); QVERIFY(mainLayout); QCOMPARE(mainLayout->contentsMargins(), QMargins(0, 0, 0, 0)); auto *scrollArea = w.findChild(QStringLiteral("scrollArea")); QVERIFY(scrollArea); QVERIFY(scrollArea->widgetResizable()); auto *mLabel = w.findChild(QStringLiteral("mLabel")); QVERIFY(mLabel); QVERIFY(mLabel->text().isEmpty()); QCOMPARE(mLabel->backgroundRole(), QPalette::Base); + QVERIFY(mLabel->pixmap()); + QEXPECT_FAIL("", "the pixmap is currently sized according to the label size, not vice versa", Continue); + QCOMPARE(mLabel->pixmap()->size(), pixmapSize); auto *zoomLayout = w.findChild(QStringLiteral("zoomLayout")); QVERIFY(zoomLayout); auto *zoomLabel = w.findChild(QStringLiteral("zoomLabel")); QVERIFY(zoomLabel); QVERIFY(!zoomLabel->text().isEmpty()); + auto *mZoomSpin = w.findChild(QStringLiteral("mZoomSpin")); + QVERIFY(mZoomSpin); + QCOMPARE(mZoomSpin->value(), 1.0); + auto *mSlider = w.findChild(QStringLiteral("mSlider")); QVERIFY(mSlider); QCOMPARE(mSlider->orientation(), Qt::Horizontal); + QCOMPARE(mSlider->value(), 100); + + mSlider->setValue(200); + QCOMPARE(mSlider->value(), 200); + QCOMPARE(mZoomSpin->value(), 2); + QCOMPARE(mLabel->pixmap()->size(), 2 * pixmapSize); + + mZoomSpin->setValue(3); + QCOMPARE(mZoomSpin->value(), 3); + QCOMPARE(mSlider->value(), 300); + QCOMPARE(mLabel->pixmap()->size(), 3 * pixmapSize); QVERIFY(!w.isAnimatedPixmap()); } diff --git a/src/widgets/dialogs/showimagewidget.cpp b/src/widgets/dialogs/showimagewidget.cpp index c489023a..6cf5a0d0 100644 --- a/src/widgets/dialogs/showimagewidget.cpp +++ b/src/widgets/dialogs/showimagewidget.cpp @@ -1,146 +1,164 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "showimagewidget.h" #include #include #include #include #include #include #include +#include +#include ShowImageWidget::ShowImageWidget(QWidget *parent) : QWidget(parent) { auto *mainLayout = new QVBoxLayout(this); mainLayout->setObjectName(QStringLiteral("mainLayout")); mainLayout->setContentsMargins(0, 0, 0, 0); auto *scrollArea = new QScrollArea(this); scrollArea->setObjectName(QStringLiteral("scrollArea")); scrollArea->setWidgetResizable(true); mainLayout->addWidget(scrollArea); mLabel = new QLabel(this); mLabel->setObjectName(QStringLiteral("mLabel")); mLabel->setBackgroundRole(QPalette::Base); scrollArea->setWidget(mLabel); + mZoomControls = new QWidget(this); + mZoomControls->setObjectName(QStringLiteral("zoomControls")); auto *zoomLayout = new QHBoxLayout; zoomLayout->setObjectName(QStringLiteral("zoomLayout")); - mainLayout->addLayout(zoomLayout); + mZoomControls->setLayout(zoomLayout); + mainLayout->addWidget(mZoomControls); - mZoomLabel = new QLabel(i18n("Zoom:"), this); - mZoomLabel->setObjectName(QStringLiteral("zoomLabel")); - zoomLayout->addWidget(mZoomLabel); + auto *zoomLabel = new QLabel(i18n("Zoom:"), this); + zoomLabel->setObjectName(QStringLiteral("zoomLabel")); + zoomLayout->addWidget(zoomLabel); + + mZoomSpin = new QDoubleSpinBox(this); + mZoomSpin->setObjectName(QStringLiteral("mZoomSpin")); + mZoomSpin->setRange(0.1, 10); + mZoomSpin->setValue(1); + mZoomSpin->setDecimals(1); + zoomLayout->addWidget(mZoomSpin); mSlider = new QSlider(this); mSlider->setObjectName(QStringLiteral("mSlider")); mSlider->setOrientation(Qt::Horizontal); zoomLayout->addWidget(mSlider); - mSlider->setRange(10, 1000); - mSlider->setValue(100); - connect(mSlider, &QSlider::valueChanged, this, &ShowImageWidget::slotValueChanged); + mSlider->setRange(mZoomSpin->minimum() * 100, mZoomSpin->maximum() * 100); + mSlider->setValue(mZoomSpin->value() * 100); + + connect(mZoomSpin, &QDoubleSpinBox::valueChanged, this, &ShowImageWidget::setZoom); + connect(mSlider, &QSlider::valueChanged, this, [this](int value) { + setZoom(static_cast(value) / 100); + }); } ShowImageWidget::~ShowImageWidget() { } -void ShowImageWidget::slotValueChanged(int value) +void ShowImageWidget::setZoom(double scale) { - if (!mIsAnimatedPixmap) { - const QPixmap pm = mPixmap.scaled(mPixmap.width()*value/100, mPixmap.height()*value/100, Qt::KeepAspectRatio); + if (!mIsAnimatedPixmap && !mIsUpdatingZoom) { + QScopedValueRollback guard(mIsUpdatingZoom, true); + const QPixmap pm = mPixmap.scaled(mPixmap.width() * scale, mPixmap.height() * scale, Qt::KeepAspectRatio); mLabel->setPixmap(pm); + mSlider->setValue(static_cast(scale * 100)); + mZoomSpin->setValue(scale); } } bool ShowImageWidget::isAnimatedPixmap() const { return mIsAnimatedPixmap; } void ShowImageWidget::setIsAnimatedPixmap(bool value) { if (mIsAnimatedPixmap != value) { mIsAnimatedPixmap = value; if (mIsAnimatedPixmap) { - mSlider->hide(); - mZoomLabel->hide(); + mZoomControls->hide(); } } } void ShowImageWidget::setImagePath(const QString &imagePath) { QMovie *movie = new QMovie(this); movie->setFileName(imagePath); mLabel->setMovie(movie); movie->start(); } void ShowImageWidget::setImage(const QPixmap &pix) { mPixmap = pix; applyPixmap(); updateGeometry(); // sizeHint changed } QSize ShowImageWidget::sizeHint() const { if (mIsAnimatedPixmap) { return QWidget::sizeHint(); } return mPixmap.size().boundedTo(QSize(800, 800)); } void ShowImageWidget::showEvent(QShowEvent *event) { applyPixmap(); QWidget::showEvent(event); } void ShowImageWidget::resizeEvent(QResizeEvent *event) { applyPixmap(); QWidget::resizeEvent(event); } void ShowImageWidget::applyPixmap() { if (!mIsAnimatedPixmap) { mLabel->setPixmap(mPixmap.scaled(mLabel->size(), Qt::KeepAspectRatio)); } } void ShowImageWidget::wheelEvent(QWheelEvent *e) { if (!mIsAnimatedPixmap) { if (e->modifiers() & Qt::ControlModifier) { if (e->angleDelta().y() > 0) { mSlider->setValue(mSlider->value() - 5); } else { mSlider->setValue(mSlider->value() + 5); } } } } diff --git a/src/widgets/dialogs/showimagewidget.h b/src/widgets/dialogs/showimagewidget.h index 5974ca55..e50732e2 100644 --- a/src/widgets/dialogs/showimagewidget.h +++ b/src/widgets/dialogs/showimagewidget.h @@ -1,61 +1,64 @@ /* Copyright (c) 2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SHOWIMAGEWIDGET_H #define SHOWIMAGEWIDGET_H #include #include "libruqolawidgets_private_export.h" class QLabel; class QSlider; +class QDoubleSpinBox; class LIBRUQOLAWIDGETS_TESTS_EXPORT ShowImageWidget : public QWidget { Q_OBJECT public: explicit ShowImageWidget(QWidget *parent = nullptr); ~ShowImageWidget() override; void setImage(const QPixmap &pix); QSize sizeHint() const override; Q_REQUIRED_RESULT bool isAnimatedPixmap() const; void setIsAnimatedPixmap(bool value); void setImagePath(const QString &imagePath); protected: void showEvent(QShowEvent *event) override; void resizeEvent(QResizeEvent *event) override; void wheelEvent(QWheelEvent *e) override; private: void applyPixmap(); - void slotValueChanged(int value); + void setZoom(double scale); QPixmap mPixmap; - QLabel *mZoomLabel = nullptr; + QWidget *mZoomControls = nullptr; QLabel *mLabel = nullptr; + QDoubleSpinBox *mZoomSpin = nullptr; QSlider *mSlider = nullptr; bool mIsAnimatedPixmap = false; + bool mIsUpdatingZoom = false; }; #endif // SHOWIMAGEWIDGET_H