Extracted common code for gradient classes.
This commit is contained in:
parent
d032f4d8b5
commit
d61e1a7bde
1 changed files with 53 additions and 177 deletions
|
|
@ -14,78 +14,24 @@
|
||||||
|
|
||||||
namespace anim {
|
namespace anim {
|
||||||
|
|
||||||
class linear_gradient {
|
namespace details {
|
||||||
public:
|
|
||||||
linear_gradient(
|
|
||||||
std::vector<QColor> colors_from,
|
|
||||||
std::vector<QColor> colors_to,
|
|
||||||
QPointF point1,
|
|
||||||
QPointF point2)
|
|
||||||
: _colors_from(colors_from)
|
|
||||||
, _colors_to(colors_to)
|
|
||||||
, _point1(point1)
|
|
||||||
, _point2(point2)
|
|
||||||
, _gradient_from(gradient(colors_from))
|
|
||||||
, _gradient_to(gradient(colors_to)) {
|
|
||||||
Expects(colors_from.size() == colors_to.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
QLinearGradient gradient(float64 b_ratio) const {
|
|
||||||
if (b_ratio == 0.) {
|
|
||||||
return _gradient_from;
|
|
||||||
} else if (b_ratio == 1.) {
|
|
||||||
return _gradient_to;
|
|
||||||
}
|
|
||||||
auto colors = std::vector<QColor>(_colors_to.size());
|
|
||||||
for (auto i = 0; i < colors.size(); i++) {
|
|
||||||
colors[i] = color(_colors_from[i], _colors_to[i], b_ratio);
|
|
||||||
}
|
|
||||||
return gradient(colors);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QLinearGradient gradient(const std::vector<QColor> &colors) const {
|
|
||||||
auto gradient = QLinearGradient(_point1, _point2);
|
|
||||||
const auto size = colors.size();
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
gradient.setColorAt(i / (size - 1), colors[i]);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QColor> _colors_from;
|
|
||||||
std::vector<QColor> _colors_to;
|
|
||||||
QPointF _point1;
|
|
||||||
QPointF _point2;
|
|
||||||
|
|
||||||
QLinearGradient _gradient_from;
|
|
||||||
QLinearGradient _gradient_to;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class linear_gradients {
|
class gradients {
|
||||||
public:
|
public:
|
||||||
linear_gradients(
|
gradients(base::flat_map<T, std::vector<QColor>> colors)
|
||||||
base::flat_map<T, std::vector<QColor>> colors,
|
: _colors(colors) {
|
||||||
QPointF point1,
|
|
||||||
QPointF point2)
|
|
||||||
: _colors(colors)
|
|
||||||
, _point1(point1)
|
|
||||||
, _point2(point2) {
|
|
||||||
Expects(_colors.size() > 0);
|
Expects(_colors.size() > 0);
|
||||||
|
|
||||||
cache_gradients();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QLinearGradient gradient(T state1, T state2, float64 b_ratio) const {
|
QGradient gradient(T state1, T state2, float64 b_ratio) const {
|
||||||
if (b_ratio == 0.) {
|
if (b_ratio == 0.) {
|
||||||
return _gradients.find(state1)->second;
|
return _gradients.find(state1)->second;
|
||||||
} else if (b_ratio == 1.) {
|
} else if (b_ratio == 1.) {
|
||||||
return _gradients.find(state2)->second;
|
return _gradients.find(state2)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gradient = QLinearGradient(_point1, _point2);
|
auto gradient = empty_gradient();
|
||||||
const auto size = _colors.front().second.size();
|
const auto size = _colors.front().second.size();
|
||||||
const auto colors1 = _colors.find(state1);
|
const auto colors1 = _colors.find(state1);
|
||||||
const auto colors2 = _colors.find(state2);
|
const auto colors2 = _colors.find(state2);
|
||||||
|
|
@ -100,124 +46,70 @@ public:
|
||||||
return gradient;
|
return gradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QGradient empty_gradient() const = 0;
|
||||||
|
|
||||||
|
void cache_gradients() {
|
||||||
|
_gradients = base::flat_map<T, QGradient>();
|
||||||
|
for (const auto &[key, value] : _colors) {
|
||||||
|
_gradients.emplace(key, gradient(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QGradient gradient(const std::vector<QColor> &colors) const {
|
||||||
|
auto gradient = empty_gradient();
|
||||||
|
const auto size = colors.size();
|
||||||
|
for (auto i = 0; i < size; i++) {
|
||||||
|
gradient.setColorAt(i / (size - 1), colors[i]);
|
||||||
|
}
|
||||||
|
return gradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
base::flat_map<T, std::vector<QColor>> _colors;
|
||||||
|
base::flat_map<T, QGradient> _gradients;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace details
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class linear_gradients final : public details::gradients<T> {
|
||||||
|
public:
|
||||||
|
linear_gradients(
|
||||||
|
base::flat_map<T, std::vector<QColor>> colors,
|
||||||
|
QPointF point1,
|
||||||
|
QPointF point2)
|
||||||
|
: details::gradients<T>(std::move(colors)) {
|
||||||
|
set_points(point1, point2);
|
||||||
|
}
|
||||||
|
|
||||||
void set_points(QPointF point1, QPointF point2) {
|
void set_points(QPointF point1, QPointF point2) {
|
||||||
if (_point1 == point1 && _point2 == point2) {
|
if (_point1 == point1 && _point2 == point2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_point1 = point1;
|
_point1 = point1;
|
||||||
_point2 = point2;
|
_point2 = point2;
|
||||||
cache_gradients();
|
details::gradients<T>::cache_gradients();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cache_gradients() {
|
QGradient empty_gradient() const override {
|
||||||
_gradients = base::flat_map<T, QLinearGradient>();
|
return QLinearGradient(_point1, _point2);
|
||||||
for (const auto &[key, value] : _colors) {
|
|
||||||
_gradients.emplace(key, gradient(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QLinearGradient gradient(const std::vector<QColor> &colors) const {
|
|
||||||
auto gradient = QLinearGradient(_point1, _point2);
|
|
||||||
const auto size = colors.size();
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
gradient.setColorAt(i / (size - 1), colors[i]);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::flat_map<T, std::vector<QColor>> _colors;
|
|
||||||
QPointF _point1;
|
QPointF _point1;
|
||||||
QPointF _point2;
|
QPointF _point2;
|
||||||
|
|
||||||
base::flat_map<T, QLinearGradient> _gradients;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class radial_gradient {
|
|
||||||
public:
|
|
||||||
radial_gradient(
|
|
||||||
std::vector<QColor> colors_from,
|
|
||||||
std::vector<QColor> colors_to,
|
|
||||||
QPointF center,
|
|
||||||
float radius)
|
|
||||||
: _colors_from(colors_from)
|
|
||||||
, _colors_to(colors_to)
|
|
||||||
, _center(center)
|
|
||||||
, _radius(radius)
|
|
||||||
, _gradient_from(gradient(colors_from))
|
|
||||||
, _gradient_to(gradient(colors_to)) {
|
|
||||||
Expects(colors_from.size() == colors_to.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
QRadialGradient gradient(float64 b_ratio) const {
|
|
||||||
if (b_ratio == 0.) {
|
|
||||||
return _gradient_from;
|
|
||||||
} else if (b_ratio == 1.) {
|
|
||||||
return _gradient_to;
|
|
||||||
}
|
|
||||||
auto colors = std::vector<QColor>(_colors_to.size());
|
|
||||||
for (auto i = 0; i < colors.size(); i++) {
|
|
||||||
colors[i] = color(_colors_from[i], _colors_to[i], b_ratio);
|
|
||||||
}
|
|
||||||
return gradient(colors);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QRadialGradient gradient(const std::vector<QColor> &colors) const {
|
|
||||||
auto gradient = QRadialGradient(_center, _radius);
|
|
||||||
const auto size = colors.size();
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
gradient.setColorAt(i / (size - 1), colors[i]);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QColor> _colors_from;
|
|
||||||
std::vector<QColor> _colors_to;
|
|
||||||
QPointF _center;
|
|
||||||
float _radius;
|
|
||||||
|
|
||||||
QRadialGradient _gradient_from;
|
|
||||||
QRadialGradient _gradient_to;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class radial_gradients {
|
class radial_gradients final : public details::gradients<T> {
|
||||||
public:
|
public:
|
||||||
radial_gradients(
|
radial_gradients(
|
||||||
base::flat_map<T, std::vector<QColor>> colors,
|
base::flat_map<T, std::vector<QColor>> colors,
|
||||||
QPointF center,
|
QPointF center,
|
||||||
float radius)
|
float radius)
|
||||||
: _colors(colors)
|
: details::gradients<T>(std::move(colors)) {
|
||||||
, _center(center)
|
set_points(center, radius);
|
||||||
, _radius(radius) {
|
|
||||||
Expects(_colors.size() > 0);
|
|
||||||
|
|
||||||
cache_gradients();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRadialGradient gradient(T state1, T state2, float64 b_ratio) const {
|
|
||||||
if (b_ratio == 0.) {
|
|
||||||
return _gradients.find(state1)->second;
|
|
||||||
} else if (b_ratio == 1.) {
|
|
||||||
return _gradients.find(state2)->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto gradient = QRadialGradient(_center, _radius);
|
|
||||||
const auto size = _colors.front().second.size();
|
|
||||||
const auto colors1 = _colors.find(state1);
|
|
||||||
const auto colors2 = _colors.find(state2);
|
|
||||||
|
|
||||||
Assert(colors1 != end(_colors));
|
|
||||||
Assert(colors2 != end(_colors));
|
|
||||||
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
auto c = color(colors1->second[i], colors2->second[i], b_ratio);
|
|
||||||
gradient.setColorAt(i / (size - 1), std::move(c));
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_points(QPointF center, float radius) {
|
void set_points(QPointF center, float radius) {
|
||||||
|
|
@ -226,32 +118,16 @@ public:
|
||||||
}
|
}
|
||||||
_center = center;
|
_center = center;
|
||||||
_radius = radius;
|
_radius = radius;
|
||||||
cache_gradients();
|
details::gradients<T>::cache_gradients();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void cache_gradients() {
|
QGradient empty_gradient() const override {
|
||||||
_gradients = base::flat_map<T, QRadialGradient>();
|
return QRadialGradient(_center, _radius);
|
||||||
for (const auto &[key, value] : _colors) {
|
|
||||||
_gradients.emplace(key, gradient(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRadialGradient gradient(const std::vector<QColor> &colors) const {
|
|
||||||
auto gradient = QRadialGradient(_center, _radius);
|
|
||||||
const auto size = colors.size();
|
|
||||||
for (auto i = 0; i < size; i++) {
|
|
||||||
gradient.setColorAt(i / (size - 1), colors[i]);
|
|
||||||
}
|
|
||||||
return gradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
base::flat_map<T, std::vector<QColor>> _colors;
|
|
||||||
QPointF _center;
|
QPointF _center;
|
||||||
float _radius;
|
float _radius = 0.;
|
||||||
|
|
||||||
base::flat_map<T, QRadialGradient> _gradients;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace anim
|
} // namespace anim
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue