Provide simple spoiler animations manager.
This commit is contained in:
parent
c732bd874f
commit
ff85d2226c
2 changed files with 81 additions and 0 deletions
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
#include "ui/effects/spoiler_mess.h"
|
||||
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/integration.h"
|
||||
#include "base/random.h"
|
||||
|
|
@ -32,6 +33,13 @@ std::atomic<const SpoilerMessCached*> DefaultMask/* = nullptr*/;
|
|||
std::condition_variable *DefaultMaskSignal/* = nullptr*/;
|
||||
std::mutex *DefaultMaskMutex/* = nullptr*/;
|
||||
|
||||
struct AnimationManager {
|
||||
Ui::Animations::Basic animation;
|
||||
base::flat_set<not_null<SpoilerAnimation*>> list;
|
||||
};
|
||||
|
||||
AnimationManager *DefaultAnimationManager/* = nullptr*/;
|
||||
|
||||
struct Header {
|
||||
uint32 version = 0;
|
||||
uint32 dataLength = 0;
|
||||
|
|
@ -124,6 +132,28 @@ void WriteDefaultMask(const SpoilerMessCached &mask) {
|
|||
}
|
||||
}
|
||||
|
||||
void Register(not_null<SpoilerAnimation*> animation) {
|
||||
if (!DefaultAnimationManager) {
|
||||
DefaultAnimationManager = new AnimationManager();
|
||||
DefaultAnimationManager->animation.init([] {
|
||||
for (const auto &animation : DefaultAnimationManager->list) {
|
||||
animation->repaint();
|
||||
}
|
||||
});
|
||||
DefaultAnimationManager->animation.start();
|
||||
}
|
||||
DefaultAnimationManager->list.emplace(animation);
|
||||
}
|
||||
|
||||
void Unregister(not_null<SpoilerAnimation*> animation) {
|
||||
Expects(DefaultAnimationManager != nullptr);
|
||||
|
||||
DefaultAnimationManager->list.remove(animation);
|
||||
if (DefaultAnimationManager->list.empty()) {
|
||||
delete base::take(DefaultAnimationManager);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SpoilerMessCached GenerateSpoilerMess(
|
||||
|
|
@ -372,6 +402,39 @@ std::optional<SpoilerMessCached> SpoilerMessCached::FromSerialized(
|
|||
header.canvasSize);
|
||||
}
|
||||
|
||||
SpoilerAnimation::SpoilerAnimation(Fn<void()> repaint)
|
||||
: _repaint(std::move(repaint)) {
|
||||
Expects(_repaint != nullptr);
|
||||
}
|
||||
|
||||
SpoilerAnimation::~SpoilerAnimation() {
|
||||
if (_animating) {
|
||||
_animating = false;
|
||||
Unregister(this);
|
||||
}
|
||||
}
|
||||
|
||||
int SpoilerAnimation::index(crl::time now, bool paused) {
|
||||
const auto add = std::min(now - _last, kDefaultFrameDuration);
|
||||
if (!paused || _last) {
|
||||
_accumulated += add;
|
||||
_last = paused ? 0 : now;
|
||||
}
|
||||
const auto absolute = (_accumulated / kDefaultFrameDuration);
|
||||
if (!paused && !_animating) {
|
||||
_animating = true;
|
||||
Register(this);
|
||||
} else if (paused && _animating) {
|
||||
_animating = false;
|
||||
Unregister(this);
|
||||
}
|
||||
return absolute % kDefaultFramesCount;
|
||||
}
|
||||
|
||||
void SpoilerAnimation::repaint() {
|
||||
_repaint();
|
||||
}
|
||||
|
||||
void PrepareDefaultSpoilerMess() {
|
||||
DefaultMaskSignal = new std::condition_variable();
|
||||
DefaultMaskMutex = new std::mutex();
|
||||
|
|
|
|||
|
|
@ -62,6 +62,24 @@ private:
|
|||
|
||||
};
|
||||
|
||||
// Works with default frame duration and default frame count.
|
||||
class SpoilerAnimation final {
|
||||
public:
|
||||
explicit SpoilerAnimation(Fn<void()> repaint);
|
||||
~SpoilerAnimation();
|
||||
|
||||
int index(crl::time now, bool paused);
|
||||
|
||||
void repaint();
|
||||
|
||||
private:
|
||||
const Fn<void()> _repaint;
|
||||
crl::time _accumulated = 0;
|
||||
crl::time _last = 0;
|
||||
bool _animating = false;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] SpoilerMessCached GenerateSpoilerMess(
|
||||
const SpoilerMessDescriptor &descriptor);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue