swift
rgbcolor.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/rgbcolor.h"
5 
6 #include <QBrush>
7 #include <QPainter>
8 #include <QPixmap>
9 #include <QSize>
10 #include <QStringBuilder>
11 #include <QtGlobal>
12 
13 #include "misc/comparefunctions.h"
14 #include "misc/icons.h"
16 #include "misc/stringutils.h"
17 
18 using namespace swift::misc;
19 
21 
22 namespace swift::misc
23 {
24  CRgbColor::CRgbColor(const QString &color, bool isName) { this->setByString(color, isName); }
25 
26  CRgbColor::CRgbColor(int r, int g, int b) : m_r(r), m_g(g), m_b(b) {}
27 
28  CRgbColor::CRgbColor(const QColor &color) { this->setQColor(color); }
29 
31  {
32  QPixmap pixmap(QSize(16, 16));
33  QPainter p(&pixmap);
34  p.setBackground(QBrush(this->toQColor()));
35  p.setBrush(this->toQColor());
36  p.drawRect(0, 0, 16, 16);
37  return pixmap;
38  }
39 
41  {
42  // if (this->isValid())
43  //{
44  // return CIcon(toPixmap(), hex());
45  // }
46  // else
47  {
48  return CIcons::StandardIconError16;
49  }
50  }
51 
52  QColor CRgbColor::toQColor() const { return QColor(red(), green(), blue()); }
53 
54  bool CRgbColor::setQColor(const QColor &color)
55  {
56  if (color.isValid())
57  {
58  m_r = color.red();
59  m_g = color.green();
60  m_b = color.blue();
61  return true;
62  }
63  else
64  {
65  this->setInvalid();
66  return false;
67  }
68  }
69 
70  int CRgbColor::red() const { return m_r; }
71 
72  double CRgbColor::normalizedRed() const
73  {
74  double c = red() * 1.0;
75  return c / colorRange();
76  }
77 
78  QString CRgbColor::redHex(int digits) const { return intToHex(m_r, digits); }
79 
80  int CRgbColor::green() const { return m_g; }
81 
83  {
84  double c = green() * 1.0;
85  return c / colorRange();
86  }
87 
88  QString CRgbColor::greenHex(int digits) const { return intToHex(m_g, digits); }
89 
90  int CRgbColor::blue() const { return m_b; }
91 
93  {
94  double c = blue() * 1.0;
95  return c / colorRange();
96  }
97 
98  QString CRgbColor::blueHex(int digits) const { return intToHex(m_b, digits); }
99 
100  QString CRgbColor::hex(bool withHash) const
101  {
102  if (!isValid()) { return {}; }
103  const QString h(redHex() + greenHex() + blueHex());
104  return withHash ? u'#' % h : h;
105  }
106 
107  int CRgbColor::packed() const
108  {
109  if (!isValid()) { return 0; }
110  return static_cast<int>(toQColor().rgb() & qRgba(255, 255, 255, 0));
111  }
112 
113  CRgbColor CRgbColor::fromPacked(int rgb) { return { qRed(rgb), qGreen(rgb), qBlue(rgb) }; }
114 
115  void CRgbColor::setByString(const QString &color, bool isName)
116  {
117  if (color.isEmpty()) { return; }
118 
119  if (isName)
120  {
121  const QColor q(color);
122  m_r = q.red();
123  m_g = q.green();
124  m_b = q.blue();
125  }
126  else
127  {
128  const QString c(color.trimmed());
129  QColor q(c);
130  if (this->setQColor(q)) { return; }
131  if (c.startsWith("#"))
132  {
133  this->setInvalid();
134  return;
135  }
136  q = QColor::fromString("#" + c);
137  this->setQColor(q);
138  }
139  }
140 
141  bool CRgbColor::isValid() const { return m_r >= 0 && m_g >= 0 && m_b >= 0; }
142 
143  double CRgbColor::colorDistance(const CRgbColor &color) const
144  {
145  if (!this->isValid() && !color.isValid()) { return 0; }
146  if (!this->isValid() || !color.isValid()) { return 1; }
147  if (*this == color) { return 0.0; } // avoid rounding
148 
149  // all values 0-1
150  const double rd = (normalizedRed() - color.normalizedRed());
151  const double bd = (normalizedBlue() - color.normalizedBlue());
152  const double gd = (normalizedGreen() - color.normalizedGreen());
153  return (rd * rd + bd * bd + gd * gd) / 3.0;
154  }
155 
157  {
158  m_r = -1;
159  m_g = -1;
160  m_b = -1;
161  }
162 
164  {
165  Q_UNUSED(i18n);
166  return this->hex();
167  }
168 
170  {
171  if (index.isMyself()) { return QVariant::fromValue(*this); }
172  const ColumnIndex i = index.frontCasted<ColumnIndex>();
173  switch (i)
174  {
175  case IndexBlue: return QVariant::fromValue(blue());
176  case IndexRed: return QVariant::fromValue(red());
177  case IndexGreen: return QVariant::fromValue(green());
178  case IndexWebHex: return QVariant::fromValue(hex());
179  default: return CValueObject::propertyByIndex(index);
180  }
181  }
182 
184  {
185  if (index.isMyself())
186  {
187  (*this) = variant.value<CRgbColor>();
188  return;
189  }
190  const ColumnIndex i = index.frontCasted<ColumnIndex>();
191  switch (i)
192  {
193  case IndexBlue: m_b = variant.toInt(); break;
194  case IndexRed: m_r = variant.toInt(); break;
195  case IndexGreen: m_g = variant.toInt(); break;
196  case IndexWebHex: this->setByString(variant.toString()); break;
197  default: CValueObject::setPropertyByIndex(index, variant); break;
198  }
199  }
200 
201  int CRgbColor::comparePropertyByIndex(CPropertyIndexRef index, const CRgbColor &compareValue) const
202  {
203  if (index.isMyself()) { return this->compare(compareValue); }
204  const ColumnIndex i = index.frontCasted<ColumnIndex>();
205  switch (i)
206  {
207  case IndexBlue: return Compare::compare(m_b, compareValue.m_b);
208  case IndexRed: return Compare::compare(m_r, compareValue.m_r);
209  case IndexGreen: return Compare::compare(m_g, compareValue.m_g);
210  case IndexWebHex: return this->compare(compareValue);
211  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Missing compare"); break;
212  }
213  return 0;
214  }
215 
216  int CRgbColor::compare(const CRgbColor &color) const
217  {
218  int c = Compare::compare(m_r, color.m_r);
219  if (c != 0) { return c; }
220  c = Compare::compare(m_g, color.m_g);
221  if (c != 0) { return c; }
222  return Compare::compare(m_b, color.m_b);
223  }
224 
225  double CRgbColor::colorRange() const
226  {
227  if (!this->isValid()) { return 255; }
228  if (m_b < 256 && m_g < 256 && m_r < 256) { return 255; }
229  if (m_b < 4096 && m_g < 4096 && m_r < 4096) { return 4095; }
230  return 65535;
231  }
232 
233  QString CRgbColor::intToHex(int h, int digits) { return swift::misc::intToHex(h, digits); }
234 
235 } // namespace swift::misc
IconIndex
Index for each icon, allows to send them via DBus, efficiently store them, etc.
Definition: icons.h:32
Non-owning reference to a CPropertyIndex with a subset of its features.
CastType frontCasted() const
First element casted to given type, usually the PropertIndex enum.
bool isMyself() const
Myself index, used with nesting.
QString blueHex(int digits=2) const
Blue as hex.
Definition: rgbcolor.cpp:98
double normalizedBlue() const
Blue 0..1.
Definition: rgbcolor.cpp:92
QVariant propertyByIndex(swift::misc::CPropertyIndexRef index) const
Property by index.
Definition: rgbcolor.cpp:169
QString hex(bool withHash=false) const
Hex value.
Definition: rgbcolor.cpp:100
void setInvalid()
Mark as invalid.
Definition: rgbcolor.cpp:156
int green() const
Green.
Definition: rgbcolor.cpp:80
int blue() const
Blue.
Definition: rgbcolor.cpp:90
QPixmap toPixmap() const
Icon as pixmap.
Definition: rgbcolor.cpp:30
QColor toQColor() const
To QColor.
Definition: rgbcolor.cpp:52
bool setQColor(const QColor &color)
Set by QColor.
Definition: rgbcolor.cpp:54
QString convertToQString(bool i18n=false) const
Cast as QString.
Definition: rgbcolor.cpp:163
int packed() const
Value packed in 24 bit integer.
Definition: rgbcolor.cpp:107
static CRgbColor fromPacked(int rgb)
Construct from packed 24 bit integer value.
Definition: rgbcolor.cpp:113
double normalizedRed() const
Red 0..1.
Definition: rgbcolor.cpp:72
double colorDistance(const CRgbColor &color) const
Color distance [0..1] http://stackoverflow.com/questions/4754506/color-similarity-distance-in-rgba-co...
Definition: rgbcolor.cpp:143
void setPropertyByIndex(swift::misc::CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: rgbcolor.cpp:183
void setByString(const QString &color, bool isName=false)
Hex or color name.
Definition: rgbcolor.cpp:115
int comparePropertyByIndex(CPropertyIndexRef index, const CRgbColor &compareValue) const
Compare for index.
Definition: rgbcolor.cpp:201
int red() const
Red.
Definition: rgbcolor.cpp:70
double normalizedGreen() const
Green 0..1.
Definition: rgbcolor.cpp:82
QString redHex(int digits=2) const
Red as hex.
Definition: rgbcolor.cpp:78
CRgbColor()=default
Constructor.
int compare(const CRgbColor &color) const
Compare with other color.
Definition: rgbcolor.cpp:216
QString greenHex(int digits=2) const
Green as hex.
Definition: rgbcolor.cpp:88
CIcons::IconIndex toIcon() const
Representing icon.
Definition: rgbcolor.cpp:40
bool isValid() const
Valid?
Definition: rgbcolor.cpp:141
ColumnIndex
Base class enums.
Definition: mixinindex.h:44
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:158
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:165
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString intToHex(int value, int digits=2)
Int to hex value.
int blue() const const
QColor fromString(QAnyStringView name)
int green() const const
bool isValid() const const
int red() const const
QRgb rgb() const const
void drawRect(const QRect &rectangle)
void setBackground(const QBrush &brush)
void setBrush(QColor color)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString trimmed() const const
QVariant fromValue(T &&value)
int toInt(bool *ok) const const
QString toString() const const
T value() const &const
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67