Added ability to pass QGradientStops to gradients.

This commit is contained in:
23rd 2020-12-16 08:48:38 +03:00
parent 5e3897fcff
commit 967b18290c

View file

@ -14,14 +14,47 @@
namespace anim { namespace anim {
struct gradient_colors {
explicit gradient_colors(QColor color) {
stops.push_back({ 0., color });
stops.push_back({ 1., color });
}
explicit gradient_colors(std::vector<QColor> colors) {
if (colors.size() == 1) {
gradient_colors(colors.front());
return;
}
const auto last = float(colors.size() - 1);
for (auto i = 0; i < colors.size(); i++) {
stops.push_back({ i / last, std::move(colors[i]) });
}
}
explicit gradient_colors(QGradientStops colors)
: stops(std::move(colors)) {
}
QGradientStops stops;
};
namespace details { namespace details {
template <typename T, typename Derived> template <typename T, typename Derived>
class gradients { class gradients {
public: public:
gradients(base::flat_map<T, std::vector<QColor>> colors) gradients(base::flat_map<T, std::vector<QColor>> colors) {
: _colors(colors) { Expects(colors.size() > 0);
Expects(_colors.size() > 0);
for (const auto &[key, value] : colors) {
auto c = gradient_colors(std::move(value));
_gradients.emplace(key, gradient_with_stops(std::move(c.stops)));
}
}
gradients(base::flat_map<T, gradient_colors> colors) {
Expects(colors.size() > 0);
for (const auto &[key, c] : colors) {
_gradients.emplace(key, gradient_with_stops(std::move(c.stops)));
}
} }
QGradient gradient(T state1, T state2, float64 b_ratio) const { QGradient gradient(T state1, T state2, float64 b_ratio) const {
@ -31,16 +64,20 @@ public:
return _gradients.find(state2)->second; return _gradients.find(state2)->second;
} }
auto gradient = static_cast<const Derived*>(this)->empty_gradient(); auto gradient = empty_gradient();
const auto size = _colors.front().second.size(); const auto gradient1 = _gradients.find(state1);
const auto colors1 = _colors.find(state1); const auto gradient2 = _gradients.find(state2);
const auto colors2 = _colors.find(state2);
Assert(colors1 != end(_colors)); Assert(gradient1 != end(_gradients));
Assert(colors2 != end(_colors)); Assert(gradient2 != end(_gradients));
const auto stops1 = gradient1->second.stops();
const auto stops2 = gradient2->second.stops();
const auto size = stops1.size();
for (auto i = 0; i < size; i++) { for (auto i = 0; i < size; i++) {
auto c = color(colors1->second[i], colors2->second[i], b_ratio); auto c = color(stops1[i].second, stops2[i].second, b_ratio);
gradient.setColorAt(i / (size - 1), std::move(c)); gradient.setColorAt(i / (size - 1), std::move(c));
} }
return gradient; return gradient;
@ -48,23 +85,22 @@ public:
protected: protected:
void cache_gradients() { void cache_gradients() {
_gradients = base::flat_map<T, QGradient>(); auto copy = std::move(_gradients);
for (const auto &[key, value] : _colors) { for (const auto &[key, value] : copy) {
_gradients.emplace(key, gradient(value)); _gradients.emplace(key, gradient_with_stops(value.stops()));
} }
} }
private: private:
QGradient gradient(const std::vector<QColor> &colors) const { QGradient empty_gradient() const {
auto gradient = static_cast<const Derived*>(this)->empty_gradient(); return static_cast<const Derived*>(this)->empty_gradient();
const auto size = colors.size(); }
for (auto i = 0; i < size; i++) { QGradient gradient_with_stops(QGradientStops stops) const {
gradient.setColorAt(i / (size - 1), colors[i]); auto gradient = empty_gradient();
} gradient.setStops(std::move(stops));
return gradient; return gradient;
} }
base::flat_map<T, std::vector<QColor>> _colors;
base::flat_map<T, QGradient> _gradients; base::flat_map<T, QGradient> _gradients;
}; };
@ -84,6 +120,13 @@ public:
: parent(std::move(colors)) { : parent(std::move(colors)) {
set_points(point1, point2); set_points(point1, point2);
} }
linear_gradients(
base::flat_map<T, gradient_colors> colors,
QPointF point1,
QPointF point2)
: parent(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) {
@ -119,6 +162,13 @@ public:
: parent(std::move(colors)) { : parent(std::move(colors)) {
set_points(center, radius); set_points(center, radius);
} }
radial_gradients(
base::flat_map<T, gradient_colors> colors,
QPointF center,
float radius)
: parent(std::move(colors)) {
set_points(center, radius);
}
void set_points(QPointF center, float radius) { void set_points(QPointF center, float radius) {
if (_center == center && _radius == radius) { if (_center == center && _radius == radius) {