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

source code of kirigami/src/colorutils.h