GrantleeTheme

color.cpp
1 /*
2  * SPDX-FileCopyrightText: 2019 Volker Krause <[email protected]>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  */
6 
7 #include "color.h"
8 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
9 #include <grantlee/exception.h>
10 #include <grantlee/metatype.h>
11 #include <grantlee/parser.h>
12 #include <grantlee/variable.h>
13 #else
14 #include <KTextTemplate/exception.h>
15 #include <KTextTemplate/metatype.h>
16 #include <KTextTemplate/parser.h>
17 #include <KTextTemplate/variable.h>
18 #endif
19 
20 #include <KColorUtils>
21 #include <QColor>
22 
23 static QColor inputToColor(const QVariant &v)
24 {
25 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
26  if (v.canConvert<Grantlee::SafeString>()) {
27  return QColor(v.value<Grantlee::SafeString>().get());
28  }
29 #else
30  if (v.canConvert<KTextTemplate::SafeString>()) {
31  return QColor(v.value<KTextTemplate::SafeString>().get());
32  }
33 #endif
34  return v.value<QColor>();
35 }
36 
37 static QString rgbaString(const QColor &c)
38 {
39  return QLatin1String("rgba(") + QString::number(c.red()) + QLatin1String(", ") + QString::number(c.green()) + QLatin1String(", ")
41 }
42 
43 #define COLOR_PROP(name) \
44  if (property == QLatin1String(#name)) { \
45  return object.name(); \
46  }
47 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
48 GRANTLEE_BEGIN_LOOKUP(QColor)
49 #else
50 KTEXTTEMPLATE_BEGIN_LOOKUP(QColor)
51 #endif
52 COLOR_PROP(red)
53 COLOR_PROP(green)
54 COLOR_PROP(blue)
55 COLOR_PROP(alpha)
56 if (property == QLatin1String("hexRgb")) {
57  return object.name();
58 }
59 if (property == QLatin1String("cssRgba")) {
60  return rgbaString(object);
61 }
62 return {};
63 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
64 GRANTLEE_END_LOOKUP
65 #else
66 KTEXTTEMPLATE_END_LOOKUP
67 #endif
68 void Color::registerMetaType()
69 {
70 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
71  Grantlee::registerMetaType<QColor>();
72 #else
73  KTextTemplate::registerMetaType<QColor>();
74 #endif
75 }
76 
77 QVariant ColorHexRgbFilter::doFilter(const QVariant &input, const QVariant &arg, bool autoescape) const
78 {
79  Q_UNUSED(arg)
80  Q_UNUSED(autoescape)
81 
82  const auto color = inputToColor(input);
83  return color.name();
84 }
85 
86 QVariant ColorCssRgbaFilter::doFilter(const QVariant &input, const QVariant &arg, bool autoescape) const
87 {
88  Q_UNUSED(arg)
89  Q_UNUSED(autoescape)
90 
91  const auto color = inputToColor(input);
92  return rgbaString(color);
93 }
94 
95 QVariant ColorLighterFilter::doFilter(const QVariant &input, const QVariant &arg, bool autoescape) const
96 {
97  Q_UNUSED(autoescape)
98 
99  const auto color = inputToColor(input);
100  const auto factor = arg.toInt();
101  return color.lighter(factor);
102 }
103 
104 QVariant ColorDarkerFilter::doFilter(const QVariant &input, const QVariant &arg, bool autoescape) const
105 {
106  Q_UNUSED(autoescape)
107 
108  const auto color = inputToColor(input);
109  const auto factor = arg.toInt();
110  return color.darker(factor);
111 }
112 
113 QVariant ColorSetAlphaFilter::doFilter(const QVariant &input, const QVariant &arg, bool autoescape) const
114 {
115  Q_UNUSED(autoescape)
116 
117  auto color = inputToColor(input);
118  color.setAlpha(arg.toInt());
119  return color;
120 }
121 
122 ColorMixTag::ColorMixTag(QObject *parent)
123 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
124  : Grantlee::AbstractNodeFactory(parent)
125 #else
126  : KTextTemplate::AbstractNodeFactory(parent)
127 #endif
128 {
129 }
130 
131 ColorMixTag::~ColorMixTag() = default;
132 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
133 Grantlee::Node *ColorMixTag::getNode(const QString &tagContent, Grantlee::Parser *p) const
134 #else
135 KTextTemplate::Node *ColorMixTag::getNode(const QString &tagContent, KTextTemplate::Parser *p) const
136 #endif
137 {
138  Q_UNUSED(p)
139  const auto parts = smartSplit(tagContent);
140  if (parts.size() != 4 && parts.size() != 6) {
141 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
142  throw Grantlee::Exception(Grantlee::TagSyntaxError, QStringLiteral("colormix tag needs 3 or 5 arguments"));
143 #else
144  throw KTextTemplate::Exception(KTextTemplate::TagSyntaxError, QStringLiteral("colormix tag needs 3 or 5 arguments"));
145 #endif
146  }
147 
148  bool ok = false;
149  const auto ratio = parts.at(3).toDouble(&ok);
150  if (!ok) {
151 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
152  throw Grantlee::Exception(Grantlee::TagSyntaxError, QStringLiteral("colormix: invalid ratio"));
153 #else
154  throw KTextTemplate::Exception(KTextTemplate::TagSyntaxError, QStringLiteral("colormix: invalid ratio"));
155 #endif
156  }
157 
158  QString varName;
159  if (parts.size() == 6) {
160  if (parts.at(4) != QLatin1String("as")) {
161 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
162  throw Grantlee::Exception(Grantlee::TagSyntaxError, QStringLiteral("colormix: syntax error"));
163 #else
164  throw KTextTemplate::Exception(KTextTemplate::TagSyntaxError, QStringLiteral("colormix: syntax error"));
165 #endif
166  }
167  varName = parts.at(5);
168  }
169 
170  return new ColorMixNode(parts.at(1), parts.at(2), ratio, varName);
171 }
172 
173 ColorMixNode::ColorMixNode(const QString &color1Name, const QString &color2Name, double ratio, const QString &varName, QObject *parent)
174 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
175  : Grantlee::Node(parent)
176 #else
177  : KTextTemplate::Node(parent)
178 #endif
179  , m_color1Name(color1Name)
180  , m_color2Name(color2Name)
181  , m_varName(varName)
182  , m_ratio(ratio)
183 {
184 }
185 
186 ColorMixNode::~ColorMixNode() = default;
187 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
188 static QColor resolveColor(const QString &name, Grantlee::Context *c)
189 #else
190 static QColor resolveColor(const QString &name, KTextTemplate::Context *c)
191 #endif
192 {
193  if (name.startsWith(QLatin1Char('"')) && name.endsWith(QLatin1Char('"'))) {
194  return QColor(QStringView(name).mid(1, name.size() - 2));
195  }
196 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
197  const auto val = Grantlee::Variable(name).resolve(c);
198 #else
199  const auto val = KTextTemplate::Variable(name).resolve(c);
200 #endif
201  return val.value<QColor>();
202 }
203 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
204 void ColorMixNode::render(Grantlee::OutputStream *stream, Grantlee::Context *c) const
205 #else
206 void ColorMixNode::render(KTextTemplate::OutputStream *stream, KTextTemplate::Context *c) const
207 #endif
208 {
209  const auto col1 = resolveColor(m_color1Name, c);
210  const auto col2 = resolveColor(m_color2Name, c);
211  const auto result = KColorUtils::mix(col1, col2, m_ratio);
212  if (!m_varName.isEmpty()) {
213  c->insert(m_varName, QVariant::fromValue(result));
214  } else {
215  (*stream) << rgbaString(result);
216  }
217 }
QString number(int n, int base)
KGUIADDONS_EXPORT QColor mix(const QColor &c1, const QColor &c2, qreal bias=0.5)
QVariant fromValue(const T &value)
T value() const const
int red() const const
int toInt(bool *ok) const const
int green() const const
qreal alphaF() const const
bool canConvert(int targetTypeId) const const
int blue() const const
const QChar at(int position) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Sep 28 2022 04:06:59 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.