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