File indexing completed on 2024-05-12 04:44:30
0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT 0003 0004 #ifndef CHROMALIGHTNESSDIAGRAM_H 0005 #define CHROMALIGHTNESSDIAGRAM_H 0006 0007 #include "abstractdiagram.h" 0008 #include "constpropagatinguniquepointer.h" 0009 #include "lchdouble.h" 0010 #include <qglobal.h> 0011 #include <qsharedpointer.h> 0012 #include <qsize.h> 0013 0014 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 0015 #include <qtmetamacros.h> 0016 #else 0017 #include <qobjectdefs.h> 0018 #include <qstring.h> 0019 class QObject; 0020 #endif 0021 0022 class QKeyEvent; 0023 class QMouseEvent; 0024 class QPaintEvent; 0025 class QResizeEvent; 0026 class QWidget; 0027 0028 namespace PerceptualColor 0029 { 0030 class ChromaLightnessDiagramPrivate; 0031 0032 class RgbColorSpace; 0033 0034 /** @internal 0035 * 0036 * @brief A widget that displays a chroma-lightness diagram. 0037 * 0038 * This widget displays a chroma-lightness diagram for a given hue. 0039 * 0040 * @image html ChromaLightnessDiagram.png "ChromaLightnessDiagram" width=250 0041 * 0042 * The widget shows the chroma-lightness diagram at the whole widget extend. 0043 * - Vertically the lightness from 0 (bottom) to 100 (top). 0044 * - Horizontally the chroma from 0 (left) to a higher value (right). The same 0045 * scale is used like for the vertical axis: So if the widget size is a 0046 * square, both chroma and lightness range from 0 to 100. If the widget 0047 * width is twice the height, the lightness ranges from 0 to 100 0048 * and the chroma ranges from 0 to 200. 0049 * 0050 * @internal 0051 * 0052 * @note This class is not part of the public API because its interface 0053 * is not polished enough. Notably it does not automatically scale the 0054 * diagram to fit a given gamut (means: to fit up to a given maximum 0055 * chroma). Even if we would fix this: We would need a public API 0056 * that is widthForHeight-dependent to allow the library user to 0057 * comfortably make use of this! 0058 * 0059 * @todo What to do if a gamut allows lightness < 0 or lightness > 100 ??? 0060 * What if a part of the gamut at the right is not displayed? (Thought 0061 * this means that @ref RgbColorSpace has a bug.) Shouldn’t this be 0062 * controlled?) Maybe it would be better to control this 0063 * within @ref RgbColorSpace … */ 0064 class ChromaLightnessDiagram : public AbstractDiagram 0065 { 0066 Q_OBJECT 0067 0068 /** @brief Currently selected color 0069 * 0070 * The widget allows the user to change the LCH chroma and the 0071 * LCH lightness values. However, the LCH hue value cannot be 0072 * changed by the user, but only by the programmer through this property. 0073 * 0074 * @sa READ @ref currentColor() const 0075 * @sa WRITE @ref setCurrentColor() 0076 * @sa NOTIFY @ref currentColorChanged() */ 0077 Q_PROPERTY(PerceptualColor::LchDouble currentColor READ currentColor WRITE setCurrentColor NOTIFY currentColorChanged) 0078 0079 public: 0080 Q_INVOKABLE explicit ChromaLightnessDiagram(const QSharedPointer<PerceptualColor::RgbColorSpace> &colorSpace, QWidget *parent = nullptr); 0081 virtual ~ChromaLightnessDiagram() noexcept override; 0082 /** @brief Getter for property @ref currentColor 0083 * @returns the property @ref currentColor */ 0084 [[nodiscard]] PerceptualColor::LchDouble currentColor() const; 0085 [[nodiscard]] virtual QSize minimumSizeHint() const override; 0086 [[nodiscard]] virtual QSize sizeHint() const override; 0087 0088 public Q_SLOTS: 0089 void setCurrentColor(const PerceptualColor::LchDouble &newCurrentColor); 0090 0091 Q_SIGNALS: 0092 /** @brief Notify signal for property @ref currentColor. 0093 * @param newCurrentColor the new current color */ 0094 void currentColorChanged(const PerceptualColor::LchDouble &newCurrentColor); 0095 0096 protected: 0097 virtual void keyPressEvent(QKeyEvent *event) override; 0098 virtual void mouseMoveEvent(QMouseEvent *event) override; 0099 virtual void mousePressEvent(QMouseEvent *event) override; 0100 virtual void mouseReleaseEvent(QMouseEvent *event) override; 0101 virtual void paintEvent(QPaintEvent *event) override; 0102 virtual void resizeEvent(QResizeEvent *event) override; 0103 0104 private: 0105 Q_DISABLE_COPY(ChromaLightnessDiagram) 0106 0107 /** @internal 0108 * 0109 * @brief Declare the private implementation as friend class. 0110 * 0111 * This allows the private class to access the protected members and 0112 * functions of instances of <em>this</em> class. */ 0113 friend class ChromaLightnessDiagramPrivate; 0114 /** @brief Pointer to implementation (pimpl) */ 0115 ConstPropagatingUniquePointer<ChromaLightnessDiagramPrivate> d_pointer; 0116 0117 /** @internal @brief Only for unit tests. */ 0118 friend class TestChromaLightnessDiagram; 0119 0120 /** @internal 0121 * @brief Internal friend declaration. 0122 * 0123 * This class is used as child class in @ref WheelColorPicker. 0124 * There is a tight collaboration. */ 0125 friend class WheelColorPicker; 0126 /** @internal 0127 * @brief Internal friend declaration. 0128 * 0129 * This class is used as child class in @ref WheelColorPicker. 0130 * There is a tight collaboration. */ 0131 friend class WheelColorPickerPrivate; 0132 }; 0133 0134 } // namespace PerceptualColor 0135 0136 #endif // CHROMALIGHTNESSDIAGRAM_H