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 */
23class KIRIGAMIPLATFORM_EXPORT ColorUtils : public QObject
24{
25 Q_OBJECT
26 QML_ELEMENT
27 QML_SINGLETON
28public:
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

source code of kirigami/src/platform/colorutils.h