File indexing completed on 2025-03-09 04:01:10

0001 // SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 #ifndef GWENVIEW_ZOOMCOMBOBOX_H
0005 #define GWENVIEW_ZOOMCOMBOBOX_H
0006 
0007 #include <QComboBox>
0008 #include <lib/gwenviewlib_export.h>
0009 
0010 class QWheelEvent;
0011 
0012 namespace Gwenview
0013 {
0014 class ZoomComboBoxPrivate;
0015 
0016 /**
0017  * QComboBox subclass designed to be somewhat similar to QSpinBox.
0018  * Allows the user to use non-integer combobox list items,
0019  * but only accepts integers as custom input.
0020  *
0021  * This class is structured in a way so that changes to the zoom done through
0022  * user interaction are signalled to the outside. On the other hand changes
0023  * done to the visual state of this class without user interaction will not
0024  * lead to emitted zoom changes/signals from this class.
0025  */
0026 class GWENVIEWLIB_EXPORT ZoomComboBox : public QComboBox
0027 {
0028     Q_OBJECT
0029     Q_PROPERTY(qreal value READ value WRITE setValue)
0030     Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum)
0031     Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum)
0032 
0033 public:
0034     explicit ZoomComboBox(QWidget *parent = nullptr);
0035     ~ZoomComboBox() override;
0036 
0037     void setActions(QAction *zoomToFitAction, QAction *zoomToFillAction, QAction *actualSizeAction);
0038 
0039     qreal value() const;
0040     /**
0041      * Called when the value that is being displayed should change.
0042      * Calling this method doesn't affect the zoom of the currently viewed image.
0043      */
0044     void setValue(const qreal value);
0045 
0046     qreal minimum() const;
0047     void setMinimum(const qreal minimum);
0048 
0049     qreal maximum() const;
0050     void setMaximum(const qreal maximum);
0051 
0052     /// Gets an integer value from text.
0053     qreal valueFromText(const QString &text, bool *ok = nullptr) const;
0054 
0055     /// Gets appropriately decorated text from an integer value.
0056     QString textFromValue(const qreal value) const;
0057 
0058     void updateDisplayedText();
0059 
0060     void showPopup() override;
0061 
0062 Q_SIGNALS:
0063     void zoomChanged(qreal zoom);
0064 
0065 protected:
0066     bool eventFilter(QObject *watched, QEvent *event) override;
0067     void focusOutEvent(QFocusEvent *event) override;
0068     void keyPressEvent(QKeyEvent *event) override;
0069 
0070     /**
0071      * Makes sure using the mouse wheel on the combobox works as
0072      * expected even though we sometimes programmatically change
0073      * the currentIndex() of this ComboBox.
0074      * @see updateCurrentIndex()
0075      */
0076     void wheelEvent(QWheelEvent *event) override;
0077 
0078 private:
0079     /**
0080      * The current index is the row in the popup of the ComboBox that is
0081      * highlighted.
0082      * This method updates the current index so it matches the current zoom
0083      * state of the application.
0084      * If the zoom value that is currently used doesn't exist as a row in
0085      * the ComboBox, the currentIndex is set to -1 which hides the highlight.
0086      */
0087     void updateCurrentIndex();
0088 
0089     void moveCurrentIndex(bool moveUp);
0090 
0091 private Q_SLOTS:
0092     /**
0093      * This method changes the zoom mode or value of the currently displayed image in response to
0094      * user interaction with the Combobox' dropdown menu.
0095      * @param index of the zoom mode or value that the user interacted with.
0096      */
0097     void changeZoomTo(int index);
0098 
0099     /**
0100      * Sets the index as the fallback when the popup menu is closed without selection in the
0101      * future and then calls changeZoomTo().
0102      * @see changeZoomTo()
0103      */
0104     void activateAndChangeZoomTo(int index);
0105 
0106 private:
0107     const std::unique_ptr<ZoomComboBoxPrivate> d_ptr;
0108     Q_DECLARE_PRIVATE(ZoomComboBox)
0109     Q_DISABLE_COPY(ZoomComboBox)
0110 };
0111 
0112 }
0113 
0114 #endif // GWENVIEW_ZOOMCOMBOBOX_H