mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-01 03:50:43 +00:00
Show appear animations in reactions dropdown.
This commit is contained in:
parent
c0b19000d6
commit
508ba4750c
@ -35,6 +35,7 @@ constexpr auto kButtonExpandDelay = crl::time(25);
|
||||
constexpr auto kButtonHideDelay = crl::time(300);
|
||||
constexpr auto kButtonExpandedHideDelay = crl::time(0);
|
||||
constexpr auto kSizeForDownscale = 96;
|
||||
constexpr auto kHoverScale = 1.2;
|
||||
|
||||
[[nodiscard]] QPoint LocalPosition(not_null<QWheelEvent*> e) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -98,6 +99,10 @@ bool Button::isHidden() const {
|
||||
return (_state == State::Hidden) && !_opacityAnimation.animating();
|
||||
}
|
||||
|
||||
bool Button::hasInitialView() const {
|
||||
return (_geometry.height() == _collapsed.height());
|
||||
}
|
||||
|
||||
QRect Button::geometry() const {
|
||||
return _geometry;
|
||||
}
|
||||
@ -368,6 +373,9 @@ void Manager::updateButton(ButtonParameters parameters) {
|
||||
return;
|
||||
} else if (_button) {
|
||||
_button->applyParameters(parameters);
|
||||
if (_button->hasInitialView()) {
|
||||
clearAppearAnimations();
|
||||
}
|
||||
return;
|
||||
} else if (parameters.outside) {
|
||||
_buttonShowTimer.cancel();
|
||||
@ -386,6 +394,7 @@ void Manager::updateButton(ButtonParameters parameters) {
|
||||
}
|
||||
|
||||
void Manager::showButtonDelayed() {
|
||||
clearAppearAnimations();
|
||||
_button = std::make_unique<Button>(
|
||||
_buttonUpdate,
|
||||
*_scheduledParameters,
|
||||
@ -503,11 +512,14 @@ void Manager::loadIcons() {
|
||||
return entry.icon;
|
||||
};
|
||||
_icons.clear();
|
||||
auto main = true;
|
||||
for (const auto &reaction : _list) {
|
||||
_icons.push_back({
|
||||
.appear = load(reaction.appearAnimation, 1),
|
||||
.appear = load(reaction.appearAnimation, main ? -1 : 1),
|
||||
.select = load(reaction.selectAnimation, -1),
|
||||
.appearAnimated = main,
|
||||
});
|
||||
main = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,6 +668,9 @@ void Manager::paintButton(
|
||||
} else {
|
||||
const auto source = validateEmoji(frameIndex, scale);
|
||||
p.drawImage(mainEmojiPosition, _cacheParts, source);
|
||||
if (button == _button.get()) {
|
||||
clearAppearAnimations();
|
||||
}
|
||||
}
|
||||
|
||||
if (opacity != 1.) {
|
||||
@ -663,6 +678,25 @@ void Manager::paintButton(
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::clearAppearAnimations() {
|
||||
if (!_showingAll) {
|
||||
return;
|
||||
}
|
||||
_showingAll = false;
|
||||
auto main = true;
|
||||
for (auto &icon : _icons) {
|
||||
if (icon.appearAnimated != main) {
|
||||
if (const auto appear = icon.appear.get()) {
|
||||
appear->jumpTo(
|
||||
main ? (appear->framesCount() - 1) : 1,
|
||||
nullptr);
|
||||
}
|
||||
icon.appearAnimated = main;
|
||||
}
|
||||
main = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::paintLongImage(
|
||||
QPainter &p,
|
||||
QRect geometry,
|
||||
@ -702,7 +736,14 @@ void Manager::paintAllEmoji(
|
||||
not_null<Button*> button,
|
||||
float64 scale,
|
||||
QPoint mainEmojiPosition) {
|
||||
const auto current = (button == _button.get());
|
||||
if (current) {
|
||||
_showingAll = true;
|
||||
}
|
||||
|
||||
const auto clip = buttonInner(button);
|
||||
const auto skip = st::reactionAppearStartSkip;
|
||||
const auto animationRect = clip.marginsRemoved({ 0, skip, 0, skip });
|
||||
p.setClipRect(clip);
|
||||
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
@ -720,17 +761,30 @@ void Manager::paintAllEmoji(
|
||||
const auto shift = QPoint(0, oneHeight * (expandUp ? -1 : 1));
|
||||
auto emojiPosition = mainEmojiPosition
|
||||
+ QPoint(0, button->scroll() * (expandUp ? 1 : -1));
|
||||
for (const auto &icon : _icons) {
|
||||
const auto update = [=] {
|
||||
if (_button) _buttonUpdate(_button->geometry());
|
||||
};
|
||||
for (auto &icon : _icons) {
|
||||
const auto target = basicTarget.translated(emojiPosition);
|
||||
emojiPosition += shift;
|
||||
|
||||
if (!target.intersects(clip)) {
|
||||
if (current) {
|
||||
if (const auto appear = icon.appear.get()) {
|
||||
appear->jumpTo(1, nullptr);
|
||||
}
|
||||
icon.appearAnimated = false;
|
||||
}
|
||||
continue;
|
||||
} else if (icon.appear) {
|
||||
if (current
|
||||
&& !icon.appearAnimated
|
||||
&& target.intersects(animationRect)) {
|
||||
icon.appearAnimated = true;
|
||||
icon.appear->animate(update, 0, icon.appear->framesCount());
|
||||
}
|
||||
const auto size = int(base::SafeRound(target.width()));
|
||||
const auto frame = icon.appear->frame(
|
||||
{ size, size },
|
||||
[=] { if (_button) _buttonUpdate(_button->geometry()); });
|
||||
const auto frame = icon.appear->frame({ size, size }, update);
|
||||
p.drawImage(target, frame.image);
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool expandUp() const;
|
||||
[[nodiscard]] bool isHidden() const;
|
||||
[[nodiscard]] bool hasInitialView() const;
|
||||
[[nodiscard]] QRect geometry() const;
|
||||
[[nodiscard]] int scroll() const;
|
||||
[[nodiscard]] float64 currentScale() const;
|
||||
@ -146,6 +147,7 @@ private:
|
||||
struct ReactionIcons {
|
||||
std::shared_ptr<Lottie::Icon> appear;
|
||||
std::shared_ptr<Lottie::Icon> select;
|
||||
bool appearAnimated = false;
|
||||
};
|
||||
static constexpr auto kFramesCount = 30;
|
||||
|
||||
@ -178,6 +180,7 @@ private:
|
||||
|
||||
void setMainReactionIcon();
|
||||
void applyPatternedShadow(const QColor &shadow);
|
||||
void clearAppearAnimations();
|
||||
[[nodiscard]] QRect cacheRect(int frameIndex, int columnIndex) const;
|
||||
QRect validateShadow(
|
||||
int frameIndex,
|
||||
@ -223,6 +226,7 @@ private:
|
||||
base::flat_map<not_null<DocumentData*>, ReactionDocument> _loadCache;
|
||||
std::vector<ReactionIcons> _icons;
|
||||
rpl::lifetime _loadCacheLifetime;
|
||||
bool _showingAll = false;
|
||||
|
||||
std::optional<ButtonParameters> _scheduledParameters;
|
||||
base::Timer _buttonShowTimer;
|
||||
|
@ -983,3 +983,4 @@ reactionCornerActiveAreaPadding: margins(10px, 10px, 10px, 10px);
|
||||
reactionCornerAddedHeightMax: 120px;
|
||||
|
||||
reactionCornerSkip: 2px;
|
||||
reactionAppearStartSkip: 2px;
|
||||
|
Loading…
Reference in New Issue
Block a user