Extracted common code for radial and linear blob classes.
This commit is contained in:
parent
9735510195
commit
d032f4d8b5
10 changed files with 229 additions and 284 deletions
|
|
@ -71,8 +71,6 @@ PRIVATE
|
||||||
ui/layers/layer_widget.h
|
ui/layers/layer_widget.h
|
||||||
ui/paint/blob.cpp
|
ui/paint/blob.cpp
|
||||||
ui/paint/blob.h
|
ui/paint/blob.h
|
||||||
ui/paint/blob_linear.cpp
|
|
||||||
ui/paint/blob_linear.h
|
|
||||||
ui/paint/blobs.cpp
|
ui/paint/blobs.cpp
|
||||||
ui/paint/blobs.h
|
ui/paint/blobs.h
|
||||||
ui/paint/blobs_linear.cpp
|
ui/paint/blobs_linear.cpp
|
||||||
|
|
|
||||||
|
|
@ -19,24 +19,69 @@ namespace {
|
||||||
constexpr auto kMaxSpeed = 8.2;
|
constexpr auto kMaxSpeed = 8.2;
|
||||||
constexpr auto kMinSpeed = 0.8;
|
constexpr auto kMinSpeed = 0.8;
|
||||||
|
|
||||||
|
constexpr auto kMinSegmentSpeed = 0.017;
|
||||||
|
constexpr auto kSegmentSpeedDiff = 0.003;
|
||||||
|
|
||||||
float64 RandomAdditional() {
|
float64 RandomAdditional() {
|
||||||
return (openssl::RandomValue<int>() % 100 / 100.);
|
return (openssl::RandomValue<int>() % 100 / 100.);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
BlobBezier::BlobBezier(int n, float minScale, float minSpeed, float maxSpeed)
|
Blob::Blob(int n, float minSpeed, float maxSpeed)
|
||||||
: _segmentsCount(n)
|
: _segmentsCount(n)
|
||||||
, _segmentLength((4.0 / 3.0) * std::tan(M_PI / (2 * n)))
|
|
||||||
, _minScale(minScale)
|
|
||||||
, _minSpeed(minSpeed ? minSpeed : kMinSpeed)
|
, _minSpeed(minSpeed ? minSpeed : kMinSpeed)
|
||||||
, _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed)
|
, _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed)
|
||||||
, _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
|
, _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blob::generateBlob() {
|
||||||
|
for (auto i = 0; i < _segmentsCount; i++) {
|
||||||
|
generateSingleValues(i);
|
||||||
|
// Fill nexts.
|
||||||
|
generateTwoValues(i);
|
||||||
|
// Fill currents.
|
||||||
|
generateTwoValues(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blob::generateSingleValues(int i) {
|
||||||
|
auto &segment = segmentAt(i);
|
||||||
|
segment.progress = 0.;
|
||||||
|
segment.speed = kMinSegmentSpeed
|
||||||
|
+ kSegmentSpeedDiff * std::abs(RandomAdditional());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blob::update(float level, float speedScale) {
|
||||||
|
for (auto i = 0; i < _segmentsCount; i++) {
|
||||||
|
auto &segment = segmentAt(i);
|
||||||
|
segment.progress += (segment.speed * _minSpeed)
|
||||||
|
+ level * segment.speed * _maxSpeed * speedScale;
|
||||||
|
if (segment.progress >= 1) {
|
||||||
|
generateSingleValues(i);
|
||||||
|
generateTwoValues(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Blob::setRadiuses(Radiuses values) {
|
||||||
|
_radiuses = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
Blob::Radiuses Blob::radiuses() const {
|
||||||
|
return _radiuses;
|
||||||
|
}
|
||||||
|
|
||||||
|
RadialBlob::RadialBlob(int n, float minScale, float minSpeed, float maxSpeed)
|
||||||
|
: Blob(n, minSpeed, maxSpeed)
|
||||||
|
, _segmentLength((4.0 / 3.0) * std::tan(M_PI / (2 * n)))
|
||||||
|
, _minScale(minScale)
|
||||||
, _segmentAngle(360. / n)
|
, _segmentAngle(360. / n)
|
||||||
|
, _angleDiff(_segmentAngle * 0.05)
|
||||||
, _segments(n) {
|
, _segments(n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobBezier::paint(Painter &p, const QBrush &brush) {
|
void RadialBlob::paint(Painter &p, const QBrush &brush) {
|
||||||
auto path = QPainterPath();
|
auto path = QPainterPath();
|
||||||
auto m = QMatrix();
|
auto m = QMatrix();
|
||||||
|
|
||||||
|
|
@ -55,14 +100,14 @@ void BlobBezier::paint(Painter &p, const QBrush &brush) {
|
||||||
const auto progress = segment.progress;
|
const auto progress = segment.progress;
|
||||||
const auto progressNext = nextSegment.progress;
|
const auto progressNext = nextSegment.progress;
|
||||||
|
|
||||||
const auto r1 = segment.radius * (1. - progress)
|
const auto r1 = segment.radius.current * (1. - progress)
|
||||||
+ segment.radiusNext * progress;
|
+ segment.radius.next * progress;
|
||||||
const auto r2 = nextSegment.radius * (1. - progressNext)
|
const auto r2 = nextSegment.radius.current * (1. - progressNext)
|
||||||
+ nextSegment.radiusNext * progressNext;
|
+ nextSegment.radius.next * progressNext;
|
||||||
const auto angle1 = segment.angle * (1. - progress)
|
const auto angle1 = segment.angle.current * (1. - progress)
|
||||||
+ segment.angleNext * progress;
|
+ segment.angle.next * progress;
|
||||||
const auto angle2 = nextSegment.angle * (1. - progressNext)
|
const auto angle2 = nextSegment.angle.current * (1. - progressNext)
|
||||||
+ nextSegment.angleNext * progressNext;
|
+ nextSegment.angle.next * progressNext;
|
||||||
|
|
||||||
const auto l = _segmentLength * (std::min(r1, r2)
|
const auto l = _segmentLength * (std::min(r1, r2)
|
||||||
+ (std::max(r1, r2) - std::min(r1, r2)) / 2.);
|
+ (std::max(r1, r2) - std::min(r1, r2)) / 2.);
|
||||||
|
|
@ -94,45 +139,98 @@ void BlobBezier::paint(Painter &p, const QBrush &brush) {
|
||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobBezier::generateBlob() {
|
void RadialBlob::generateTwoValues(int i) {
|
||||||
for (auto i = 0; i < _segmentsCount; i++) {
|
auto &radius = _segments[i].radius;
|
||||||
auto &segment = _segments[i];
|
auto &angle = _segments[i].angle;
|
||||||
generateBlob(segment.radius, segment.angle, i);
|
|
||||||
generateBlob(segment.radiusNext, segment.angleNext, i);
|
|
||||||
segment.progress = 0.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlobBezier::generateBlob(float &radius, float &angle, int i) {
|
|
||||||
const auto angleDiff = _segmentAngle * 0.05;
|
|
||||||
const auto radDiff = _radiuses.max - _radiuses.min;
|
const auto radDiff = _radiuses.max - _radiuses.min;
|
||||||
|
|
||||||
radius = _radiuses.min + std::abs(RandomAdditional()) * radDiff;
|
angle.setNext(_segmentAngle * i + RandomAdditional() * _angleDiff);
|
||||||
angle = _segmentAngle * i + RandomAdditional() * angleDiff;
|
radius.setNext(_radiuses.min + std::abs(RandomAdditional()) * radDiff);
|
||||||
_segments[i].speed = 0.017 + 0.003 * std::abs(RandomAdditional());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobBezier::update(float level, float speedScale) {
|
void RadialBlob::update(float level, float speedScale) {
|
||||||
_scale = level;
|
_scale = level;
|
||||||
|
Blob::update(level, speedScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blob::Segment &RadialBlob::segmentAt(int i) {
|
||||||
|
return _segments[i];
|
||||||
|
};
|
||||||
|
|
||||||
|
LinearBlob::LinearBlob(
|
||||||
|
int n,
|
||||||
|
Direction direction,
|
||||||
|
float minSpeed,
|
||||||
|
float maxSpeed)
|
||||||
|
: Blob(n + 1)
|
||||||
|
, _topDown(direction == Direction::TopDown ? 1 : -1)
|
||||||
|
, _segments(_segmentsCount) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinearBlob::paint(Painter &p, const QBrush &brush, int width) {
|
||||||
|
auto path = QPainterPath();
|
||||||
|
|
||||||
|
const auto left = 0;
|
||||||
|
const auto right = width;
|
||||||
|
|
||||||
|
path.moveTo(right, 0);
|
||||||
|
path.lineTo(left, 0);
|
||||||
|
|
||||||
|
const auto n = float(_segmentsCount - 1);
|
||||||
|
|
||||||
|
p.save();
|
||||||
|
|
||||||
for (auto i = 0; i < _segmentsCount; i++) {
|
for (auto i = 0; i < _segmentsCount; i++) {
|
||||||
auto &segment = _segments[i];
|
const auto &segment = _segments[i];
|
||||||
segment.progress += (segment.speed * _minSpeed)
|
|
||||||
+ level * segment.speed * _maxSpeed * speedScale;
|
if (!i) {
|
||||||
if (segment.progress >= 1) {
|
const auto &progress = segment.progress;
|
||||||
segment.progress = 0.;
|
const auto r1 = segment.radius.current * (1. - progress)
|
||||||
segment.radius = segment.radiusNext;
|
+ segment.radius.next * progress;
|
||||||
segment.angle = segment.angleNext;
|
const auto y = r1 * _topDown;
|
||||||
generateBlob(segment.radiusNext, segment.angleNext, i);
|
path.lineTo(left, y);
|
||||||
|
} else {
|
||||||
|
const auto &prevSegment = _segments[i - 1];
|
||||||
|
const auto &progress = prevSegment.progress;
|
||||||
|
const auto r1 = prevSegment.radius.current * (1. - progress)
|
||||||
|
+ prevSegment.radius.next * progress;
|
||||||
|
|
||||||
|
const auto &progressNext = segment.progress;
|
||||||
|
const auto r2 = segment.radius.current * (1. - progressNext)
|
||||||
|
+ segment.radius.next * progressNext;
|
||||||
|
|
||||||
|
const auto x1 = (right - left) / n * (i - 1);
|
||||||
|
const auto x2 = (right - left) / n * i;
|
||||||
|
const auto cx = x1 + (x2 - x1) / 2;
|
||||||
|
|
||||||
|
const auto y1 = r1 * _topDown;
|
||||||
|
const auto y2 = r2 * _topDown;
|
||||||
|
path.cubicTo(
|
||||||
|
QPointF(cx, y1),
|
||||||
|
QPointF(cx, y2),
|
||||||
|
QPointF(x2, y2)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
path.lineTo(right, 0);
|
||||||
|
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.setPen(_pen);
|
||||||
|
p.fillPath(path, brush);
|
||||||
|
p.drawPath(path);
|
||||||
|
|
||||||
|
p.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobBezier::setRadiuses(Radiuses values) {
|
void LinearBlob::generateTwoValues(int i) {
|
||||||
_radiuses = values;
|
auto &radius = _segments[i].radius;
|
||||||
|
const auto radDiff = _radiuses.max - _radiuses.min;
|
||||||
|
radius.setNext(_radiuses.min + std::abs(RandomAdditional()) * radDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobBezier::Radiuses BlobBezier::radiuses() const {
|
Blob::Segment &LinearBlob::segmentAt(int i) {
|
||||||
return _radiuses;
|
return _segments[i];
|
||||||
}
|
};
|
||||||
|
|
||||||
} // namespace Ui::Paint
|
} // namespace Ui::Paint
|
||||||
|
|
|
||||||
|
|
@ -10,54 +10,103 @@ class Painter;
|
||||||
|
|
||||||
namespace Ui::Paint {
|
namespace Ui::Paint {
|
||||||
|
|
||||||
class BlobBezier final {
|
class Blob {
|
||||||
public:
|
public:
|
||||||
struct Radiuses {
|
struct Radiuses {
|
||||||
float min = 0.;
|
float min = 0.;
|
||||||
float max = 0.;
|
float max = 0.;
|
||||||
|
|
||||||
inline bool operator==(const Radiuses &other) const {
|
|
||||||
return (min == other.min) && (max == other.max);
|
|
||||||
}
|
|
||||||
inline bool operator!=(const Radiuses &other) const {
|
|
||||||
return !(min == other.min) && (max == other.max);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BlobBezier(int n, float minScale, float minSpeed = 0, float maxSpeed = 0);
|
Blob(int n, float minSpeed = 0, float maxSpeed = 0);
|
||||||
|
|
||||||
void paint(Painter &p, const QBrush &brush);
|
|
||||||
void update(float level, float speedScale);
|
void update(float level, float speedScale);
|
||||||
void generateBlob();
|
void generateBlob();
|
||||||
|
|
||||||
void setRadiuses(Radiuses values);
|
void setRadiuses(Radiuses values);
|
||||||
Radiuses radiuses() const;
|
[[nodiscard]] Radiuses radiuses() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct TwoValues {
|
||||||
|
float current = 0.;
|
||||||
|
float next = 0.;
|
||||||
|
void setNext(float v) {
|
||||||
|
current = next;
|
||||||
|
next = v;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
struct Segment {
|
struct Segment {
|
||||||
float radius = 0.;
|
|
||||||
float angle = 0.;
|
|
||||||
float radiusNext = 0.;
|
|
||||||
float angleNext = 0.;
|
|
||||||
float progress = 0.;
|
float progress = 0.;
|
||||||
float speed = 0.;
|
float speed = 0.;
|
||||||
};
|
};
|
||||||
|
|
||||||
void generateBlob(float &radius, float &angle, int i);
|
void generateSingleValues(int i);
|
||||||
|
virtual void generateTwoValues(int i) = 0;
|
||||||
|
virtual Segment &segmentAt(int i) = 0;
|
||||||
|
|
||||||
const int _segmentsCount;
|
const int _segmentsCount;
|
||||||
const float64 _segmentLength;
|
|
||||||
const float _minScale;
|
|
||||||
const float _minSpeed;
|
const float _minSpeed;
|
||||||
const float _maxSpeed;
|
const float _maxSpeed;
|
||||||
const QPen _pen;
|
const QPen _pen;
|
||||||
const float _segmentAngle;
|
|
||||||
|
|
||||||
std::vector<Segment> _segments;
|
|
||||||
|
|
||||||
float64 _scale = 0;
|
|
||||||
Radiuses _radiuses;
|
Radiuses _radiuses;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RadialBlob final : public Blob {
|
||||||
|
public:
|
||||||
|
RadialBlob(int n, float minScale, float minSpeed = 0, float maxSpeed = 0);
|
||||||
|
|
||||||
|
void paint(Painter &p, const QBrush &brush);
|
||||||
|
void update(float level, float speedScale);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Segment : Blob::Segment {
|
||||||
|
Blob::TwoValues radius;
|
||||||
|
Blob::TwoValues angle;
|
||||||
|
};
|
||||||
|
|
||||||
|
void generateTwoValues(int i) override;
|
||||||
|
Blob::Segment &segmentAt(int i) override;
|
||||||
|
|
||||||
|
const float64 _segmentLength;
|
||||||
|
const float _minScale;
|
||||||
|
const float _segmentAngle;
|
||||||
|
const float _angleDiff;
|
||||||
|
|
||||||
|
std::vector<Segment> _segments;
|
||||||
|
|
||||||
|
float64 _scale = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class LinearBlob final : public Blob {
|
||||||
|
public:
|
||||||
|
enum class Direction {
|
||||||
|
TopDown,
|
||||||
|
BottomUp,
|
||||||
|
};
|
||||||
|
|
||||||
|
LinearBlob(
|
||||||
|
int n,
|
||||||
|
Direction direction = Direction::TopDown,
|
||||||
|
float minSpeed = 0,
|
||||||
|
float maxSpeed = 0);
|
||||||
|
|
||||||
|
void paint(Painter &p, const QBrush &brush, int width);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Segment : Blob::Segment {
|
||||||
|
Blob::TwoValues radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
void generateTwoValues(int i) override;
|
||||||
|
Blob::Segment &segmentAt(int i) override;
|
||||||
|
|
||||||
|
const int _topDown;
|
||||||
|
|
||||||
|
std::vector<Segment> _segments;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Ui::Paint
|
} // namespace Ui::Paint
|
||||||
|
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
// This file is part of Desktop App Toolkit,
|
|
||||||
// a set of libraries for developing nice desktop applications.
|
|
||||||
//
|
|
||||||
// For license and copyright information please follow this link:
|
|
||||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
||||||
//
|
|
||||||
#include "ui/paint/blob_linear.h"
|
|
||||||
|
|
||||||
#include "base/openssl_help.h"
|
|
||||||
#include "ui/painter.h"
|
|
||||||
|
|
||||||
#include <QtGui/QPainterPath>
|
|
||||||
|
|
||||||
namespace Ui::Paint {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr auto kMaxSpeed = 8.2;
|
|
||||||
constexpr auto kMinSpeed = 0.8;
|
|
||||||
|
|
||||||
float64 RandomAdditional() {
|
|
||||||
return (openssl::RandomValue<int>() % 100 / 100.);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
LinearBlobBezier::LinearBlobBezier(
|
|
||||||
int n,
|
|
||||||
Direction direction,
|
|
||||||
float minSpeed,
|
|
||||||
float maxSpeed)
|
|
||||||
: _segmentsCount(n)
|
|
||||||
, _minSpeed(minSpeed ? minSpeed : kMinSpeed)
|
|
||||||
, _maxSpeed(maxSpeed ? maxSpeed : kMaxSpeed)
|
|
||||||
, _pen(Qt::NoBrush, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)
|
|
||||||
, _topDown(direction == Direction::TopDown ? 1 : -1)
|
|
||||||
, _segments(n + 1) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearBlobBezier::paint(Painter &p, const QBrush &brush, int width) {
|
|
||||||
auto path = QPainterPath();
|
|
||||||
|
|
||||||
const auto left = 0;
|
|
||||||
const auto right = width;
|
|
||||||
|
|
||||||
path.moveTo(right, 0);
|
|
||||||
path.lineTo(left, 0);
|
|
||||||
|
|
||||||
const auto &n = _segmentsCount;
|
|
||||||
|
|
||||||
p.save();
|
|
||||||
|
|
||||||
for (auto i = 0; i <= n; i++) {
|
|
||||||
const auto &segment = _segments[i];
|
|
||||||
|
|
||||||
if (!i) {
|
|
||||||
const auto progress = segment.progress;
|
|
||||||
const auto r1 = segment.radius * (1. - progress)
|
|
||||||
+ segment.radiusNext * progress;
|
|
||||||
const auto y = r1 * _topDown;
|
|
||||||
path.lineTo(left, y);
|
|
||||||
} else {
|
|
||||||
const auto &prevSegment = _segments[i - 1];
|
|
||||||
const auto &progress = prevSegment.progress;
|
|
||||||
const auto r1 = prevSegment.radius * (1. - progress)
|
|
||||||
+ prevSegment.radiusNext * progress;
|
|
||||||
|
|
||||||
const auto &progressNext = segment.progress;
|
|
||||||
const auto r2 = segment.radius * (1. - progressNext)
|
|
||||||
+ segment.radiusNext * progressNext;
|
|
||||||
|
|
||||||
const auto x1 = (right - left) / n * (i - 1);
|
|
||||||
const auto x2 = (right - left) / n * i;
|
|
||||||
const auto cx = x1 + (x2 - x1) / 2;
|
|
||||||
|
|
||||||
const auto y1 = r1 * _topDown;
|
|
||||||
const auto y2 = r2 * _topDown;
|
|
||||||
path.cubicTo(
|
|
||||||
QPointF(cx, y1),
|
|
||||||
QPointF(cx, y2),
|
|
||||||
QPointF(x2, y2)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path.lineTo(right, 0);
|
|
||||||
|
|
||||||
p.setBrush(Qt::NoBrush);
|
|
||||||
p.setPen(_pen);
|
|
||||||
p.fillPath(path, brush);
|
|
||||||
p.drawPath(path);
|
|
||||||
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearBlobBezier::generateBlob() {
|
|
||||||
for (auto i = 0; i < _segmentsCount; i++) {
|
|
||||||
auto &segment = _segments[i];
|
|
||||||
generateBlob(segment.radius, i);
|
|
||||||
generateBlob(segment.radiusNext, i);
|
|
||||||
segment.progress = 0.;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearBlobBezier::generateBlob(float &radius, int i) {
|
|
||||||
const auto radDiff = _radiuses.max - _radiuses.min;
|
|
||||||
|
|
||||||
radius = _radiuses.min + std::abs(RandomAdditional()) * radDiff;
|
|
||||||
_segments[i].speed = 0.017 + 0.003 * std::abs(RandomAdditional());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearBlobBezier::update(float level, float speedScale) {
|
|
||||||
for (auto i = 0; i < _segmentsCount; i++) {
|
|
||||||
auto &segment = _segments[i];
|
|
||||||
segment.progress += (segment.speed * _minSpeed)
|
|
||||||
+ level * segment.speed * _maxSpeed * speedScale;
|
|
||||||
if (segment.progress >= 1) {
|
|
||||||
segment.progress = 0.;
|
|
||||||
segment.radius = segment.radiusNext;
|
|
||||||
generateBlob(segment.radiusNext, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinearBlobBezier::setRadiuses(Radiuses values) {
|
|
||||||
_radiuses = values;
|
|
||||||
}
|
|
||||||
|
|
||||||
LinearBlobBezier::Radiuses LinearBlobBezier::radiuses() const {
|
|
||||||
return _radiuses;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Ui::Paint
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
// This file is part of Desktop App Toolkit,
|
|
||||||
// a set of libraries for developing nice desktop applications.
|
|
||||||
//
|
|
||||||
// For license and copyright information please follow this link:
|
|
||||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
||||||
//
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class Painter;
|
|
||||||
|
|
||||||
namespace Ui::Paint {
|
|
||||||
|
|
||||||
class LinearBlobBezier final {
|
|
||||||
public:
|
|
||||||
enum class Direction {
|
|
||||||
TopDown,
|
|
||||||
BottomUp,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Radiuses {
|
|
||||||
float min = 0.;
|
|
||||||
float max = 0.;
|
|
||||||
|
|
||||||
inline bool operator==(const Radiuses &other) const {
|
|
||||||
return (min == other.min) && (max == other.max);
|
|
||||||
}
|
|
||||||
inline bool operator!=(const Radiuses &other) const {
|
|
||||||
return !(min == other.min) && (max == other.max);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LinearBlobBezier(
|
|
||||||
int n,
|
|
||||||
Direction direction = Direction::TopDown,
|
|
||||||
float minSpeed = 0,
|
|
||||||
float maxSpeed = 0);
|
|
||||||
|
|
||||||
void paint(Painter &p, const QBrush &brush, int width);
|
|
||||||
void update(float level, float speedScale);
|
|
||||||
void generateBlob();
|
|
||||||
|
|
||||||
void setRadiuses(Radiuses values);
|
|
||||||
Radiuses radiuses() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Segment {
|
|
||||||
float radius = 0.;
|
|
||||||
float radiusNext = 0.;
|
|
||||||
float progress = 0.;
|
|
||||||
float speed = 0.;
|
|
||||||
};
|
|
||||||
|
|
||||||
void generateBlob(float &radius, int i);
|
|
||||||
|
|
||||||
const int _segmentsCount;
|
|
||||||
const float _minSpeed;
|
|
||||||
const float _maxSpeed;
|
|
||||||
const QPen _pen;
|
|
||||||
const int _topDown;
|
|
||||||
|
|
||||||
std::vector<Segment> _segments;
|
|
||||||
|
|
||||||
Radiuses _radiuses;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Ui::Paint
|
|
||||||
|
|
@ -22,7 +22,7 @@ Blobs::Blobs(
|
||||||
|
|
||||||
void Blobs::init() {
|
void Blobs::init() {
|
||||||
for (const auto &data : _blobDatas) {
|
for (const auto &data : _blobDatas) {
|
||||||
auto blob = Paint::BlobBezier(data.segmentsCount, data.minScale);
|
auto blob = Paint::RadialBlob(data.segmentsCount, data.minScale);
|
||||||
blob.setRadiuses({ data.minRadius, data.maxRadius });
|
blob.setRadiuses({ data.minRadius, data.maxRadius });
|
||||||
blob.generateBlob();
|
blob.generateBlob();
|
||||||
_blobs.push_back(std::move(blob));
|
_blobs.push_back(std::move(blob));
|
||||||
|
|
@ -45,17 +45,17 @@ int Blobs::size() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blobs::setRadiusesAt(
|
void Blobs::setRadiusesAt(
|
||||||
rpl::producer<BlobBezier::Radiuses> &&radiuses,
|
rpl::producer<Blob::Radiuses> &&radiuses,
|
||||||
int index) {
|
int index) {
|
||||||
Expects(index >= 0 && index < size());
|
Expects(index >= 0 && index < size());
|
||||||
std::move(
|
std::move(
|
||||||
radiuses
|
radiuses
|
||||||
) | rpl::start_with_next([=](BlobBezier::Radiuses r) {
|
) | rpl::start_with_next([=](Blob::Radiuses r) {
|
||||||
_blobs[index].setRadiuses(std::move(r));
|
_blobs[index].setRadiuses(std::move(r));
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobBezier::Radiuses Blobs::radiusesAt(int index) {
|
Blob::Radiuses Blobs::radiusesAt(int index) {
|
||||||
Expects(index >= 0 && index < size());
|
Expects(index >= 0 && index < size());
|
||||||
return _blobs[index].radiuses();
|
return _blobs[index].radiuses();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ public:
|
||||||
float maxLevel);
|
float maxLevel);
|
||||||
|
|
||||||
void setRadiusesAt(
|
void setRadiusesAt(
|
||||||
rpl::producer<BlobBezier::Radiuses> &&radiuses,
|
rpl::producer<Blob::Radiuses> &&radiuses,
|
||||||
int index);
|
int index);
|
||||||
BlobBezier::Radiuses radiusesAt(int index);
|
Blob::Radiuses radiusesAt(int index);
|
||||||
|
|
||||||
void setLevel(float value);
|
void setLevel(float value);
|
||||||
void paint(Painter &p, const QBrush &brush);
|
void paint(Painter &p, const QBrush &brush);
|
||||||
|
|
@ -50,7 +50,7 @@ private:
|
||||||
const float _maxLevel;
|
const float _maxLevel;
|
||||||
|
|
||||||
std::vector<BlobData> _blobDatas;
|
std::vector<BlobData> _blobDatas;
|
||||||
std::vector<BlobBezier> _blobs;
|
std::vector<RadialBlob> _blobs;
|
||||||
|
|
||||||
anim::continuous_value _levelValue;
|
anim::continuous_value _levelValue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ LinearBlobs::LinearBlobs(
|
||||||
std::vector<BlobData> blobDatas,
|
std::vector<BlobData> blobDatas,
|
||||||
float levelDuration,
|
float levelDuration,
|
||||||
float maxLevel,
|
float maxLevel,
|
||||||
LinearBlobBezier::Direction direction)
|
LinearBlob::Direction direction)
|
||||||
: _maxLevel(maxLevel)
|
: _maxLevel(maxLevel)
|
||||||
, _direction(direction)
|
, _direction(direction)
|
||||||
, _blobDatas(std::move(blobDatas))
|
, _blobDatas(std::move(blobDatas))
|
||||||
|
|
@ -24,7 +24,7 @@ LinearBlobs::LinearBlobs(
|
||||||
|
|
||||||
void LinearBlobs::init() {
|
void LinearBlobs::init() {
|
||||||
for (const auto &data : _blobDatas) {
|
for (const auto &data : _blobDatas) {
|
||||||
auto blob = Paint::LinearBlobBezier(
|
auto blob = Paint::LinearBlob(
|
||||||
data.segmentsCount,
|
data.segmentsCount,
|
||||||
_direction);
|
_direction);
|
||||||
blob.setRadiuses({ data.minRadius, data.idleRadius });
|
blob.setRadiuses({ data.minRadius, data.idleRadius });
|
||||||
|
|
@ -49,17 +49,17 @@ int LinearBlobs::size() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinearBlobs::setRadiusesAt(
|
void LinearBlobs::setRadiusesAt(
|
||||||
rpl::producer<LinearBlobBezier::Radiuses> &&radiuses,
|
rpl::producer<Blob::Radiuses> &&radiuses,
|
||||||
int index) {
|
int index) {
|
||||||
Expects(index >= 0 && index < size());
|
Expects(index >= 0 && index < size());
|
||||||
std::move(
|
std::move(
|
||||||
radiuses
|
radiuses
|
||||||
) | rpl::start_with_next([=](LinearBlobBezier::Radiuses r) {
|
) | rpl::start_with_next([=](Blob::Radiuses r) {
|
||||||
_blobs[index].setRadiuses(std::move(r));
|
_blobs[index].setRadiuses(std::move(r));
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
LinearBlobBezier::Radiuses LinearBlobs::radiusesAt(int index) {
|
Blob::Radiuses LinearBlobs::radiusesAt(int index) {
|
||||||
Expects(index >= 0 && index < size());
|
Expects(index >= 0 && index < size());
|
||||||
return _blobs[index].radiuses();
|
return _blobs[index].radiuses();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/effects/animation_value.h"
|
#include "ui/effects/animation_value.h"
|
||||||
#include "ui/paint/blob_linear.h"
|
#include "ui/paint/blob.h"
|
||||||
|
|
||||||
class Painter;
|
class Painter;
|
||||||
|
|
||||||
|
|
@ -22,19 +22,18 @@ public:
|
||||||
float idleRadius = 0;
|
float idleRadius = 0;
|
||||||
float speedScale = 0;
|
float speedScale = 0;
|
||||||
float alpha = 0;
|
float alpha = 0;
|
||||||
int topOffset = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
LinearBlobs(
|
LinearBlobs(
|
||||||
std::vector<BlobData> blobDatas,
|
std::vector<BlobData> blobDatas,
|
||||||
float levelDuration,
|
float levelDuration,
|
||||||
float maxLevel,
|
float maxLevel,
|
||||||
LinearBlobBezier::Direction direction);
|
LinearBlob::Direction direction);
|
||||||
|
|
||||||
void setRadiusesAt(
|
void setRadiusesAt(
|
||||||
rpl::producer<LinearBlobBezier::Radiuses> &&radiuses,
|
rpl::producer<Blob::Radiuses> &&radiuses,
|
||||||
int index);
|
int index);
|
||||||
LinearBlobBezier::Radiuses radiusesAt(int index);
|
Blob::Radiuses radiusesAt(int index);
|
||||||
|
|
||||||
void setLevel(float value);
|
void setLevel(float value);
|
||||||
void paint(Painter &p, const QBrush &brush, int width);
|
void paint(Painter &p, const QBrush &brush, int width);
|
||||||
|
|
@ -50,10 +49,10 @@ private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
const float _maxLevel;
|
const float _maxLevel;
|
||||||
const LinearBlobBezier::Direction _direction;
|
const LinearBlob::Direction _direction;
|
||||||
|
|
||||||
std::vector<BlobData> _blobDatas;
|
std::vector<BlobData> _blobDatas;
|
||||||
std::vector<LinearBlobBezier> _blobs;
|
std::vector<LinearBlob> _blobs;
|
||||||
|
|
||||||
anim::continuous_value _levelValue;
|
anim::continuous_value _levelValue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Ui {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using Radiuses = Paint::BlobBezier::Radiuses;
|
using Radiuses = Paint::Blob::Radiuses;
|
||||||
|
|
||||||
constexpr auto kMaxLevel = 1.;
|
constexpr auto kMaxLevel = 1.;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue