mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Handle clicks on expandable emoji category icons.
This commit is contained in:
parent
38a69242ca
commit
57d5ec4513
6 changed files with 189 additions and 95 deletions
|
@ -114,21 +114,21 @@ emojiTabs: SettingsSlider(defaultTabsSlider) {
|
|||
}
|
||||
emojiScroll: defaultSolidScroll;
|
||||
emojiRecent: icon {{ "emoji/emoji_recent", emojiIconFg }};
|
||||
emojiRecentActive: icon {{ "emoji/emoji_recent", emojiIconFgActive }};
|
||||
emojiRecentActive: icon {{ "emoji/emoji_recent", windowBoldFg }};
|
||||
emojiPeople: icon {{ "emoji/emoji_people", emojiIconFg }};
|
||||
emojiPeopleActive: icon {{ "emoji/emoji_people", emojiIconFgActive }};
|
||||
emojiPeopleActive: icon {{ "emoji/emoji_people", windowBoldFg }};
|
||||
emojiNature: icon {{ "emoji/emoji_nature", emojiIconFg }};
|
||||
emojiNatureActive: icon {{ "emoji/emoji_nature", emojiIconFgActive }};
|
||||
emojiNatureActive: icon {{ "emoji/emoji_nature", windowBoldFg }};
|
||||
emojiFood: icon {{ "emoji/emoji_food", emojiIconFg }};
|
||||
emojiFoodActive: icon {{ "emoji/emoji_food", emojiIconFgActive }};
|
||||
emojiFoodActive: icon {{ "emoji/emoji_food", windowBoldFg }};
|
||||
emojiActivity: icon {{ "emoji/emoji_activity", emojiIconFg }};
|
||||
emojiActivityActive: icon {{ "emoji/emoji_activity", emojiIconFgActive }};
|
||||
emojiActivityActive: icon {{ "emoji/emoji_activity", windowBoldFg }};
|
||||
emojiTravel: icon {{ "emoji/emoji_travel", emojiIconFg }};
|
||||
emojiTravelActive: icon {{ "emoji/emoji_travel", emojiIconFgActive }};
|
||||
emojiTravelActive: icon {{ "emoji/emoji_travel", windowBoldFg }};
|
||||
emojiObjects: icon {{ "emoji/emoji_objects", emojiIconFg }};
|
||||
emojiObjectsActive: icon {{ "emoji/emoji_objects", emojiIconFgActive }};
|
||||
emojiObjectsActive: icon {{ "emoji/emoji_objects", windowBoldFg }};
|
||||
emojiSymbols: icon {{ "emoji/emoji_symbols", emojiIconFg }};
|
||||
emojiSymbolsActive: icon {{ "emoji/emoji_symbols", emojiIconFgActive }};
|
||||
emojiSymbolsActive: icon {{ "emoji/emoji_symbols", windowBoldFg }};
|
||||
|
||||
emojiFooterHeight: 46px;
|
||||
emojiCategorySkip: 4px;
|
||||
|
|
|
@ -1129,7 +1129,6 @@ void EmojiListWidget::refreshRecent() {
|
|||
clearSelection();
|
||||
_emoji[0] = Core::App().settings().recentEmojiSection();
|
||||
_counts[0] = _emoji[0].size();
|
||||
refreshCustom();
|
||||
resizeToWidth(width());
|
||||
}
|
||||
|
||||
|
@ -1371,10 +1370,15 @@ void EmojiListWidget::showEmojiSection(Section section) {
|
|||
showSet(EmojiSectionSetId(section));
|
||||
}
|
||||
|
||||
void EmojiListWidget::refreshEmoji() {
|
||||
refreshRecent();
|
||||
refreshCustom();
|
||||
}
|
||||
|
||||
void EmojiListWidget::showSet(uint64 setId) {
|
||||
clearSelection();
|
||||
|
||||
refreshRecent();
|
||||
refreshEmoji();
|
||||
|
||||
auto y = 0;
|
||||
enumerateSections([&](const SectionInfo &info) {
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
void refreshEmoji();
|
||||
|
||||
[[nodiscard]] rpl::producer<EmojiPtr> chosen() const;
|
||||
[[nodiscard]] auto customChosen() const
|
||||
-> rpl::producer<TabbedSelector::FileChosen>;
|
||||
|
|
|
@ -33,6 +33,9 @@ constexpr auto kEmojiSectionSetIdBase = uint64(0x77FF'FFFF'FFFF'FFF0ULL);
|
|||
using EmojiSection = Ui::Emoji::Section;
|
||||
|
||||
void UpdateAnimated(anim::value &value, int to) {
|
||||
if (int(base::SafeRound(value.to())) == to) {
|
||||
return;
|
||||
}
|
||||
value = anim::value(
|
||||
(value.from() != value.to()) ? value.from() : to,
|
||||
to);
|
||||
|
@ -118,13 +121,12 @@ StickersListFooter::StickersListFooter(Descriptor &&descriptor)
|
|||
, _searchButtonVisible(descriptor.searchButtonVisible)
|
||||
, _settingsButtonVisible(descriptor.settingsButtonVisible)
|
||||
, _iconsAnimation([=](crl::time now) {
|
||||
return iconsAnimationCallback(now);
|
||||
return iconsAnimationCallback(_iconState, now);
|
||||
})
|
||||
, _subiconsAnimation([=](crl::time now) {
|
||||
return iconsAnimationCallback(now);
|
||||
return iconsAnimationCallback(_subiconState, now);
|
||||
})
|
||||
, _selectionBg(st::roundRadiusSmall, st::windowBgRipple)
|
||||
, _emojiIconWidth(st::stickerIconWidth)
|
||||
, _barSelection(descriptor.barSelection) {
|
||||
setMouseTracking(true);
|
||||
|
||||
|
@ -273,11 +275,14 @@ void StickersListFooter::enumerateIcons(
|
|||
auto left = _iconsLeft - iconsX;
|
||||
const auto emojiId = AllEmojiSectionSetId();
|
||||
const auto right = width();
|
||||
const auto single = st::stickerIconWidth;
|
||||
for (auto i = 0, count = int(_icons.size()); i != count; ++i) {
|
||||
auto &icon = _icons[i];
|
||||
const auto width = (icon.setId == emojiId)
|
||||
? _emojiIconWidthAnimation.value(_emojiIconWidth)
|
||||
: st::stickerIconWidth;
|
||||
? _subiconsWidthAnimation.value(_subiconsExpanded
|
||||
? _subiconsWidth
|
||||
: single)
|
||||
: single;
|
||||
const auto visible = (left + width > 0 && left < right);
|
||||
const auto result = callback({
|
||||
.index = i,
|
||||
|
@ -296,13 +301,13 @@ void StickersListFooter::enumerateSubicons(
|
|||
Fn<bool(const IconInfo &)> callback) const {
|
||||
auto iconsX = int(base::SafeRound(_subiconState.x.current()));
|
||||
auto left = -iconsX;
|
||||
const auto right = _emojiIconWidth;
|
||||
const auto right = _subiconsWidth;
|
||||
using Section = Ui::Emoji::Section;
|
||||
for (auto i = int(Section::People); i <= int(Section::Symbols); ++i) {
|
||||
const auto width = st::stickerIconWidth;
|
||||
const auto visible = (left + width > 0 && left < right);
|
||||
const auto result = callback({
|
||||
.index = i,
|
||||
.index = i - int(Section::People),
|
||||
.left = left,
|
||||
.width = int(base::SafeRound(width)),
|
||||
.visible = visible,
|
||||
|
@ -353,8 +358,8 @@ void StickersListFooter::preloadImages() {
|
|||
}
|
||||
|
||||
void StickersListFooter::validateSelectedIcon(
|
||||
uint64 setId,
|
||||
ValidateIconAnimations animations) {
|
||||
uint64 setId,
|
||||
ValidateIconAnimations animations) {
|
||||
_activeByScrollId = setId;
|
||||
|
||||
using EmojiSection = Ui::Emoji::Section;
|
||||
|
@ -389,21 +394,18 @@ void StickersListFooter::validateSelectedIcon(
|
|||
}
|
||||
|
||||
void StickersListFooter::updateEmojiSectionWidth() {
|
||||
_emojiIconExpanded = (_iconState.selected >= 0)
|
||||
const auto expanded = (_iconState.selected >= 0)
|
||||
&& (_iconState.selected < _icons.size())
|
||||
&& (_icons[_iconState.selected].setId == AllEmojiSectionSetId());
|
||||
const auto desired = _emojiIconExpanded
|
||||
? (9 * st::stickerIconWidth / 2)
|
||||
: st::stickerIconWidth;
|
||||
if (_emojiIconWidth == desired) {
|
||||
if (_subiconsExpanded == expanded) {
|
||||
return;
|
||||
}
|
||||
_emojiIconWidthAnimation.start(
|
||||
_subiconsExpanded = expanded;
|
||||
_subiconsWidthAnimation.start(
|
||||
[=] { updateEmojiWidthCallback(); },
|
||||
_emojiIconWidth,
|
||||
desired,
|
||||
st::stickerIconMove);
|
||||
_emojiIconWidth = desired;
|
||||
expanded ? st::stickerIconWidth : _subiconsWidth,
|
||||
expanded ? _subiconsWidth : st::stickerIconWidth,
|
||||
st::slideDuration);
|
||||
}
|
||||
|
||||
void StickersListFooter::updateEmojiWidthCallback() {
|
||||
|
@ -411,6 +413,9 @@ void StickersListFooter::updateEmojiWidthCallback() {
|
|||
const auto info = iconInfo(_iconState.selected);
|
||||
UpdateAnimated(_iconState.selectionX, info.left);
|
||||
UpdateAnimated(_iconState.selectionWidth, info.width);
|
||||
if (_iconsAnimation.animating()) {
|
||||
iconsAnimationCallback(_iconState, crl::now());
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListFooter::setSelectedIcon(
|
||||
|
@ -421,10 +426,11 @@ void StickersListFooter::setSelectedIcon(
|
|||
}
|
||||
_iconState.selected = newSelected;
|
||||
updateEmojiSectionWidth();
|
||||
const auto shift = int(base::SafeRound(_iconState.x.current()));
|
||||
const auto info = iconInfo(_iconState.selected);
|
||||
UpdateAnimated(_iconState.selectionX, info.left, animations);
|
||||
UpdateAnimated(_iconState.selectionX, shift + info.left, animations);
|
||||
UpdateAnimated(_iconState.selectionWidth, info.width, animations);
|
||||
const auto relativeLeft = info.left - _iconsLeft;
|
||||
const auto relativeLeft = shift + info.left - _iconsLeft;
|
||||
const auto iconsWidthForCentering = 2 * relativeLeft + info.width;
|
||||
const auto iconsXFinal = std::clamp(
|
||||
(_iconsLeft + iconsWidthForCentering + _iconsRight - width()) / 2,
|
||||
|
@ -449,23 +455,21 @@ void StickersListFooter::setSelectedSubicon(
|
|||
return;
|
||||
}
|
||||
_subiconState.selected = newSelected;
|
||||
const auto shift = int(base::SafeRound(_subiconState.x.current()));
|
||||
const auto info = subiconInfo(_subiconState.selected);
|
||||
updateEmojiSectionWidth();
|
||||
UpdateAnimated(_subiconState.selectionX, info.left, animations);
|
||||
UpdateAnimated(_subiconState.selectionX, shift + info.left, animations);
|
||||
UpdateAnimated(_subiconState.selectionWidth, info.width, animations);
|
||||
const auto relativeLeft = info.left;
|
||||
const auto relativeLeft = shift + info.left;
|
||||
const auto subiconsWidthForCentering = 2 * relativeLeft + info.width;
|
||||
const auto subiconsXFinal = std::clamp(
|
||||
(subiconsWidthForCentering - width()) / 2,
|
||||
(subiconsWidthForCentering - _subiconsWidth) / 2,
|
||||
0,
|
||||
_subiconState.max);
|
||||
if (animations == ValidateIconAnimations::None) {
|
||||
_subiconState.selectionX = anim::value(
|
||||
subiconsXFinal,
|
||||
subiconsXFinal);
|
||||
_subiconState.x = anim::value(subiconsXFinal, subiconsXFinal);
|
||||
_subiconsAnimation.stop();
|
||||
} else {
|
||||
_subiconState.selectionX.start(subiconsXFinal);
|
||||
_subiconState.x.start(subiconsXFinal);
|
||||
_subiconState.animationStart = crl::now();
|
||||
_subiconsAnimation.start();
|
||||
}
|
||||
|
@ -474,7 +478,7 @@ void StickersListFooter::setSelectedSubicon(
|
|||
}
|
||||
|
||||
void StickersListFooter::processHideFinished() {
|
||||
_iconOver = _iconDown = SpecialOver::None;
|
||||
_selected = _pressed = SpecialOver::None;
|
||||
_iconsAnimation.stop();
|
||||
_iconState.animationStart = 0;
|
||||
_iconState.x.finish();
|
||||
|
@ -603,6 +607,7 @@ void StickersListFooter::resizeEvent(QResizeEvent *e) {
|
|||
resizeSearchControls();
|
||||
}
|
||||
refreshIconsGeometry(ValidateIconAnimations::None);
|
||||
refreshSubiconsGeometry();
|
||||
}
|
||||
|
||||
void StickersListFooter::resizeSearchControls() {
|
||||
|
@ -637,12 +642,12 @@ void StickersListFooter::mousePressEvent(QMouseEvent *e) {
|
|||
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
||||
updateSelected();
|
||||
|
||||
if (_iconOver == SpecialOver::Settings) {
|
||||
if (_selected == SpecialOver::Settings) {
|
||||
_openSettingsRequests.fire({});
|
||||
} else if (_iconOver == SpecialOver::Search) {
|
||||
} else if (_selected == SpecialOver::Search) {
|
||||
toggleSearch(true);
|
||||
} else {
|
||||
_iconDown = _iconOver;
|
||||
_pressed = _selected;
|
||||
_iconsMouseDown = _iconsMousePos;
|
||||
_iconsStartX = qRound(_iconState.x.current());
|
||||
}
|
||||
|
@ -654,7 +659,7 @@ void StickersListFooter::mouseMoveEvent(QMouseEvent *e) {
|
|||
|
||||
if (!_iconsDragging
|
||||
&& !_icons.empty()
|
||||
&& v::is<int>(_iconDown)) {
|
||||
&& v::is<IconId>(_pressed)) {
|
||||
if ((_iconsMousePos - _iconsMouseDown).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_iconsDragging = true;
|
||||
}
|
||||
|
@ -679,7 +684,7 @@ void StickersListFooter::mouseReleaseEvent(QMouseEvent *e) {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto wasDown = std::exchange(_iconDown, SpecialOver::None);
|
||||
const auto wasDown = std::exchange(_pressed, SpecialOver::None);
|
||||
|
||||
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
||||
if (_iconsDragging) {
|
||||
|
@ -688,12 +693,23 @@ void StickersListFooter::mouseReleaseEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
updateSelected();
|
||||
if (wasDown == _iconOver) {
|
||||
if (const auto index = std::get_if<int>(&_iconOver)) {
|
||||
const auto info = iconInfo(*index);
|
||||
if (wasDown == _selected) {
|
||||
if (const auto icon = std::get_if<IconId>(&_selected)) {
|
||||
const auto info = iconInfo(icon->index);
|
||||
_iconState.selectionX = anim::value(info.left, info.left);
|
||||
_iconState.selectionWidth = anim::value(info.width, info.width);
|
||||
_setChosen.fire_copy(_icons[*index].setId);
|
||||
const auto subinfo = subiconInfo(icon->subindex);
|
||||
_subiconState.selectionX = anim::value(
|
||||
subinfo.left,
|
||||
subinfo.left);
|
||||
_subiconState.selectionWidth = anim::value(
|
||||
subinfo.width,
|
||||
subinfo.width);
|
||||
const auto setId = _icons[icon->index].setId;
|
||||
_setChosen.fire_copy((setId == AllEmojiSectionSetId())
|
||||
? EmojiSectionSetId(
|
||||
EmojiSection(int(EmojiSection::People) + icon->subindex))
|
||||
: setId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -717,8 +733,8 @@ bool StickersListFooter::eventHook(QEvent *e) {
|
|||
if (e->type() == QEvent::TouchBegin) {
|
||||
} else if (e->type() == QEvent::Wheel) {
|
||||
if (!_icons.empty()
|
||||
&& v::is<int>(_iconOver)
|
||||
&& (_iconDown == SpecialOver::None)) {
|
||||
&& v::is<IconId>(_selected)
|
||||
&& (_pressed == SpecialOver::None)) {
|
||||
scrollByWheelEvent(static_cast<QWheelEvent*>(e));
|
||||
}
|
||||
}
|
||||
|
@ -789,7 +805,7 @@ void StickersListFooter::clipCallback(
|
|||
}
|
||||
|
||||
void StickersListFooter::updateSelected() {
|
||||
if (_iconDown != SpecialOver::None) {
|
||||
if (_pressed != SpecialOver::None) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -821,20 +837,30 @@ void StickersListFooter::updateSelected() {
|
|||
x += qRound(_iconState.x.current());
|
||||
enumerateIcons([&](const IconInfo &info) {
|
||||
if (x >= info.left && x < info.left + info.width) {
|
||||
newOver = info.index;
|
||||
newOver = IconId{ .index = info.index };
|
||||
if (_icons[info.index].setId == AllEmojiSectionSetId()) {
|
||||
const auto subx = (x - info.left);
|
||||
enumerateSubicons([&](const IconInfo &info) {
|
||||
if (subx >= info.left && subx < info.left + info.width) {
|
||||
v::get<IconId>(newOver).subindex = info.index;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (newOver != _iconOver) {
|
||||
if (newOver != _selected) {
|
||||
if (newOver == SpecialOver::None) {
|
||||
setCursor(style::cur_default);
|
||||
} else if (_iconOver == SpecialOver::None) {
|
||||
} else if (_selected == SpecialOver::None) {
|
||||
setCursor(style::cur_pointer);
|
||||
}
|
||||
_iconOver = newOver;
|
||||
_selected = newOver;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -881,7 +907,7 @@ void StickersListFooter::refreshIcons(
|
|||
|
||||
void StickersListFooter::refreshIconsGeometry(
|
||||
ValidateIconAnimations animations) {
|
||||
_iconOver = _iconDown = SpecialOver::None;
|
||||
_selected = _pressed = SpecialOver::None;
|
||||
_iconState.x.finish();
|
||||
_iconState.selectionX.finish();
|
||||
_iconState.selectionWidth.finish();
|
||||
|
@ -896,9 +922,39 @@ void StickersListFooter::refreshIconsGeometry(
|
|||
}
|
||||
updateSelected();
|
||||
validateSelectedIcon(_activeByScrollId, animations);
|
||||
refreshSubiconsGeometry();
|
||||
update();
|
||||
}
|
||||
|
||||
void StickersListFooter::refreshSubiconsGeometry() {
|
||||
using Section = Ui::Emoji::Section;
|
||||
_subiconState.x.finish();
|
||||
_subiconState.selectionX.finish();
|
||||
_subiconState.selectionWidth.finish();
|
||||
_subiconState.animationStart = 0;
|
||||
_subiconsAnimation.stop();
|
||||
const auto single = st::stickerIconWidth;
|
||||
const auto half = single / 2;
|
||||
const auto count = int(Section::Symbols) - int(Section::Recent);
|
||||
const auto widthMax = count * single;
|
||||
const auto widthMin = 4 * single + half;
|
||||
const auto collapsedWidth = int(_icons.size()) * single;
|
||||
_subiconsWidth = std::clamp(
|
||||
width() + single - collapsedWidth,
|
||||
widthMin,
|
||||
widthMax);
|
||||
if (_subiconsWidth < widthMax) {
|
||||
_subiconsWidth = ((_subiconsWidth - half) / single) * single + half;
|
||||
}
|
||||
const auto &last = subiconInfo(int(Section::Symbols));
|
||||
_subiconState.max = std::max(
|
||||
widthMax - _subiconsWidth,
|
||||
0);
|
||||
if (_subiconState.x.current() > _subiconState.max) {
|
||||
_subiconState.x = anim::value(_subiconState.max, _subiconState.max);
|
||||
}
|
||||
}
|
||||
|
||||
bool StickersListFooter::hasOnlyFeaturedSets() const {
|
||||
return (_icons.size() == 1)
|
||||
&& (_icons[0].setId == Data::Stickers::FeaturedSetId);
|
||||
|
@ -1069,21 +1125,32 @@ void StickersListFooter::paintSetIcon(
|
|||
_premiumIcon);
|
||||
} else {
|
||||
using Section = Ui::Emoji::Section;
|
||||
const auto sectionIcon = [&](Section section) {
|
||||
switch (section) {
|
||||
case Section::Recent: return &st::emojiRecent;
|
||||
case Section::People: return &st::emojiPeople;
|
||||
case Section::Nature: return &st::emojiNature;
|
||||
case Section::Food: return &st::emojiFood;
|
||||
case Section::Activity: return &st::emojiActivity;
|
||||
case Section::Travel: return &st::emojiTravel;
|
||||
case Section::Objects: return &st::emojiObjects;
|
||||
case Section::Symbols: return &st::emojiSymbols;
|
||||
}
|
||||
Unexpected("Section in SetIdEmojiSection result.");
|
||||
const auto sectionIcon = [&](Section section, bool active) {
|
||||
const auto icons = std::array{
|
||||
&st::emojiRecent,
|
||||
&st::emojiRecentActive,
|
||||
&st::emojiPeople,
|
||||
&st::emojiPeopleActive,
|
||||
&st::emojiNature,
|
||||
&st::emojiNatureActive,
|
||||
&st::emojiFood,
|
||||
&st::emojiFoodActive,
|
||||
&st::emojiActivity,
|
||||
&st::emojiActivityActive,
|
||||
&st::emojiTravel,
|
||||
&st::emojiTravelActive,
|
||||
&st::emojiObjects,
|
||||
&st::emojiObjectsActive,
|
||||
&st::emojiSymbols,
|
||||
&st::emojiSymbolsActive,
|
||||
};
|
||||
const auto index = int(section) * 2 + (active ? 1 : 0);
|
||||
|
||||
Assert(index >= 0 && index < icons.size());
|
||||
return icons[index];
|
||||
};
|
||||
auto left = info.left;
|
||||
const auto paintOne = [&](const style::icon *icon) {
|
||||
const auto left = info.left;
|
||||
const auto paintOne = [&](int left, const style::icon *icon) {
|
||||
icon->paint(
|
||||
p,
|
||||
left + (st::stickerIconWidth - icon->width()) / 2,
|
||||
|
@ -1100,13 +1167,19 @@ void StickersListFooter::paintSetIcon(
|
|||
info.width - 2 * skip,
|
||||
st::emojiFooterHeight,
|
||||
Qt::IntersectClip);
|
||||
for (auto i = int(Section::People); i <= int(Section::Symbols); ++i) {
|
||||
paintOne(sectionIcon(Section(i)));
|
||||
left += st::stickerIconWidth;
|
||||
}
|
||||
enumerateSubicons([&](const IconInfo &info) {
|
||||
if (info.visible) {
|
||||
paintOne(
|
||||
info.left + left,
|
||||
sectionIcon(
|
||||
Section(int(Section::People) + info.index),
|
||||
(_subiconState.selected == info.index)));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
p.restore();
|
||||
} else {
|
||||
paintOne([&] {
|
||||
paintOne(left, [&] {
|
||||
if (icon.setId == Data::Stickers::FeaturedSetId) {
|
||||
const auto session = &_controller->session();
|
||||
return session->data().stickers().featuredSetsUnreadCount()
|
||||
|
@ -1114,8 +1187,10 @@ void StickersListFooter::paintSetIcon(
|
|||
: &st::stickersTrending;
|
||||
//} else if (setId == Stickers::FavedSetId) {
|
||||
// return &st::stickersFaved;
|
||||
} else if (icon.setId == AllEmojiSectionSetId()) {
|
||||
return &st::emojiPeople;
|
||||
} else if (const auto section = SetIdEmojiSection(icon.setId)) {
|
||||
return sectionIcon(*section);
|
||||
return sectionIcon(*section, false);
|
||||
}
|
||||
return &st::emojiRecent;
|
||||
}());
|
||||
|
@ -1123,28 +1198,30 @@ void StickersListFooter::paintSetIcon(
|
|||
}
|
||||
}
|
||||
|
||||
bool StickersListFooter::iconsAnimationCallback(crl::time now) {
|
||||
bool StickersListFooter::iconsAnimationCallback(
|
||||
ScrollState &state,
|
||||
crl::time now) {
|
||||
if (anim::Disabled()) {
|
||||
now += st::stickerIconMove;
|
||||
}
|
||||
if (_iconState.animationStart) {
|
||||
const auto dt = (now - _iconState.animationStart)
|
||||
if (state.animationStart) {
|
||||
const auto dt = (now - state.animationStart)
|
||||
/ float64(st::stickerIconMove);
|
||||
if (dt >= 1.) {
|
||||
_iconState.animationStart = 0;
|
||||
_iconState.x.finish();
|
||||
_iconState.selectionX.finish();
|
||||
_iconState.selectionWidth.finish();
|
||||
state.animationStart = 0;
|
||||
state.x.finish();
|
||||
state.selectionX.finish();
|
||||
state.selectionWidth.finish();
|
||||
} else {
|
||||
_iconState.x.update(dt, anim::linear);
|
||||
_iconState.selectionX.update(dt, anim::linear);
|
||||
_iconState.selectionWidth.update(dt, anim::linear);
|
||||
state.x.update(dt, anim::linear);
|
||||
state.selectionX.update(dt, anim::linear);
|
||||
state.selectionWidth.update(dt, anim::linear);
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
return (_iconState.animationStart != 0);
|
||||
return (state.animationStart != 0);
|
||||
}
|
||||
|
||||
} // namespace ChatHelpers
|
||||
|
|
|
@ -127,7 +127,15 @@ private:
|
|||
Search,
|
||||
Settings,
|
||||
};
|
||||
using OverState = std::variant<SpecialOver, int>;
|
||||
struct IconId {
|
||||
int index = 0;
|
||||
int subindex = 0;
|
||||
|
||||
friend inline bool operator==(IconId a, IconId b) {
|
||||
return (a.index == b.index) && (a.subindex == b.subindex);
|
||||
}
|
||||
};
|
||||
using OverState = std::variant<SpecialOver, IconId>;
|
||||
struct IconInfo {
|
||||
int index = 0;
|
||||
int left = 0;
|
||||
|
@ -150,7 +158,7 @@ private:
|
|||
[[nodiscard]] IconInfo subiconInfo(int index) const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
||||
bool iconsAnimationCallback(crl::time now);
|
||||
bool iconsAnimationCallback(ScrollState &state, crl::time now);
|
||||
void setSelectedIcon(
|
||||
int newSelected,
|
||||
ValidateIconAnimations animations);
|
||||
|
@ -162,6 +170,7 @@ private:
|
|||
void validateIconAnimation(const StickerIcon &icon);
|
||||
|
||||
void refreshIconsGeometry(ValidateIconAnimations animations);
|
||||
void refreshSubiconsGeometry();
|
||||
void updateSelected();
|
||||
void updateSetIcon(uint64 setId);
|
||||
void updateSetIconAt(int left);
|
||||
|
@ -198,8 +207,8 @@ private:
|
|||
std::vector<StickerIcon> _icons;
|
||||
Fn<std::shared_ptr<Lottie::FrameRenderer>()> _renderer;
|
||||
uint64 _activeByScrollId = 0;
|
||||
OverState _iconOver = SpecialOver::None;
|
||||
OverState _iconDown = SpecialOver::None;
|
||||
OverState _selected = SpecialOver::None;
|
||||
OverState _pressed = SpecialOver::None;
|
||||
|
||||
QPoint _iconsMousePos, _iconsMouseDown;
|
||||
mutable QImage _premiumIcon;
|
||||
|
@ -217,9 +226,9 @@ private:
|
|||
Ui::Animations::Basic _subiconsAnimation;
|
||||
|
||||
Ui::RoundRect _selectionBg;
|
||||
Ui::Animations::Simple _emojiIconWidthAnimation;
|
||||
int _emojiIconWidth = 0;
|
||||
bool _emojiIconExpanded = false;
|
||||
Ui::Animations::Simple _subiconsWidthAnimation;
|
||||
int _subiconsWidth = 0;
|
||||
bool _subiconsExpanded = false;
|
||||
bool _barSelection = false;
|
||||
|
||||
bool _horizontal = false;
|
||||
|
|
|
@ -410,6 +410,8 @@ TabbedSelector::TabbedSelector(
|
|||
emoji()->showSet(setId);
|
||||
_showRequests.fire({});
|
||||
}, lifetime());
|
||||
|
||||
emoji()->refreshEmoji();
|
||||
}
|
||||
//setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||
|
|
Loading…
Add table
Reference in a new issue