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 
30  QPixmap CRgbColor::toPixmap() const
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  else if (isName)
119  {
120  const QColor q(color);
121  m_r = q.red();
122  m_g = q.green();
123  m_b = q.blue();
124  }
125  else
126  {
127  const QString c(color.trimmed());
128  QColor q(c);
129  if (this->setQColor(q)) { return; }
130  if (c.startsWith("#"))
131  {
132  this->setInvalid();
133  return;
134  }
135  q.setNamedColor("#" + c);
136  this->setQColor(q);
137  }
138  }
139 
140  bool CRgbColor::isValid() const { return m_r >= 0 && m_g >= 0 && m_b >= 0; }
141 
142  double CRgbColor::colorDistance(const CRgbColor &color) const
143  {
144  if (!this->isValid() && !color.isValid()) { return 0; }
145  if (!this->isValid() || !color.isValid()) { return 1; }
146  if (*this == color) { return 0.0; } // avoid rounding
147 
148  // all values 0-1
149  const double rd = (normalizedRed() - color.normalizedRed());
150  const double bd = (normalizedBlue() - color.normalizedBlue());
151  const double gd = (normalizedGreen() - color.normalizedGreen());
152  return (rd * rd + bd * bd + gd * gd) / 3.0;
153  }
154 
156  {
157  m_r = -1;
158  m_g = -1;
159  m_b = -1;
160  }
161 
162  QString CRgbColor::convertToQString(bool i18n) const
163  {
164  Q_UNUSED(i18n);
165  return this->hex();
166  }
167 
169  {
170  if (index.isMyself()) { return QVariant::fromValue(*this); }
171  const ColumnIndex i = index.frontCasted<ColumnIndex>();
172  switch (i)
173  {
174  case IndexBlue: return QVariant::fromValue(blue());
175  case IndexRed: return QVariant::fromValue(red());
176  case IndexGreen: return QVariant::fromValue(green());
177  case IndexWebHex: return QVariant::fromValue(hex());
178  default: return CValueObject::propertyByIndex(index);
179  }
180  }
181 
182  void CRgbColor::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
183  {
184  if (index.isMyself())
185  {
186  (*this) = variant.value<CRgbColor>();
187  return;
188  }
189  const ColumnIndex i = index.frontCasted<ColumnIndex>();
190  switch (i)
191  {
192  case IndexBlue: m_b = variant.toInt(); break;
193  case IndexRed: m_r = variant.toInt(); break;
194  case IndexGreen: m_g = variant.toInt(); break;
195  case IndexWebHex: this->setByString(variant.toString()); break;
196  default: CValueObject::setPropertyByIndex(index, variant); break;
197  }
198  }
199 
200  int CRgbColor::comparePropertyByIndex(CPropertyIndexRef index, const CRgbColor &compareValue) const
201  {
202  if (index.isMyself()) { return this->compare(compareValue); }
203  const ColumnIndex i = index.frontCasted<ColumnIndex>();
204  switch (i)
205  {
206  case IndexBlue: return Compare::compare(m_b, compareValue.m_b);
207  case IndexRed: return Compare::compare(m_r, compareValue.m_r);
208  case IndexGreen: return Compare::compare(m_g, compareValue.m_g);
209  case IndexWebHex: return this->compare(compareValue);
210  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Missing compare"); break;
211  }
212  return 0;
213  }
214 
215  int CRgbColor::compare(const CRgbColor &color) const
216  {
217  int c = Compare::compare(m_r, color.m_r);
218  if (c != 0) { return c; }
219  c = Compare::compare(m_g, color.m_g);
220  if (c != 0) { return c; }
221  return Compare::compare(m_b, color.m_b);
222  }
223 
224  double CRgbColor::colorRange() const
225  {
226  if (!this->isValid()) { return 255; }
227  if (m_b < 256 && m_g < 256 && m_r < 256) { return 255; }
228  if (m_b < 4096 && m_g < 4096 && m_r < 4096) { return 4095; }
229  return 65535;
230  }
231 
232  QString CRgbColor::intToHex(int h, int digits) { return swift::misc::intToHex(h, digits); }
233 
234 } // 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:168
QString hex(bool withHash=false) const
Hex value.
Definition: rgbcolor.cpp:100
void setInvalid()
Mark as invalid.
Definition: rgbcolor.cpp:155
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:162
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:142
void setPropertyByIndex(swift::misc::CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: rgbcolor.cpp:182
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:200
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:215
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:140
ColumnIndex
Base class enums.
Definition: mixinindex.h:44
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
Set property by index.
Definition: mixinindex.h:160
QVariant propertyByIndex(CPropertyIndexRef index) const
Property by index.
Definition: mixinindex.h:167
Free functions in swift::misc.
SWIFT_MISC_EXPORT QString intToHex(int value, int digits=2)
Int to hex value.
#define SWIFT_DEFINE_VALUEOBJECT_MIXINS(Namespace, Class)
Explicit template definition of mixins for a CValueObject subclass.
Definition: valueobject.h:67