Skip to main content

cxx_qt_lib/gui/
qcolor.rs

1// SPDX-FileCopyrightText: 2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
2// SPDX-FileContributor: Andrew Hayzen <andrew.hayzen@kdab.com>
3// SPDX-FileContributor: Gerhard de Clercq <gerhard.declercq@kdab.com>
4//
5// SPDX-License-Identifier: MIT OR Apache-2.0
6use cxx::{type_id, ExternType};
7use std::fmt;
8use std::mem::MaybeUninit;
9
10use crate::{QString, QStringList};
11
12#[cxx::bridge]
13mod ffi {
14    /// How to format the output of [`QColor::name`].
15    #[repr(i32)]
16    #[namespace = "rust::cxxqtlib1"]
17    enum QColorNameFormat {
18        /// A "#" character followed by three two-digit hexadecimal numbers (i.e. #RRGGBB).
19        HexRgb,
20        /// A "#" character followed by four two-digit hexadecimal numbers (i.e. #AARRGGBB).
21        HexArgb,
22    }
23
24    /// The type of color specified, either RGB, extended RGB, HSV, CMYK or HSL.
25    #[repr(i32)]
26    #[namespace = "rust::cxxqtlib1"]
27    enum QColorSpec {
28        Invalid,
29        Rgb,
30        Hsv,
31        Cmyk,
32        Hsl,
33        ExtendedRgb,
34    }
35
36    unsafe extern "C++" {
37        include!("cxx-qt-lib/qcolor.h");
38        type QColor = super::QColor;
39        include!("cxx-qt-lib/qstring.h");
40        type QString = crate::QString;
41        include!("cxx-qt-lib/qstringlist.h");
42        type QStringList = crate::QStringList;
43
44        /// Returns the alpha color component of this color.
45        fn alpha(self: &QColor) -> i32;
46        /// Returns the black color component of this color.
47        fn black(self: &QColor) -> i32;
48        /// Returns the blue color component of this color.
49        fn blue(self: &QColor) -> i32;
50        /// Creates a copy of this color in the format specified by `color_spec`.
51        #[rust_name = "convert_to"]
52        fn convertTo(self: &QColor, color_spec: QColorSpec) -> QColor;
53        /// Returns the cyan color component of this color.
54        fn cyan(self: &QColor) -> i32;
55        /// Returns a darker (or lighter) color, but does not change this object.
56        ///
57        /// If the `factor` is greater than 100, this functions returns a darker color. Setting `factor` to 300 returns a color that has one-third the brightness. If the `factor` is less than 100, the return color is lighter, but we recommend using [`lighter`](Self::lighter) for this purpose. If the `factor` is 0 or negative, the return value is unspecified.
58        ///
59        /// The function converts the current color to HSV, divides the value (V) component by factor and converts the color back to it's original color spec.
60        fn darker(self: &QColor, factor: i32) -> QColor;
61        /// Returns the green color component of this color.
62        fn green(self: &QColor) -> i32;
63        /// Returns the HSL hue color component of this color.
64        #[rust_name = "hsl_hue"]
65        fn hslHue(self: &QColor) -> i32;
66        /// Returns the HSL saturation color component of this color.
67        #[rust_name = "hsl_saturation"]
68        fn hslSaturation(self: &QColor) -> i32;
69        /// Returns the HSV hue color component of this color.
70        #[rust_name = "hsv_hue"]
71        fn hsvHue(self: &QColor) -> i32;
72        /// Returns the HSV saturation color component of this color.
73        #[rust_name = "hsv_saturation"]
74        fn hsvSaturation(self: &QColor) -> i32;
75        /// Returns the HSV hue color component of this color.
76        ///
77        /// The color is implicitly converted to HSV.
78        fn hue(self: &QColor) -> i32;
79        /// Returns `true` if the color is valid; otherwise returns `false`.
80        #[rust_name = "is_valid"]
81        fn isValid(self: &QColor) -> bool;
82        /// Returns a lighter (or darker) color, but does not change this object.
83        ///
84        /// If the `factor` is greater than 100, this functions returns a lighter color. Setting `factor` to 150 returns a color that is 50% brighter. If the `factor` is less than 100, the return color is darker, but we recommend using [`darker`](Self::darker) for this purpose. If the `factor` is 0 or negative, the return value is unspecified.
85        ///
86        /// The function converts the current color to HSV, multiplies the value (V) component by factor and converts the color back to it's original color spec.
87        fn lighter(self: &QColor, factor: i32) -> QColor;
88        /// Returns the lightness color component of this color.
89        fn lightness(self: &QColor) -> i32;
90        /// Returns the magenta color component of this color.
91        fn magenta(self: &QColor) -> i32;
92        /// Returns the name of the color in the specified `format`.
93        fn name(self: &QColor, format: QColorNameFormat) -> QString;
94        /// Returns the red color component of this color.
95        fn red(self: &QColor) -> i32;
96        /// Returns the HSV saturation color component of this color.
97        ///
98        /// The color is implicitly converted to HSV.
99        fn saturation(self: &QColor) -> i32;
100        /// Sets the alpha of this color to `alpha`. Integer alpha is specified in the range 0-255.
101        #[rust_name = "set_alpha"]
102        fn setAlpha(self: &mut QColor, alpha: i32);
103        /// Sets the blue color component of this color to 1. Integer components are specified in the range 0-255.
104        #[rust_name = "set_blue"]
105        fn setBlue(self: &mut QColor, blue: i32);
106        /// Sets the color to CMYK values, `c` (cyan), `m` (magenta), `y` (yellow), `k` (black), and `a` (alpha-channel, i.e. transparency).
107        ///
108        /// All the values must be in the range 0-255.
109        #[rust_name = "set_cmyk"]
110        fn setCmyk(self: &mut QColor, c: i32, m: i32, y: i32, k: i32, a: i32);
111        /// Sets the green color component of this color to `green`. Integer components are specified in the range 0-255.
112        #[rust_name = "set_green"]
113        fn setGreen(self: &mut QColor, green: i32);
114        /// Sets a HSL color value; `h` is the hue, `s` is the saturation, `l` is the lightness and `a` is the alpha component of the HSL color.
115        ///
116        /// The saturation, value and alpha-channel values must be in the range 0-255, and the hue value must be greater than -1.
117        #[rust_name = "set_hsl"]
118        fn setHsl(self: &mut QColor, h: i32, s: i32, l: i32, a: i32);
119        /// Sets a HSV color value; `h` is the hue, `s` is the saturation, `v` is the value and `a` is the alpha component of the HSV color.
120        ///
121        /// The saturation, value and alpha-channel values must be in the range 0-255, and the hue value must be greater than -1.
122        #[rust_name = "set_hsv"]
123        fn setHsv(self: &mut QColor, h: i32, s: i32, v: i32, a: i32);
124        /// Sets the red color component of this color to `red`. Integer components are specified in the range 0-255.
125        #[rust_name = "set_red"]
126        fn setRed(self: &mut QColor, red: i32);
127        /// Sets the RGB value to `r`, `g`, `b` and the alpha value to `a`.
128        ///
129        /// All the values must be in the range 0-255.
130        #[rust_name = "set_rgb"]
131        fn setRgb(self: &mut QColor, r: i32, g: i32, b: i32, a: i32);
132        /// Returns how the color was specified.
133        fn spec(self: &QColor) -> QColorSpec;
134        /// Creates and returns a CMYK `QColor` based on this color.
135        #[rust_name = "to_cmyk"]
136        fn toCmyk(self: &QColor) -> QColor;
137        /// Create and returns an extended RGB `QColor` based on this color.
138        #[rust_name = "to_extended_rgb"]
139        fn toExtendedRgb(self: &QColor) -> QColor;
140        /// Creates and returns an HSL `QColor` based on this color.
141        #[rust_name = "to_hsl"]
142        fn toHsl(self: &QColor) -> QColor;
143        /// Creates and returns an HSV `QColor` based on this color.
144        #[rust_name = "to_hsv"]
145        fn toHsv(self: &QColor) -> QColor;
146        /// Create and returns an RGB `QColor` based on this color.
147        #[rust_name = "to_rgb"]
148        fn toRgb(self: &QColor) -> QColor;
149        /// Returns the value color component of this color.
150        fn value(self: &QColor) -> i32;
151        /// Returns the yellow color component of this color.
152        fn yellow(self: &QColor) -> i32;
153    }
154
155    #[namespace = "rust::cxxqtlib1"]
156    unsafe extern "C++" {
157        type QColorNameFormat;
158        type QColorSpec;
159
160        #[doc(hidden)]
161        #[rust_name = "qcolor_color_names"]
162        fn qcolorColorNames() -> QStringList;
163        #[doc(hidden)]
164        #[rust_name = "qcolor_init_from_cmyk"]
165        fn qcolorInitFromCmyk(c: i32, m: i32, y: i32, k: i32, a: i32) -> QColor;
166        #[doc(hidden)]
167        #[rust_name = "qcolor_init_from_cmyk_f"]
168        fn qcolorInitFromCmykF(c: f32, m: f32, y: f32, k: f32, a: f32) -> QColor;
169        #[doc(hidden)]
170        #[rust_name = "qcolor_init_from_hsl"]
171        fn qcolorInitFromHsl(h: i32, s: i32, l: i32, a: i32) -> QColor;
172        #[doc(hidden)]
173        #[rust_name = "qcolor_init_from_hsl_f"]
174        fn qcolorInitFromHslF(h: f32, s: f32, l: f32, a: f32) -> QColor;
175        #[doc(hidden)]
176        #[rust_name = "qcolor_init_from_hsv"]
177        fn qcolorInitFromHsv(h: i32, s: i32, v: i32, a: i32) -> QColor;
178        #[doc(hidden)]
179        #[rust_name = "qcolor_init_from_hsv_f"]
180        fn qcolorInitFromHsvF(h: f32, s: f32, v: f32, a: f32) -> QColor;
181        #[doc(hidden)]
182        #[rust_name = "qcolor_init_from_rgb"]
183        fn qcolorInitFromRgb(red: i32, green: i32, blue: i32, alpha: i32) -> QColor;
184        #[doc(hidden)]
185        #[rust_name = "qcolor_init_from_rgb_f"]
186        fn qcolorInitFromRgbF(red: f32, green: f32, blue: f32, alpha: f32) -> QColor;
187
188        #[doc(hidden)]
189        #[rust_name = "qcolor_alpha_f"]
190        fn qcolorAlphaF(color: &QColor) -> f32;
191        #[doc(hidden)]
192        #[rust_name = "qcolor_black_f"]
193        fn qcolorBlackF(color: &QColor) -> f32;
194        #[doc(hidden)]
195        #[rust_name = "qcolor_blue_f"]
196        fn qcolorBlueF(color: &QColor) -> f32;
197        #[doc(hidden)]
198        #[rust_name = "qcolor_cyan_f"]
199        fn qcolorCyanF(color: &QColor) -> f32;
200        #[doc(hidden)]
201        #[rust_name = "qcolor_green_f"]
202        fn qcolorGreenF(color: &QColor) -> f32;
203        #[doc(hidden)]
204        #[rust_name = "qcolor_hsl_hue_f"]
205        fn qcolorHslHueF(color: &QColor) -> f32;
206        #[doc(hidden)]
207        #[rust_name = "qcolor_hsl_saturation_f"]
208        fn qcolorHslSaturationF(color: &QColor) -> f32;
209        #[doc(hidden)]
210        #[rust_name = "qcolor_hsv_hue_f"]
211        fn qcolorHsvHueF(color: &QColor) -> f32;
212        #[doc(hidden)]
213        #[rust_name = "qcolor_hsv_saturation_f"]
214        fn qcolorHsvSaturationF(color: &QColor) -> f32;
215        #[doc(hidden)]
216        #[rust_name = "qcolor_hue_f"]
217        fn qcolorHueF(color: &QColor) -> f32;
218        #[doc(hidden)]
219        #[rust_name = "qcolor_lightness_f"]
220        fn qcolorLightnessF(color: &QColor) -> f32;
221        #[doc(hidden)]
222        #[rust_name = "qcolor_magenta_f"]
223        fn qcolorMagentaF(color: &QColor) -> f32;
224        #[doc(hidden)]
225        #[rust_name = "qcolor_red_f"]
226        fn qcolorRedF(color: &QColor) -> f32;
227        #[doc(hidden)]
228        #[rust_name = "qcolor_saturation_f"]
229        fn qcolorSaturationF(color: &QColor) -> f32;
230        #[doc(hidden)]
231        #[rust_name = "qcolor_set_alpha_f"]
232        fn qcolorSetAlphaF(color: &mut QColor, alpha: f32);
233        #[doc(hidden)]
234        #[rust_name = "qcolor_set_blue_f"]
235        fn qcolorSetBlueF(color: &mut QColor, blue: f32);
236        #[doc(hidden)]
237        #[rust_name = "qcolor_set_cmyk_f"]
238        fn qcolorSetCmykF(color: &mut QColor, c: f32, m: f32, y: f32, k: f32, a: f32);
239        #[doc(hidden)]
240        #[rust_name = "qcolor_set_green_f"]
241        fn qcolorSetGreenF(color: &mut QColor, green: f32);
242        #[doc(hidden)]
243        #[rust_name = "qcolor_set_hsl_f"]
244        fn qcolorSetHslF(color: &mut QColor, h: f32, s: f32, l: f32, a: f32);
245        #[doc(hidden)]
246        #[rust_name = "qcolor_set_hsv_f"]
247        fn qcolorSetHsvF(color: &mut QColor, h: f32, s: f32, v: f32, a: f32);
248        #[doc(hidden)]
249        #[rust_name = "qcolor_set_red_f"]
250        fn qcolorSetRedF(color: &mut QColor, red: f32);
251        #[doc(hidden)]
252        #[rust_name = "qcolor_set_rgb_f"]
253        fn qcolorSetRgbF(color: &mut QColor, r: f32, g: f32, b: f32, a: f32);
254        #[doc(hidden)]
255        #[rust_name = "qcolor_value_f"]
256        fn qcolorValueF(color: &QColor) -> f32;
257        #[doc(hidden)]
258        #[rust_name = "qcolor_yellow_f"]
259        fn qcolorYellowF(color: &QColor) -> f32;
260    }
261
262    #[namespace = "rust::cxxqtlib1"]
263    unsafe extern "C++" {
264        include!("cxx-qt-lib/common.h");
265
266        #[doc(hidden)]
267        #[rust_name = "qcolor_init_default"]
268        fn construct() -> QColor;
269        #[doc(hidden)]
270        #[rust_name = "qcolor_init_from_qstring"]
271        fn construct(name: &QString) -> QColor;
272        #[doc(hidden)]
273        #[rust_name = "qcolor_eq"]
274        fn operatorEq(a: &QColor, b: &QColor) -> bool;
275    }
276}
277
278pub use ffi::{QColorNameFormat, QColorSpec};
279
280/// The `QColor` class provides colors based on RGB, HSL, HSV or CMYK values.
281///
282/// Qt Documentation: [QColor](https://doc.qt.io/qt/qcolor.html#details)
283#[derive(Clone)]
284#[repr(C)]
285pub struct QColor {
286    _cspec: MaybeUninit<i32>,
287    _ct: MaybeUninit<[u16; 5]>,
288}
289
290impl QColor {
291    /// Returns the alpha color component of this color.
292    pub fn alpha_f(&self) -> f32 {
293        ffi::qcolor_alpha_f(self)
294    }
295
296    /// Returns the black color component of this color.
297    pub fn black_f(&self) -> f32 {
298        ffi::qcolor_black_f(self)
299    }
300
301    /// Returns the blue color component of this color.
302    pub fn blue_f(&self) -> f32 {
303        ffi::qcolor_blue_f(self)
304    }
305
306    /// Returns a `QStringList` containing the color names Qt knows about.
307    pub fn color_names() -> QStringList {
308        ffi::qcolor_color_names()
309    }
310
311    /// Returns the cyan color component of this color.
312    pub fn cyan_f(&self) -> f32 {
313        ffi::qcolor_cyan_f(self)
314    }
315
316    /// Constructs a QColor from the CMYK value `c`, `m`, `y`, and `k`.
317    pub fn from_cmyk(c: i32, m: i32, y: i32, k: i32) -> Self {
318        ffi::qcolor_init_from_cmyk(c, m, y, k, 255)
319    }
320
321    /// Constructs a `QColor` from the CMYK value `c`, `m`, `y`, `k`, and the alpha-channel (transparency) value of `a`.
322    pub fn from_cmyka(c: i32, m: i32, y: i32, k: i32, a: i32) -> Self {
323        ffi::qcolor_init_from_cmyk(c, m, y, k, a)
324    }
325
326    /// Constructs a `QColor` from the CMYK value `c`, `m`, `y`, and `k`.
327    pub fn from_cmyk_f(c: f32, m: f32, y: f32, k: f32) -> Self {
328        ffi::qcolor_init_from_cmyk_f(c, m, y, k, 1.0)
329    }
330
331    /// Constructs a `QColor` from the CMYK value `c`, `m`, `y`, `k`, and the alpha-channel (transparency) value of `a`.
332    pub fn from_cmyka_f(c: f32, m: f32, y: f32, k: f32, a: f32) -> Self {
333        ffi::qcolor_init_from_cmyk_f(c, m, y, k, a)
334    }
335
336    /// Constructs a `QColor` from the HSL value `h`, `s`, and `l`.
337    pub fn from_hsl(h: i32, s: i32, l: i32) -> Self {
338        ffi::qcolor_init_from_hsl(h, s, l, 255)
339    }
340
341    /// Constructs a `QColor` from the HSL value `h`, `s`, `l`, and the alpha-channel (transparency) value of `a`.
342    pub fn from_hsla(h: i32, s: i32, l: i32, a: i32) -> Self {
343        ffi::qcolor_init_from_hsl(h, s, l, a)
344    }
345
346    /// Constructs a `QColor` from the HSL value `h`, `s`, and `l`.
347    pub fn from_hsl_f(h: f32, s: f32, l: f32) -> Self {
348        ffi::qcolor_init_from_hsl_f(h, s, l, 1.0)
349    }
350
351    /// Constructs a `QColor` from the HSL value `h`, `s`, `l`, and the alpha-channel (transparency) value of `a`.
352    pub fn from_hsla_f(h: f32, s: f32, l: f32, a: f32) -> Self {
353        ffi::qcolor_init_from_hsl_f(h, s, l, a)
354    }
355
356    /// Constructs a `QColor` from the HSV value `h`, `s`, and `v`.
357    pub fn from_hsv(h: i32, s: i32, v: i32) -> Self {
358        ffi::qcolor_init_from_hsv(h, s, v, 255)
359    }
360
361    /// Constructs a `QColor` from the HSV value `h`, `s`, `v`, and the alpha-channel (transparency) value of `a`.
362    pub fn from_hsva(h: i32, s: i32, v: i32, a: i32) -> Self {
363        ffi::qcolor_init_from_hsv(h, s, v, a)
364    }
365
366    /// Constructs a `QColor` from the HSV value `h`, `s`, and `v`.
367    pub fn from_hsv_f(h: f32, s: f32, v: f32) -> Self {
368        ffi::qcolor_init_from_hsv_f(h, s, v, 1.0)
369    }
370
371    /// Constructs a `QColor` from the HSV value `h`, `s`, `v`, and the alpha-channel (transparency) value of `a`.
372    pub fn from_hsva_f(h: f32, s: f32, v: f32, a: f32) -> Self {
373        ffi::qcolor_init_from_hsv_f(h, s, v, a)
374    }
375
376    /// Constructs a `QColor` with the RGB value `r`, `g`, and `b`.
377    ///
378    /// The color is left invalid if any of the arguments are invalid.
379    pub fn from_rgb(red: i32, green: i32, blue: i32) -> Self {
380        ffi::qcolor_init_from_rgb(red, green, blue, 255)
381    }
382
383    /// Constructs a `QColor` with the RGB value `r`, `g`, `b`, and the alpha-channel (transparency) value of `a`.
384    ///
385    /// The color is left invalid if any of the arguments are invalid.
386    pub fn from_rgba(red: i32, green: i32, blue: i32, alpha: i32) -> Self {
387        ffi::qcolor_init_from_rgb(red, green, blue, alpha)
388    }
389
390    /// Constructs a `QColor` with the RGB value `r`, `g`, and `b`.
391    pub fn from_rgb_f(red: f32, green: f32, blue: f32) -> Self {
392        ffi::qcolor_init_from_rgb_f(red, green, blue, 1.0)
393    }
394
395    /// Constructs a `QColor` with the RGB value `r`, `g`, `b`, and the alpha-channel (transparency) value of `a`.
396    pub fn from_rgba_f(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
397        ffi::qcolor_init_from_rgb_f(red, green, blue, alpha)
398    }
399
400    /// Returns the green color component of this color.
401    pub fn green_f(&self) -> f32 {
402        ffi::qcolor_green_f(self)
403    }
404
405    /// Returns the HSL hue color component of this color.
406    pub fn hsl_hue_f(&self) -> f32 {
407        ffi::qcolor_hsl_hue_f(self)
408    }
409
410    /// Returns the HSL saturation color component of this color.
411    pub fn hsl_saturation_f(&self) -> f32 {
412        ffi::qcolor_hsl_saturation_f(self)
413    }
414
415    /// Returns the hue color component of this color.
416    pub fn hsv_hue_f(&self) -> f32 {
417        ffi::qcolor_hsv_hue_f(self)
418    }
419
420    /// Returns the HSV saturation color component of this color.
421    pub fn hsv_saturation_f(&self) -> f32 {
422        ffi::qcolor_hsv_saturation_f(self)
423    }
424
425    /// Returns the HSV hue color component of this color.
426    ///
427    /// The color is implicitly converted to HSV.
428    pub fn hue_f(self: &QColor) -> f32 {
429        ffi::qcolor_hue_f(self)
430    }
431
432    /// Returns the lightness color component of this color.
433    pub fn lightness_f(&self) -> f32 {
434        ffi::qcolor_lightness_f(self)
435    }
436
437    /// Returns the magenta color component of this color.
438    pub fn magenta_f(&self) -> f32 {
439        ffi::qcolor_magenta_f(self)
440    }
441
442    /// Returns the red color component of this color.
443    pub fn red_f(&self) -> f32 {
444        ffi::qcolor_red_f(self)
445    }
446
447    /// Returns the HSV saturation color component of this color.
448    ///
449    /// The color is implicitly converted to HSV.
450    pub fn saturation_f(&self) -> f32 {
451        ffi::qcolor_saturation_f(self)
452    }
453
454    /// Sets the alpha of this color to `alpha`. float alpha is specified in the range 0.0-1.0.
455    pub fn set_alpha_f(&mut self, alpha: f32) {
456        ffi::qcolor_set_alpha_f(self, alpha);
457    }
458
459    /// Sets the blue color component of this color to `blue`.
460    ///
461    /// If `blue` lies outside the 0.0-1.0 range, the color model will be changed to [`QColorSpec::ExtendedRgb`].
462    pub fn set_blue_f(&mut self, blue: f32) {
463        ffi::qcolor_set_blue_f(self, blue);
464    }
465
466    /// Sets the color to CMYK values, `c` (cyan), `m` (magenta), `y` (yellow), `k` (black), and `a` (alpha-channel, i.e. transparency).
467    ///
468    /// All the values must be in the range 0.0-1.0.
469    pub fn set_cmyk_f(&mut self, c: f32, m: f32, y: f32, k: f32, a: f32) {
470        ffi::qcolor_set_cmyk_f(self, c, m, y, k, a);
471    }
472
473    /// Sets the green color component of this color to green.
474    ///
475    /// If `green` lies outside the 0.0-1.0 range, the color model will be changed to [`QColorSpec::ExtendedRgb`].
476    pub fn set_green_f(&mut self, green: f32) {
477        ffi::qcolor_set_green_f(self, green);
478    }
479
480    /// Sets a HSL color lightness; `h` is the hue, `s` is the saturation, `l` is the lightness and `a` is the alpha component of the HSL color.
481    ///
482    /// All the values must be in the range 0.0-1.0.
483    pub fn set_hsl_f(&mut self, h: f32, s: f32, l: f32, a: f32) {
484        ffi::qcolor_set_hsl_f(self, h, s, l, a);
485    }
486
487    /// Sets a HSV color value; `h` is the hue, `s` is the saturation, `v` is the value and `a` is the alpha component of the HSV color.
488    ///
489    /// All the values must be in the range 0.0-1.0.
490    pub fn set_hsv_f(&mut self, h: f32, s: f32, v: f32, a: f32) {
491        ffi::qcolor_set_hsv_f(self, h, s, v, a);
492    }
493
494    /// Sets the red color component of this color to `red`.
495    ///
496    /// If `red` lies outside the 0.0-1.0 range, the color model will be changed to [`QColorSpec::ExtendedRgb`].
497    pub fn set_red_f(&mut self, red: f32) {
498        ffi::qcolor_set_red_f(self, red);
499    }
500
501    /// Sets the color channels of this color to `r` (red), `g` (green), `b` (blue) and `a` (alpha, transparency).
502    ///
503    /// The alpha value must be in the range 0.0-1.0. If any of the other values are outside the range of 0.0-1.0 the color model will be set as [`QColorSpec::ExtendedRgb`].
504    pub fn set_rgb_f(&mut self, r: f32, g: f32, b: f32, a: f32) {
505        ffi::qcolor_set_rgb_f(self, r, g, b, a);
506    }
507
508    /// Returns the value color component of this color.
509    pub fn value_f(self: &QColor) -> f32 {
510        ffi::qcolor_value_f(self)
511    }
512
513    /// Returns the yellow color component of this color.
514    pub fn yellow_f(self: &QColor) -> f32 {
515        ffi::qcolor_yellow_f(self)
516    }
517}
518
519impl Default for QColor {
520    /// Constructs an invalid color. An invalid color is a color that is not properly set up for the underlying window system.
521    ///
522    /// The alpha value of an invalid color is unspecified.
523    fn default() -> Self {
524        ffi::qcolor_init_default()
525    }
526}
527
528impl TryFrom<&str> for QColor {
529    type Error = &'static str;
530
531    fn try_from(value: &str) -> Result<Self, Self::Error> {
532        Self::try_from(&QString::from(value))
533    }
534}
535
536impl TryFrom<&String> for QColor {
537    type Error = &'static str;
538
539    fn try_from(value: &String) -> Result<Self, Self::Error> {
540        Self::try_from(value.as_str())
541    }
542}
543
544impl TryFrom<&QString> for QColor {
545    type Error = &'static str;
546
547    fn try_from(value: &QString) -> Result<Self, Self::Error> {
548        let color = ffi::qcolor_init_from_qstring(value);
549        if color.is_valid() {
550            Ok(color)
551        } else {
552            Err("Invalid color")
553        }
554    }
555}
556
557impl std::cmp::PartialEq for QColor {
558    fn eq(&self, other: &Self) -> bool {
559        ffi::qcolor_eq(self, other)
560    }
561}
562
563impl std::cmp::Eq for QColor {}
564
565impl fmt::Display for QColor {
566    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
567        if f.width().is_some() || f.precision().is_some() {
568            #[allow(clippy::recursive_format_impl)]
569            return f.pad(&self.to_string());
570        }
571        // TODO: consider the different color spec
572        let r = self.red();
573        let g = self.green();
574        let b = self.blue();
575        let a = self.alpha();
576        write!(f, "RGBA({r}, {g}, {b}, {a})")
577    }
578}
579
580impl fmt::Debug for QColor {
581    // We use more fancy printing for the Debug formatter
582    // If you dislike this, use the Display formatter instead
583    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
584        // TODO: consider the different color spec
585        let r = self.red();
586        let g = self.green();
587        let b = self.blue();
588        let a = self.alpha();
589        // very simple heuristic to use a light foreground if background is dark and vice versa
590        let fg = if (r + b + g) < 384 { 255 } else { 0 };
591        // Use terminal escape codes to **actually** print the color
592        write!(f, "\x1b[48;2;{r};{g};{b}m\x1b[38;2;{fg};{fg};{fg}mRGBA({r}, {g}, {b}, {a})\x1b[39m\x1b[49m")
593    }
594}
595
596#[cfg(feature = "rgb")]
597impl From<&rgb::RGB8> for QColor {
598    fn from(value: &rgb::RGB8) -> Self {
599        Self::from_rgb(value.r as i32, value.g as i32, value.b as i32)
600    }
601}
602
603#[cfg(feature = "rgb")]
604impl From<&rgb::RGBA8> for QColor {
605    fn from(value: &rgb::RGBA8) -> Self {
606        Self::from_rgba(
607            value.r as i32,
608            value.g as i32,
609            value.b as i32,
610            value.a as i32,
611        )
612    }
613}
614
615#[cfg(feature = "rgb")]
616impl From<&QColor> for rgb::RGB8 {
617    fn from(value: &QColor) -> Self {
618        Self {
619            r: value.red() as u8,
620            g: value.green() as u8,
621            b: value.blue() as u8,
622        }
623    }
624}
625
626#[cfg(feature = "rgb")]
627impl From<&QColor> for rgb::RGBA8 {
628    fn from(value: &QColor) -> Self {
629        Self {
630            r: value.red() as u8,
631            g: value.green() as u8,
632            b: value.blue() as u8,
633            a: value.alpha() as u8,
634        }
635    }
636}
637
638// Safety:
639//
640// Static checks on the C++ side to ensure the size is the same.
641unsafe impl ExternType for QColor {
642    type Id = type_id!("QColor");
643    type Kind = cxx::kind::Trivial;
644}
645
646#[cfg(test)]
647mod tests {
648    #[cfg(feature = "rgb")]
649    use super::*;
650
651    #[cfg(feature = "rgb")]
652    #[test]
653    fn test_rgb() {
654        let color = rgb::RGB8 {
655            r: 0,
656            g: 100,
657            b: 255,
658        };
659        let qcolor = QColor::from(&color);
660        assert_eq!(qcolor.red(), 0);
661        assert_eq!(qcolor.green(), 100);
662        assert_eq!(qcolor.blue(), 255);
663        assert_eq!(qcolor.alpha(), 255);
664
665        let rgb_color = rgb::RGB8::from(&qcolor);
666        assert_eq!(color, rgb_color);
667    }
668
669    #[cfg(feature = "rgb")]
670    #[test]
671    fn test_rgba() {
672        let color = rgb::RGBA8 {
673            r: 0,
674            g: 100,
675            b: 255,
676            a: 100,
677        };
678        let qcolor = QColor::from(&color);
679        assert_eq!(qcolor.red(), 0);
680        assert_eq!(qcolor.green(), 100);
681        assert_eq!(qcolor.blue(), 255);
682        assert_eq!(qcolor.alpha(), 100);
683
684        let rgba_color = rgb::RGBA8::from(&qcolor);
685        assert_eq!(color, rgba_color);
686    }
687
688    #[test]
689    fn test_display_fmt() {
690        let qcolor = QColor::from_rgba(50, 100, 150, 200);
691        assert_eq!(format!("{qcolor:-<30}"), "RGBA(50, 100, 150, 200)-------");
692    }
693}