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/spoiler_mess.h"
|
||||||
|
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/integration.h"
|
#include "ui/integration.h"
|
||||||
#include "base/random.h"
|
#include "base/random.h"
|
||||||
|
|
@ -32,6 +33,13 @@ std::atomic<const SpoilerMessCached*> DefaultMask/* = nullptr*/;
|
||||||
std::condition_variable *DefaultMaskSignal/* = nullptr*/;
|
std::condition_variable *DefaultMaskSignal/* = nullptr*/;
|
||||||
std::mutex *DefaultMaskMutex/* = nullptr*/;
|
std::mutex *DefaultMaskMutex/* = nullptr*/;
|
||||||
|
|
||||||
|
struct AnimationManager {
|
||||||
|
Ui::Animations::Basic animation;
|
||||||
|
base::flat_set<not_null<SpoilerAnimation*>> list;
|
||||||
|
};
|
||||||
|
|
||||||
|
AnimationManager *DefaultAnimationManager/* = nullptr*/;
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
uint32 version = 0;
|
uint32 version = 0;
|
||||||
uint32 dataLength = 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
|
} // namespace
|
||||||
|
|
||||||
SpoilerMessCached GenerateSpoilerMess(
|
SpoilerMessCached GenerateSpoilerMess(
|
||||||
|
|
@ -372,6 +402,39 @@ std::optional<SpoilerMessCached> SpoilerMessCached::FromSerialized(
|
||||||
header.canvasSize);
|
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() {
|
void PrepareDefaultSpoilerMess() {
|
||||||
DefaultMaskSignal = new std::condition_variable();
|
DefaultMaskSignal = new std::condition_variable();
|
||||||
DefaultMaskMutex = new std::mutex();
|
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(
|
[[nodiscard]] SpoilerMessCached GenerateSpoilerMess(
|
||||||
const SpoilerMessDescriptor &descriptor);
|
const SpoilerMessDescriptor &descriptor);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue