Added expand/collapse animation to emoji picker overlay.

This commit is contained in:
23rd
2026-04-13 21:42:43 +03:00
parent 3bddcb5461
commit 7b720b2a3f
3 changed files with 73 additions and 36 deletions
@@ -212,10 +212,15 @@ void CreateStickerBox(
.maxSelected = kMaxEmojis,
.allowExpand = true,
};
const auto overlayExpanded = [&] {
const auto pickerCollapsed = [&] {
auto probe = ChatHelpers::EmojiPickerOverlay(nullptr, pickerDescriptor);
return probe.collapsedHeight();
}();
const auto pickerExpanded = [&] {
auto probe = ChatHelpers::EmojiPickerOverlay(nullptr, pickerDescriptor);
return probe.expandedHeight();
}();
const auto pickerExtra = pickerExpanded - pickerCollapsed;
const auto previewHolder = inner->add(
object_ptr<Ui::RpWidget>(inner),
@@ -223,7 +228,7 @@ void CreateStickerBox(
style::al_top);
previewHolder->resize(
st::boxWideWidth,
kPreviewSide + overlayExpanded / 2);
kPreviewSide + pickerExtra);
const auto preview = Ui::CreateChild<PreviewWidget>(
previewHolder,
image);
@@ -236,12 +241,9 @@ void CreateStickerBox(
const auto w = std::min(
previewHolder->width() - 2 * st::boxRowPadding.left(),
int(kPreviewSide * 1.1));
const auto h = picker->expanded()
? picker->expandedHeight()
: picker->collapsedHeight();
const auto x = (previewHolder->width() - w) / 2;
const auto y = kPreviewSide - h;
picker->setGeometry(x, y, w, h);
const auto y = kPreviewSide - pickerCollapsed;
picker->setGeometry(x, y, w, pickerExpanded);
picker->raise();
};
@@ -251,11 +253,6 @@ void CreateStickerBox(
layoutOverlay();
}, preview->lifetime());
picker->expandedValue(
) | rpl::on_next([=](bool) {
layoutOverlay();
}, picker->lifetime());
Ui::AddSkip(inner);
const auto startUpload = [=, set = std::move(set), done = std::move(done)](
@@ -240,7 +240,7 @@ void EmojiPickerOverlay::Strip::mouseReleaseEvent(QMouseEvent *e) {
const auto index = _pressed;
_pressed = -1;
if (released == index && index >= 0 && index < int(_cells.size())) {
_owner->toggleEmoji(_cells[index].emoji);
_owner->toggleEmoji(_cells[index].emoji, false);
}
}
@@ -346,7 +346,7 @@ void EmojiPickerOverlay::Grid::mouseReleaseEvent(QMouseEvent *e) {
const auto index = _pressed;
_pressed = -1;
if (released == index && index >= 0 && index < int(_cells.size())) {
_owner->toggleEmoji(_cells[index].emoji);
_owner->toggleEmoji(_cells[index].emoji, true);
}
}
@@ -402,22 +402,10 @@ EmojiPickerOverlay::EmojiPickerOverlay(
object_ptr<Grid>(_scroll.get(), this));
_grid = gridPtr.data();
_grid->setEmojis(_allForGrid);
_expanded.value(
) | rpl::on_next([=](bool value) {
if (_scroll) {
_scroll->setVisible(value);
}
if (_expandButton) {
_expandButton->update();
}
resize(width(), value ? expandedHeight() : collapsedHeight());
relayout();
}, lifetime());
}
_selectedVar = _selectedList;
resize(width(), collapsedHeight());
resize(width(), expandedHeight());
}
EmojiPickerOverlay::~EmojiPickerOverlay() = default;
@@ -432,10 +420,49 @@ EmojiPickerOverlay::selectedValue() const {
}
void EmojiPickerOverlay::setExpanded(bool expanded) {
if (!_allowExpand) {
if (!_allowExpand || _expanded.current() == expanded) {
return;
}
startExpandAnimation(expanded);
_expanded = expanded;
if (_expandButton) {
_expandButton->update();
}
}
void EmojiPickerOverlay::startExpandAnimation(bool expanded) {
const auto from = _expandAnim.value(expanded ? 0. : 1.);
const auto to = expanded ? 1. : 0.;
_expandAnim.start(
[=] { applyExpandProgress(); },
from,
to,
st::slideWrapDuration,
anim::easeOutCirc);
applyExpandProgress();
}
float64 EmojiPickerOverlay::currentExpandValue() const {
return _expandAnim.value(_expanded.current() ? 1. : 0.);
}
int EmojiPickerOverlay::currentShownHeight() const {
const auto progress = currentExpandValue();
return anim::interpolate(
collapsedHeight(),
expandedHeight(),
progress);
}
void EmojiPickerOverlay::applyExpandProgress() {
const auto h = currentShownHeight();
setMask(QRegion(0, 0, width(), h));
if (_scroll) {
const auto progress = currentExpandValue();
_scroll->setVisible(progress > 0.);
}
relayout();
update();
}
bool EmojiPickerOverlay::expanded() const {
@@ -465,13 +492,21 @@ void EmojiPickerOverlay::paintEvent(QPaintEvent *e) {
p.setPen(Qt::NoPen);
p.setBrush(st::stickersEmojiPickerBg);
const auto radius = st::stickersEmojiPickerRadius;
p.drawRoundedRect(rect(), radius, radius);
const auto h = currentShownHeight();
p.drawRoundedRect(QRect(0, 0, width(), h), radius, radius);
}
void EmojiPickerOverlay::resizeEvent(QResizeEvent *e) {
setMask(QRegion(0, 0, width(), currentShownHeight()));
relayout();
}
void EmojiPickerOverlay::mousePressEvent(QMouseEvent *e) {
if (e->pos().y() > currentShownHeight()) {
e->ignore();
}
}
void EmojiPickerOverlay::relayout() {
const auto &pad = st::stickersEmojiPickerPadding;
if (_about) {
@@ -520,7 +555,7 @@ void EmojiPickerOverlay::relayout() {
}
}
void EmojiPickerOverlay::toggleEmoji(EmojiPtr emoji) {
void EmojiPickerOverlay::toggleEmoji(EmojiPtr emoji, bool fromGrid) {
if (!emoji) {
return;
}
@@ -537,6 +572,9 @@ void EmojiPickerOverlay::toggleEmoji(EmojiPtr emoji) {
_selectedList.push_back(emoji);
}
notifySelectionChanged();
if (fromGrid) {
setExpanded(false);
}
}
void EmojiPickerOverlay::notifySelectionChanged() {
@@ -549,8 +587,4 @@ void EmojiPickerOverlay::notifySelectionChanged() {
}
}
void EmojiPickerOverlay::buildSections() {
// Reserved for potential future categorised rendering in the grid.
}
} // namespace ChatHelpers
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "ui/rp_widget.h"
#include "ui/effects/animations.h"
#include "ui/emoji_config.h"
namespace Ui {
@@ -46,15 +47,19 @@ public:
protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
private:
class Strip;
class Grid;
void buildSections();
void relayout();
void toggleEmoji(EmojiPtr emoji);
void toggleEmoji(EmojiPtr emoji, bool fromGrid);
void notifySelectionChanged();
void startExpandAnimation(bool expanded);
void applyExpandProgress();
[[nodiscard]] float64 currentExpandValue() const;
[[nodiscard]] int currentShownHeight() const;
const QString _aboutText;
const std::vector<EmojiPtr> _recent;
@@ -72,6 +77,7 @@ private:
Ui::AbstractButton *_expandButton = nullptr;
std::unique_ptr<Ui::ScrollArea> _scroll;
Grid *_grid = nullptr;
Ui::Animations::Simple _expandAnim;
};