mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Play select animations in reactions.
This commit is contained in:
parent
7f27ce6dee
commit
c56a22c8d5
2 changed files with 80 additions and 13 deletions
|
@ -363,6 +363,7 @@ Manager::~Manager() = default;
|
||||||
void Manager::updateButton(ButtonParameters parameters) {
|
void Manager::updateButton(ButtonParameters parameters) {
|
||||||
const auto contextChanged = (_buttonContext != parameters.context);
|
const auto contextChanged = (_buttonContext != parameters.context);
|
||||||
if (contextChanged) {
|
if (contextChanged) {
|
||||||
|
setSelectedIcon(-1);
|
||||||
if (_button) {
|
if (_button) {
|
||||||
_button->applyState(ButtonState::Hidden);
|
_button->applyState(ButtonState::Hidden);
|
||||||
_buttonHiding.push_back(std::move(_button));
|
_buttonHiding.push_back(std::move(_button));
|
||||||
|
@ -498,6 +499,12 @@ bool Manager::checkIconLoaded(ReactionDocument &entry) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::updateCurrentButton() const {
|
||||||
|
if (const auto button = _button.get()) {
|
||||||
|
_buttonUpdate(button->geometry());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::loadIcons() {
|
void Manager::loadIcons() {
|
||||||
const auto load = [&](not_null<DocumentData*> document, int frame) {
|
const auto load = [&](not_null<DocumentData*> document, int frame) {
|
||||||
if (const auto i = _loadCache.find(document); i != end(_loadCache)) {
|
if (const auto i = _loadCache.find(document); i != end(_loadCache)) {
|
||||||
|
@ -521,7 +528,7 @@ void Manager::loadIcons() {
|
||||||
for (const auto &reaction : _list) {
|
for (const auto &reaction : _list) {
|
||||||
_icons.push_back({
|
_icons.push_back({
|
||||||
.appear = load(reaction.appearAnimation, main ? -1 : 0),
|
.appear = load(reaction.appearAnimation, main ? -1 : 0),
|
||||||
.select = load(reaction.selectAnimation, -1),
|
.select = load(reaction.selectAnimation, 0),
|
||||||
.appearAnimated = main,
|
.appearAnimated = main,
|
||||||
});
|
});
|
||||||
main = false;
|
main = false;
|
||||||
|
@ -592,11 +599,25 @@ void Manager::setSelectedIcon(int index) const {
|
||||||
}
|
}
|
||||||
icon.selected = selected;
|
icon.selected = selected;
|
||||||
icon.selectedScale.start(
|
icon.selectedScale.start(
|
||||||
[=] { if (_button) _buttonUpdate(_button->geometry()); },
|
[=] { updateCurrentButton(); },
|
||||||
selected ? 1. : kHoverScale,
|
selected ? 1. : kHoverScale,
|
||||||
selected ? kHoverScale : 1.,
|
selected ? kHoverScale : 1.,
|
||||||
kHoverScaleDuration,
|
kHoverScaleDuration,
|
||||||
anim::sineInOut);
|
anim::sineInOut);
|
||||||
|
if (selected) {
|
||||||
|
const auto skipAnimation = icon.selectAnimated
|
||||||
|
|| !icon.appearAnimated
|
||||||
|
|| (icon.select && icon.select->animating())
|
||||||
|
|| (icon.appear && icon.appear->animating());
|
||||||
|
const auto select = skipAnimation ? nullptr : icon.select.get();
|
||||||
|
if (select && !icon.selectAnimated) {
|
||||||
|
icon.selectAnimated = true;
|
||||||
|
select->animate(
|
||||||
|
[=] { updateCurrentButton(); },
|
||||||
|
0,
|
||||||
|
select->framesCount() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (_selectedIcon != index) {
|
if (_selectedIcon != index) {
|
||||||
setSelected(_selectedIcon, false);
|
setSelected(_selectedIcon, false);
|
||||||
|
@ -694,17 +715,16 @@ void Manager::paintButton(
|
||||||
const auto mainEmojiPosition = position + (button->expandUp()
|
const auto mainEmojiPosition = position + (button->expandUp()
|
||||||
? QPoint(0, size.height() - _outer.height())
|
? QPoint(0, size.height() - _outer.height())
|
||||||
: QPoint());
|
: QPoint());
|
||||||
if (size.height() > _outer.height()
|
if (onlyMainEmojiVisible(button)) {
|
||||||
|| (!_icons.empty() && _icons.front().selected)) {
|
const auto source = validateEmoji(frameIndex, scale);
|
||||||
|
p.drawImage(mainEmojiPosition, _cacheParts, source);
|
||||||
|
} else {
|
||||||
p.save();
|
p.save();
|
||||||
paintAllEmoji(p, button, scale, mainEmojiPosition);
|
paintAllEmoji(p, button, scale, mainEmojiPosition);
|
||||||
p.restore();
|
p.restore();
|
||||||
} else {
|
}
|
||||||
const auto source = validateEmoji(frameIndex, scale);
|
if (button == _button.get() && button->hasInitialView()) {
|
||||||
p.drawImage(mainEmojiPosition, _cacheParts, source);
|
clearAppearAnimations();
|
||||||
if (button == _button.get()) {
|
|
||||||
clearAppearAnimations();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opacity != 1.) {
|
if (opacity != 1.) {
|
||||||
|
@ -712,6 +732,22 @@ void Manager::paintButton(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Manager::onlyMainEmojiVisible(not_null<Button*> button) const {
|
||||||
|
if (!button->hasInitialView()) {
|
||||||
|
return false;
|
||||||
|
} else if (button != _button.get() || _icons.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto &icon = _icons.front();
|
||||||
|
if (icon.selected
|
||||||
|
|| icon.selectedScale.animating()
|
||||||
|
|| (icon.select && icon.select->animating())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
icon.selectAnimated = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::clearAppearAnimations() {
|
void Manager::clearAppearAnimations() {
|
||||||
if (!_showingAll) {
|
if (!_showingAll) {
|
||||||
return;
|
return;
|
||||||
|
@ -719,10 +755,20 @@ void Manager::clearAppearAnimations() {
|
||||||
_showingAll = false;
|
_showingAll = false;
|
||||||
auto main = true;
|
auto main = true;
|
||||||
for (auto &icon : _icons) {
|
for (auto &icon : _icons) {
|
||||||
|
if (!main) {
|
||||||
|
if (icon.selected) {
|
||||||
|
setSelectedIcon(-1);
|
||||||
|
}
|
||||||
|
icon.selectedScale.stop();
|
||||||
|
if (const auto select = icon.select.get()) {
|
||||||
|
select->jumpTo(0, nullptr);
|
||||||
|
}
|
||||||
|
icon.selectAnimated = false;
|
||||||
|
}
|
||||||
if (icon.appearAnimated != main) {
|
if (icon.appearAnimated != main) {
|
||||||
if (const auto appear = icon.appear.get()) {
|
if (const auto appear = icon.appear.get()) {
|
||||||
appear->jumpTo(
|
appear->jumpTo(
|
||||||
main ? (appear->framesCount() - 1) : 1,
|
main ? (appear->framesCount() - 1) : 0,
|
||||||
nullptr);
|
nullptr);
|
||||||
}
|
}
|
||||||
icon.appearAnimated = main;
|
icon.appearAnimated = main;
|
||||||
|
@ -811,7 +857,7 @@ void Manager::paintAllEmoji(
|
||||||
auto emojiPosition = mainEmojiPosition
|
auto emojiPosition = mainEmojiPosition
|
||||||
+ QPoint(0, button->scroll() * (expandUp ? 1 : -1));
|
+ QPoint(0, button->scroll() * (expandUp ? 1 : -1));
|
||||||
const auto update = [=] {
|
const auto update = [=] {
|
||||||
if (_button) _buttonUpdate(_button->geometry());
|
updateCurrentButton();
|
||||||
};
|
};
|
||||||
for (auto &icon : _icons) {
|
for (auto &icon : _icons) {
|
||||||
const auto target = countTarget(icon).translated(emojiPosition);
|
const auto target = countTarget(icon).translated(emojiPosition);
|
||||||
|
@ -820,10 +866,22 @@ void Manager::paintAllEmoji(
|
||||||
if (!target.intersects(clip)) {
|
if (!target.intersects(clip)) {
|
||||||
if (current) {
|
if (current) {
|
||||||
if (const auto appear = icon.appear.get()) {
|
if (const auto appear = icon.appear.get()) {
|
||||||
appear->jumpTo(1, nullptr);
|
appear->jumpTo(0, nullptr);
|
||||||
|
}
|
||||||
|
if (icon.selected) {
|
||||||
|
setSelectedIcon(-1);
|
||||||
}
|
}
|
||||||
icon.appearAnimated = false;
|
icon.appearAnimated = false;
|
||||||
|
icon.selectAnimated = false;
|
||||||
|
if (const auto select = icon.select.get()) {
|
||||||
|
select->jumpTo(0, nullptr);
|
||||||
|
}
|
||||||
|
icon.selectedScale.stop();
|
||||||
}
|
}
|
||||||
|
} else if (icon.select && icon.select->animating()) {
|
||||||
|
const auto size = int(base::SafeRound(target.width()));
|
||||||
|
const auto frame = icon.select->frame({ size, size }, update);
|
||||||
|
p.drawImage(target, frame.image);
|
||||||
} else if (const auto appear = icon.appear.get()) {
|
} else if (const auto appear = icon.appear.get()) {
|
||||||
if (current
|
if (current
|
||||||
&& !icon.appearAnimated
|
&& !icon.appearAnimated
|
||||||
|
@ -835,6 +893,12 @@ void Manager::paintAllEmoji(
|
||||||
const auto frame = appear->frame({ size, size }, update);
|
const auto frame = appear->frame({ size, size }, update);
|
||||||
p.drawImage(target, frame.image);
|
p.drawImage(target, frame.image);
|
||||||
}
|
}
|
||||||
|
if (current
|
||||||
|
&& icon.selectAnimated
|
||||||
|
&& !icon.select->animating()
|
||||||
|
&& !icon.selected) {
|
||||||
|
icon.selectAnimated = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ private:
|
||||||
mutable Ui::Animations::Simple selectedScale;
|
mutable Ui::Animations::Simple selectedScale;
|
||||||
bool appearAnimated = false;
|
bool appearAnimated = false;
|
||||||
mutable bool selected = false;
|
mutable bool selected = false;
|
||||||
|
mutable bool selectAnimated = false;
|
||||||
};
|
};
|
||||||
static constexpr auto kFramesCount = 30;
|
static constexpr auto kFramesCount = 30;
|
||||||
|
|
||||||
|
@ -205,6 +206,8 @@ private:
|
||||||
[[nodiscard]] ClickHandlerPtr resolveButtonLink(
|
[[nodiscard]] ClickHandlerPtr resolveButtonLink(
|
||||||
const Data::Reaction &reaction) const;
|
const Data::Reaction &reaction) const;
|
||||||
|
|
||||||
|
void updateCurrentButton() const;
|
||||||
|
[[nodiscard]] bool onlyMainEmojiVisible(not_null<Button*> button) const;
|
||||||
[[nodiscard]] bool checkIconLoaded(ReactionDocument &entry) const;
|
[[nodiscard]] bool checkIconLoaded(ReactionDocument &entry) const;
|
||||||
void loadIcons();
|
void loadIcons();
|
||||||
void checkIcons();
|
void checkIcons();
|
||||||
|
|
Loading…
Add table
Reference in a new issue