| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- // 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/blobs_linear.h"
- #include "ui/painter.h"
- namespace Ui::Paint {
- namespace {
- constexpr auto kRateLimitF = 1000. / 60.;
- constexpr auto kRateLimit = int(kRateLimitF + 0.5); // Round.
- } // namespace
- LinearBlobs::LinearBlobs(
- std::vector<BlobData> blobDatas,
- float levelDuration,
- float maxLevel,
- LinearBlob::Direction direction)
- : _maxLevel(maxLevel)
- , _direction(direction)
- , _blobDatas(std::move(blobDatas))
- , _levelValue(levelDuration) {
- init();
- }
- void LinearBlobs::init() {
- for (const auto &data : _blobDatas) {
- auto blob = Paint::LinearBlob(
- data.segmentsCount,
- _direction,
- data.minSpeed,
- data.maxSpeed);
- blob.setRadiuses({ data.minRadius, data.idleRadius });
- blob.generateBlob();
- _blobs.push_back(std::move(blob));
- }
- }
- float LinearBlobs::maxRadius() const {
- const auto maxOfRadiuses = [](const BlobData &d) {
- return std::max(d.idleRadius, std::max(d.maxRadius, d.minRadius));
- };
- const auto max = *ranges::max_element(
- _blobDatas,
- std::less<>(),
- maxOfRadiuses);
- return maxOfRadiuses(max);
- }
- int LinearBlobs::size() const {
- return _blobs.size();
- }
- void LinearBlobs::setRadiusesAt(
- rpl::producer<Blob::Radiuses> &&radiuses,
- int index) {
- Expects(index >= 0 && index < size());
- std::move(
- radiuses
- ) | rpl::start_with_next([=](Blob::Radiuses r) {
- _blobs[index].setRadiuses(std::move(r));
- }, _lifetime);
- }
- Blob::Radiuses LinearBlobs::radiusesAt(int index) {
- Expects(index >= 0 && index < size());
- return _blobs[index].radiuses();
- }
- void LinearBlobs::setLevel(float value) {
- const auto to = std::min(_maxLevel, value) / _maxLevel;
- _levelValue.start(to);
- }
- void LinearBlobs::paint(QPainter &p, const QBrush &brush, int width) {
- PainterHighQualityEnabler hq(p);
- const auto opacity = p.opacity();
- for (auto i = 0; i < _blobs.size(); i++) {
- const auto alpha = _blobDatas[i].alpha;
- if (alpha != 1.) {
- p.setOpacity(opacity * alpha);
- }
- _blobs[i].paint(p, brush, width);
- if (alpha != 1.) {
- p.setOpacity(opacity);
- }
- }
- }
- void LinearBlobs::updateLevel(crl::time dt) {
- const auto limitedDt = (dt > 20) ? kRateLimit : dt;
- _levelValue.update(limitedDt);
- const auto level = (float)currentLevel();
- for (auto i = 0; i < _blobs.size(); i++) {
- const auto &data = _blobDatas[i];
- _blobs[i].setRadiuses({
- data.minRadius,
- data.idleRadius + (data.maxRadius - data.idleRadius) * level });
- _blobs[i].update(
- _levelValue.current(),
- data.speedScale,
- limitedDt / kRateLimitF);
- }
- }
- float64 LinearBlobs::currentLevel() const {
- return _levelValue.current();
- }
- } // namespace Ui::Paint
|