File indexing completed on 2024-05-12 04:44:35
0001 // SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0002 // SPDX-License-Identifier: BSD-2-Clause OR MIT 0003 0004 #ifndef RGBCOLOR_H 0005 #define RGBCOLOR_H 0006 0007 #include "genericcolor.h" 0008 #include <optional> 0009 #include <qcolor.h> 0010 #include <qdebug.h> 0011 0012 namespace PerceptualColor 0013 { 0014 0015 /** @internal 0016 * 0017 * @brief An RGB color stored in multiple different RGB transformations. 0018 * 0019 * Unlike <tt>QColor</tt> (which is essentially a C++ <tt>union</tt> of 0020 * different color formats, so only one of them is actually saved), 0021 * @ref RgbColor <em>actually</em> stores <em>all</em> available color 0022 * transformations. 0023 * 0024 * This data type is just an (ugly) implementation detail of @ref ColorDialog. 0025 * For simplicity, data members are accessible directly, without write 0026 * protection. Usage: Create instances of this class with one of the static 0027 * factory functions, and assign them to <tt>const</tt> variables. The factory 0028 * functions guarantee that all data members have correct values representing 0029 * the <em>same</em> color. 0030 * 0031 * Changes to some values of some color formats under certain 0032 * circumstances do not change the color: 0033 * - HSL saturation: When the color is either black (L = 0%) or 0034 * white (L = 100%). 0035 * - HSV/HSB saturation: When the color is black (V/B = 0%). 0036 * 0037 * The color conversion of this class provides meaningful and predictable 0038 * <em>HSL-saturation</em> and <em>HSV-saturation</em> values. 0039 * 0040 * This data type can be passed to QDebug thanks to 0041 * @ref operator<<(QDebug dbg, const PerceptualColor::RgbColor &value) 0042 * 0043 * @sa @ref AbsoluteColor */ 0044 class RgbColor final 0045 { 0046 public: 0047 [[nodiscard]] static RgbColor fromHsl(const GenericColor &color); 0048 [[nodiscard]] static RgbColor fromHsv(const GenericColor &color); 0049 [[nodiscard]] static RgbColor fromHwb(const GenericColor &color); 0050 [[nodiscard]] static RgbColor fromRgb255(const GenericColor &color, std::optional<double> hue = std::optional<double>()); 0051 [[nodiscard]] static RgbColor fromRgbQColor(const QColor &color); 0052 0053 /** @brief Constructor for an uninitialized object. 0054 * 0055 * This constructor is quite useless except for declaring variables 0056 * of this type. Use the static functions to get an actual color object. 0057 * 0058 * @warning As the data members are uninitialized, this implies that the 0059 * count of <tt>QList</tt> items is not correct! */ 0060 RgbColor(); 0061 /** @brief Default copy constructor 0062 * @param other the object to copy */ 0063 RgbColor(const RgbColor &other) = default; 0064 /** @brief Default copy assignment operator 0065 * @param other the object to copy 0066 * @returns The default implementation’s return value. */ 0067 RgbColor &operator=(const RgbColor &other) = default; 0068 // NOTE About move constructor and move assignment operator: 0069 // Declaring them with “= default” will create a compiler-generated 0070 // implementation that, apparently, does not copy correctly 0071 // the data members of type QList. Using “=delete” however 0072 // will create a move constructor that it forbidden to be used. 0073 // When some code needs a move constructor, the overload resolution 0074 // will choose this move constructor, and the compilation fails 0075 // because it is forbidden to be used. For details on this behaviour, 0076 // see https://blog.knatten.org/2021/10/15/ Therefore, we do not declare 0077 // the move constructor at all: Because the copy constructor exists, the 0078 // move constructor will not be generated implicitly at all. When some 0079 // code needs a move constructor, the overload resolution does not find 0080 // one and falls back to the copy constructor (which is the default 0081 // implementation, but apparently works correctly also for QList members). 0082 // RgbColor &operator=(RgbColor &&other) noexcept = default; 0083 // RgbColor(RgbColor &&other) noexcept = default; 0084 0085 [[nodiscard]] bool operator==(const RgbColor &other) const; 0086 0087 /** @brief HWB representation. 0088 * 0089 * Range: [0, 360], [0, 100], [0, 100] */ 0090 GenericColor hwb; 0091 /** @brief HSL representation. 0092 * 0093 * Range: [0, 360], [0, 100], [0, 100] */ 0094 GenericColor hsl; 0095 /** @brief HSV representation. 0096 * 0097 * Range: [0, 360], [0, 100], [0, 100] */ 0098 GenericColor hsv; 0099 /** @brief RGB representation. 0100 * 0101 * Range: [0, 255] */ 0102 GenericColor rgb255; 0103 /** @brief QColor representation. 0104 * 0105 * <tt>QColor::spec()</tt> is <tt>QColor::Rgb</tt>. */ 0106 QColor rgbQColor; 0107 0108 private: 0109 void fillAll(QColor color, std::optional<double> hue); 0110 }; 0111 0112 QDebug operator<<(QDebug dbg, const PerceptualColor::RgbColor &value); 0113 0114 } // namespace PerceptualColor 0115 0116 #endif // RGBCOLOR_H