File indexing completed on 2024-05-12 04:44:29

0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com>
0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT
0003 
0004 #ifndef ABSTRACTDIAGRAM_H
0005 #define ABSTRACTDIAGRAM_H
0006 
0007 #include "constpropagatinguniquepointer.h"
0008 #include "importexport.h"
0009 #include <qcolor.h>
0010 #include <qglobal.h>
0011 #include <qimage.h>
0012 #include <qsize.h>
0013 #include <qwidget.h>
0014 class QHideEvent;
0015 class QShowEvent;
0016 
0017 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0018 #include <qtmetamacros.h>
0019 #else
0020 #include <qobjectdefs.h>
0021 #include <qstring.h>
0022 class QObject;
0023 #endif
0024 
0025 namespace PerceptualColor
0026 {
0027 class AbstractDiagramPrivate;
0028 
0029 /** @brief Base class for LCH diagrams.
0030  *
0031  * Provides some elements that are common for all LCH diagrams in this
0032  * library.
0033  *
0034  * @internal
0035  *
0036  * @note Qt provides some possibilities to declare that a certain widget
0037  * has a fixed ration between width and height. You can reimplement
0038  * <tt>QWidget::hasHeightForWidth()</tt> (indicates that the widget’s preferred
0039  * height depends on its width) and <tt>QWidget::heightForWidth()</tt>
0040  * (returns the preferred height for this widget, given the width <tt>w</tt>).
0041  * However, Qt’s layout management makes only very limited use of this
0042  * information. It is ignored, when the surrounding window is resized by
0043  * grabbing the window border with the mouse. It is however considered when
0044  * the surrounding window is resized by grabbing a <tt>QSizeGrip</tt>
0045  * widget. This behavior is inconsistent and would be surprising for the
0046  * user. Furthermore, if the widget is yet touching the border of the
0047  * screen, then the policy cannot be honored anyway; but it causes
0048  * flickering. Another possibility is QSizePolicy::setHeightForWidth or
0049  * QSizePolicy::setWidthForHeight which seem both to be “only supported for
0050  * QGraphicsLayout’s subclasses”. Therefore, it’s better not to use at all
0051  * these features; that’s the only way to provide a consistent and good
0052  * user experience.
0053  *
0054  * @todo Circular diagrams should be right-aligned on RTL layouts.
0055  *
0056  * @todo Touchscreen support: Magnify the handle circle, when diagram is
0057  * used on a touch device?  */
0058 class PERCEPTUALCOLOR_IMPORTEXPORT AbstractDiagram : public QWidget
0059 {
0060     Q_OBJECT
0061 
0062 public:
0063     Q_INVOKABLE explicit AbstractDiagram(QWidget *parent = nullptr);
0064     /** @brief Default destructor */
0065     virtual ~AbstractDiagram() noexcept override;
0066 
0067 protected:
0068     virtual void actualVisibilityToggledEvent();
0069     void callUpdate();
0070     [[nodiscard]] QColor focusIndicatorColor() const;
0071     [[nodiscard]] int gradientMinimumLength() const;
0072     [[nodiscard]] int gradientThickness() const;
0073     virtual void hideEvent(QHideEvent *event) override;
0074     [[nodiscard]] bool isActuallyVisible() const;
0075     [[nodiscard]] int maximumPhysicalSquareSize() const;
0076     [[nodiscard]] qreal maximumWidgetSquareSize() const;
0077     [[nodiscard]] QSize physicalPixelSize() const;
0078     [[nodiscard]] QColor handleColorFromBackgroundLightness(qreal lightness) const;
0079     [[nodiscard]] int handleOutlineThickness() const;
0080     [[nodiscard]] qreal handleRadius() const;
0081     virtual void showEvent(QShowEvent *event) override;
0082     [[nodiscard]] int spaceForFocusIndicator() const;
0083     [[nodiscard]] QImage transparencyBackground() const;
0084 
0085 private:
0086     Q_DISABLE_COPY(AbstractDiagram)
0087 
0088     /** @internal
0089      *
0090      * @brief Declare the private implementation as friend class.
0091      *
0092      * This allows the private class to access the protected members and
0093      * functions of instances of <em>this</em> class. */
0094     friend class AbstractDiagramPrivate;
0095     /** @brief Pointer to implementation (pimpl) */
0096     ConstPropagatingUniquePointer<AbstractDiagramPrivate> d_pointer;
0097 
0098     /** @internal @brief Only for unit tests. */
0099     friend class TestAbstractDiagram;
0100 };
0101 
0102 } // namespace PerceptualColor
0103 
0104 #endif // ABSTRACTDIAGRAM_H