1 | /* |
2 | * SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com> |
3 | * |
4 | * SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #pragma once |
8 | |
9 | #include <QColor> |
10 | #include <QJSValue> |
11 | #include <QObject> |
12 | #include <QQuickItem> |
13 | |
14 | #include "kirigamiplatform_export.h" |
15 | |
16 | /*! |
17 | * \qmltype ColorUtils |
18 | * \inqmlmodule org.kde.kirigami.platform |
19 | * |
20 | * \brief Utilities for processing items to obtain colors and information useful for |
21 | * UIs that need to adjust to variable elements. |
22 | */ |
23 | class KIRIGAMIPLATFORM_EXPORT ColorUtils : public QObject |
24 | { |
25 | Q_OBJECT |
26 | QML_ELEMENT |
27 | QML_SINGLETON |
28 | public: |
29 | /*! |
30 | * \enum ColorUtils::Brightness |
31 | * |
32 | * Describes the contrast of an item. |
33 | * |
34 | * \value Dark The item is dark and requires a light foreground color to achieve readable contrast |
35 | * \value Light The item is light and requires a dark foreground color to achieve readable contrast |
36 | * |
37 | */ |
38 | enum Brightness { |
39 | Dark, |
40 | Light, |
41 | }; |
42 | Q_ENUM(Brightness) |
43 | |
44 | explicit ColorUtils(QObject *parent = nullptr); |
45 | |
46 | /*! |
47 | * \qmlmethod enumeration ColorUtils::brightnessForColor(color color) |
48 | * |
49 | * Returns whether a color is bright or dark. |
50 | * |
51 | * \qml |
52 | * import QtQuick |
53 | * import org.kde.kirigami as Kirigami |
54 | * |
55 | * Kirigami.Heading { |
56 | * text: { |
57 | * if (Kirigami.ColorUtils.brightnessForColor("pink") == Kirigami.ColorUtils.Light) { |
58 | * return "The color is light" |
59 | * } else { |
60 | * return "The color is dark" |
61 | * } |
62 | * } |
63 | * } |
64 | * \endqml |
65 | * |
66 | * \since 5.69 |
67 | */ |
68 | Q_INVOKABLE ColorUtils::Brightness brightnessForColor(const QColor &color); |
69 | |
70 | /*! |
71 | * \qmlmethod real ColorUtils::grayForColor(color color) |
72 | * |
73 | * Same Algorithm as brightnessForColor but returns a 0 to 1 value for an |
74 | * estimate of the equivalent gray light value (luma). |
75 | * 0 as full black, 1 as full white and 0.5 equivalent to a 50% gray. |
76 | * |
77 | * \since 5.81 |
78 | */ |
79 | Q_INVOKABLE qreal grayForColor(const QColor &color); |
80 | |
81 | /*! |
82 | * \qmlmethod color ColorUtils::alphaBlend(color foreground, color background) |
83 | * |
84 | * Returns the result of overlaying the foreground color on the background |
85 | * color. |
86 | * |
87 | * \a foreground The color to overlay on the background. |
88 | * |
89 | * \a background The color to overlay the foreground on. |
90 | * |
91 | * \qml |
92 | * import QtQuick |
93 | * import org.kde.kirigami as Kirigami |
94 | * |
95 | * Rectangle { |
96 | * color: Kirigami.ColorUtils.alphaBlend(Qt.rgba(0, 0, 0, 0.5), Qt.rgba(1, 1, 1, 1)) |
97 | * } |
98 | * \endqml |
99 | * |
100 | * \since 5.69 |
101 | */ |
102 | Q_INVOKABLE QColor alphaBlend(const QColor &foreground, const QColor &background); |
103 | |
104 | /*! |
105 | * \qmlmethod color ColorUtils::linearInterpolation(color one, color two, real balance) |
106 | * |
107 | * Returns a linearly interpolated color between color one and color two. |
108 | * |
109 | * \a one The color to linearly interpolate from. |
110 | * |
111 | * \a two The color to linearly interpolate to. |
112 | * |
113 | * \a balance The balance between the two colors. 0.0 will return the |
114 | * first color, 1.0 will return the second color. Values beyond these bounds |
115 | * are valid, and will result in extrapolation. |
116 | * |
117 | * \qml |
118 | * import QtQuick |
119 | * import org.kde.kirigami as Kirigami |
120 | * |
121 | * Rectangle { |
122 | * color: Kirigami.ColorUtils.linearInterpolation("black", "white", 0.5) |
123 | * } |
124 | * \endqml |
125 | * |
126 | * \since 5.69 |
127 | */ |
128 | Q_INVOKABLE QColor linearInterpolation(const QColor &one, const QColor &two, double balance); |
129 | |
130 | /*! |
131 | * \qmlmethod color ColorUtils::adjustColor |
132 | * |
133 | * Increases or decreases the properties of color by fixed amounts. |
134 | * |
135 | * \a color The color to adjust. |
136 | * |
137 | * \a adjustments The adjustments to apply to the color. |
138 | * |
139 | * \qml |
140 | * { |
141 | * red: null, // Range: -255 to 255 |
142 | * green: null, // Range: -255 to 255 |
143 | * blue: null, // Range: -255 to 255 |
144 | * hue: null, // Range: -360 to 360 |
145 | * saturation: null, // Range: -255 to 255 |
146 | * value: null // Range: -255 to 255 |
147 | * alpha: null, // Range: -255 to 255 |
148 | * } |
149 | * \endqml |
150 | * |
151 | * \warning It is an error to adjust both RGB and HSV properties. |
152 | * |
153 | * \since 5.69 |
154 | */ |
155 | Q_INVOKABLE QColor adjustColor(const QColor &color, const QJSValue &adjustments); |
156 | |
157 | /*! |
158 | * \qmlmethod color ColorUtils::scaleColor |
159 | * |
160 | * Smoothly scales colors. |
161 | * |
162 | * \a color The color to adjust. |
163 | * |
164 | * \a adjustments The adjustments to apply to the color. Each value must |
165 | * be between `-100.0` and `100.0`. This indicates how far the property should |
166 | * be scaled from its original to the maximum if positive or to the minimum if |
167 | * negative. |
168 | * |
169 | * \qml |
170 | * { |
171 | * red: null |
172 | * green: null |
173 | * blue: null |
174 | * saturation: null |
175 | * value: null |
176 | * alpha: null |
177 | * } |
178 | * \endqml |
179 | * |
180 | * \warning It is an error to scale both RGB and HSV properties. |
181 | * |
182 | * \since 5.69 |
183 | */ |
184 | Q_INVOKABLE QColor scaleColor(const QColor &color, const QJSValue &adjustments); |
185 | |
186 | /*! |
187 | * \qmlmethod color ColorUtils::tintWithAlpha |
188 | * |
189 | * Tint a color using a separate alpha value. |
190 | * |
191 | * This does the same as Qt.tint() except that rather than using the tint |
192 | * color's alpha value, it uses a separate value that gets multiplied with |
193 | * the tint color's alpha. This avoids needing to create a new color just to |
194 | * adjust an alpha value. |
195 | * |
196 | * \a targetColor The color to tint. |
197 | * |
198 | * \a tintColor The color to tint with. |
199 | * |
200 | * \a alpha The amount of tinting to apply. |
201 | * |
202 | * \sa Qt.tint() |
203 | */ |
204 | Q_INVOKABLE QColor tintWithAlpha(const QColor &targetColor, const QColor &tintColor, double alpha); |
205 | |
206 | /*! |
207 | * \qmlmethod real ColorUtils::chroma |
208 | * |
209 | * Returns the CIELAB chroma of the given color. |
210 | * |
211 | * CIELAB chroma may give a better quantification of how vibrant a color is compared to HSV saturation. |
212 | * |
213 | * \sa {https://en.wikipedia.org/wiki/Colorfulness} {Colorfulness (Wikipedia)} |
214 | * \sa {https://en.wikipedia.org/wiki/CIELAB_color_space} {CIELAB Color Space (Wikipedia)} |
215 | */ |
216 | Q_INVOKABLE static qreal chroma(const QColor &color); |
217 | |
218 | struct XYZColor { |
219 | qreal x = 0; |
220 | qreal y = 0; |
221 | qreal z = 0; |
222 | }; |
223 | |
224 | struct LabColor { |
225 | qreal l = 0; |
226 | qreal a = 0; |
227 | qreal b = 0; |
228 | }; |
229 | |
230 | // Not for QML, returns the comvertion from srgb of a QColor and XYZ colorspace |
231 | static ColorUtils::XYZColor colorToXYZ(const QColor &color); |
232 | |
233 | // Not for QML, returns the comvertion from srgb of a QColor and Lab colorspace |
234 | static ColorUtils::LabColor colorToLab(const QColor &color); |
235 | |
236 | static qreal luminance(const QColor &color); |
237 | }; |
238 | |