mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Collapse unavailable premium emoji sets in the panel.
This commit is contained in:
parent
b0fab8c987
commit
19f89b1d87
3 changed files with 77 additions and 10 deletions
|
@ -38,6 +38,12 @@ emojiPanButton: RoundButton(defaultActiveButton) {
|
||||||
height: 23px;
|
height: 23px;
|
||||||
textTop: 2px;
|
textTop: 2px;
|
||||||
}
|
}
|
||||||
|
emojiPanExpand: RoundButton(defaultActiveButton) {
|
||||||
|
font: font(12px bold);
|
||||||
|
width: -8px;
|
||||||
|
height: 19px;
|
||||||
|
textTop: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
stickersTrendingAddTop: 14px;
|
stickersTrendingAddTop: 14px;
|
||||||
stickersTrendingAdd: RoundButton(defaultActiveButton) {
|
stickersTrendingAdd: RoundButton(defaultActiveButton) {
|
||||||
|
|
|
@ -40,6 +40,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kCollapsedRows = 3;
|
||||||
|
|
||||||
using Core::RecentEmojiId;
|
using Core::RecentEmojiId;
|
||||||
using Core::RecentEmojiDocument;
|
using Core::RecentEmojiDocument;
|
||||||
|
|
||||||
|
@ -367,6 +369,7 @@ EmojiListWidget::EmojiListWidget(
|
||||||
: Inner(parent, controller)
|
: Inner(parent, controller)
|
||||||
, _localSetsManager(
|
, _localSetsManager(
|
||||||
std::make_unique<LocalStickersManager>(&controller->session()))
|
std::make_unique<LocalStickersManager>(&controller->session()))
|
||||||
|
, _collapsedBg(st::emojiPanExpand.height / 2, st::emojiPanHeaderFg)
|
||||||
, _picker(this)
|
, _picker(this)
|
||||||
, _showPickerTimer([=] { showPicker(); })
|
, _showPickerTimer([=] { showPicker(); })
|
||||||
, _repaintTimer([=] { invokeRepaints(); }) {
|
, _repaintTimer([=] { invokeRepaints(); }) {
|
||||||
|
@ -596,7 +599,9 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
||||||
auto info = SectionInfo();
|
auto info = SectionInfo();
|
||||||
const auto session = &controller()->session();
|
const auto session = &controller()->session();
|
||||||
const auto next = [&] {
|
const auto next = [&] {
|
||||||
info.rowsCount = (info.count + _columnCount - 1) / _columnCount;
|
info.rowsCount = info.collapsed
|
||||||
|
? kCollapsedRows
|
||||||
|
: (info.count + _columnCount - 1) / _columnCount;
|
||||||
info.rowsTop = info.top
|
info.rowsTop = info.top
|
||||||
+ (i == 0 ? st::emojiPanPadding : st::emojiPanHeader);
|
+ (i == 0 ? st::emojiPanPadding : st::emojiPanHeader);
|
||||||
info.rowsBottom = info.rowsTop
|
info.rowsBottom = info.rowsTop
|
||||||
|
@ -619,6 +624,9 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
||||||
info.section = i++;
|
info.section = i++;
|
||||||
info.premiumRequired = section.premiumRequired;
|
info.premiumRequired = section.premiumRequired;
|
||||||
info.count = int(section.list.size());
|
info.count = int(section.list.size());
|
||||||
|
info.collapsed = !section.expanded
|
||||||
|
&& (!section.canRemove || section.premiumRequired)
|
||||||
|
&& (info.count > _columnCount * kCollapsedRows);
|
||||||
if (!next()) {
|
if (!next()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -814,8 +822,10 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
auto toRow = ceilclamp(r.y() + r.height() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
auto toRow = ceilclamp(r.y() + r.height() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
||||||
for (auto i = fromRow; i < toRow; ++i) {
|
for (auto i = fromRow; i < toRow; ++i) {
|
||||||
for (auto j = fromColumn; j < toColumn; ++j) {
|
for (auto j = fromColumn; j < toColumn; ++j) {
|
||||||
auto index = i * _columnCount + j;
|
const auto index = i * _columnCount + j;
|
||||||
if (index >= info.count) break;
|
if (index >= info.count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const auto state = OverEmoji{
|
const auto state = OverEmoji{
|
||||||
.section = info.section,
|
.section = info.section,
|
||||||
|
@ -824,14 +834,20 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
const auto selected = (state == _selected)
|
const auto selected = (state == _selected)
|
||||||
|| (!_picker->isHidden()
|
|| (!_picker->isHidden()
|
||||||
&& state == _pickerSelected);
|
&& state == _pickerSelected);
|
||||||
|
|
||||||
auto w = QPoint(
|
auto w = QPoint(
|
||||||
_rowsLeft + j * _singleSize.width(),
|
_rowsLeft + j * _singleSize.width(),
|
||||||
info.rowsTop + i * _singleSize.height()
|
info.rowsTop + i * _singleSize.height()
|
||||||
) + _areaPosition;
|
) + _areaPosition;
|
||||||
|
if (info.collapsed
|
||||||
|
&& index + 1 == _columnCount * kCollapsedRows) {
|
||||||
|
drawCollapsedBadge(p, w - _areaPosition, info.count);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (selected && !info.premiumRequired) {
|
if (selected && !info.premiumRequired) {
|
||||||
auto tl = w;
|
auto tl = w;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::emojiPanArea.width());
|
if (rtl()) {
|
||||||
|
tl.setX(width() - tl.x() - st::emojiPanArea.width());
|
||||||
|
}
|
||||||
Ui::FillRoundRect(
|
Ui::FillRoundRect(
|
||||||
p,
|
p,
|
||||||
QRect(tl, st::emojiPanArea),
|
QRect(tl, st::emojiPanArea),
|
||||||
|
@ -853,6 +869,26 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::drawCollapsedBadge(
|
||||||
|
QPainter &p,
|
||||||
|
QPoint position,
|
||||||
|
int count) {
|
||||||
|
const auto &st = st::emojiPanExpand;
|
||||||
|
const auto text = u"+%1"_q.arg(count - _columnCount * kCollapsedRows + 1);
|
||||||
|
const auto textWidth = st.font->width(text);
|
||||||
|
const auto buttonw = std::max(textWidth - st.width, st.height);
|
||||||
|
const auto buttonh = st.height;
|
||||||
|
const auto buttonx = position.x() + (_singleSize.width() - buttonw) / 2;
|
||||||
|
const auto buttony = position.y() + (_singleSize.height() - buttonh) / 2;
|
||||||
|
_collapsedBg.paint(p, QRect(buttonx, buttony, buttonw, buttonh));
|
||||||
|
p.setPen(st::emojiPanBg);
|
||||||
|
p.setFont(st.font);
|
||||||
|
p.drawText(
|
||||||
|
buttonx + (buttonw - textWidth) / 2,
|
||||||
|
(buttony + st.textTop + st.font->ascent),
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiListWidget::drawRecent(
|
void EmojiListWidget::drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
@ -985,7 +1021,14 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (const auto over = std::get_if<OverEmoji>(&_selected)) {
|
if (const auto over = std::get_if<OverEmoji>(&_selected)) {
|
||||||
const auto section = over->section;
|
const auto section = over->section;
|
||||||
const auto index = over->index;
|
const auto index = over->index;
|
||||||
if (const auto emoji = lookupOverEmoji(over)) {
|
if (section >= kEmojiSectionCount
|
||||||
|
&& sectionInfo(section).collapsed
|
||||||
|
&& index + 1 == _columnCount * kCollapsedRows) {
|
||||||
|
_custom[section - kEmojiSectionCount].expanded = true;
|
||||||
|
resizeToWidth(width());
|
||||||
|
update();
|
||||||
|
return;
|
||||||
|
} else if (const auto emoji = lookupOverEmoji(over)) {
|
||||||
if (emoji->hasVariants() && !_picker->isHidden()) {
|
if (emoji->hasVariants() && !_picker->isHidden()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1290,6 +1333,9 @@ void EmojiListWidget::processHideFinished() {
|
||||||
|
|
||||||
void EmojiListWidget::processPanelHideFinished() {
|
void EmojiListWidget::processPanelHideFinished() {
|
||||||
unloadAllCustom();
|
unloadAllCustom();
|
||||||
|
if (_localSetsManager->clearInstalledLocally()) {
|
||||||
|
refreshCustom();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::refreshRecent() {
|
void EmojiListWidget::refreshRecent() {
|
||||||
|
@ -1312,7 +1358,10 @@ void EmojiListWidget::refreshCustom() {
|
||||||
}
|
}
|
||||||
const auto canRemove = !!(it->second->flags
|
const auto canRemove = !!(it->second->flags
|
||||||
& Data::StickersSetFlag::Installed);
|
& Data::StickersSetFlag::Installed);
|
||||||
if (canRemove != installed) {
|
const auto sortAsInstalled = canRemove
|
||||||
|
&& (!(it->second->flags & Data::StickersSetFlag::Featured)
|
||||||
|
|| !_localSetsManager->isInstalledLocally(setId));
|
||||||
|
if (sortAsInstalled != installed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto premium = false;
|
auto premium = false;
|
||||||
|
@ -1338,9 +1387,16 @@ void EmojiListWidget::refreshCustom() {
|
||||||
return;
|
return;
|
||||||
} else if (valid) {
|
} else if (valid) {
|
||||||
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
||||||
i->canRemove = canRemove;
|
const auto premiumRequired = premium && premiumMayBeBought;
|
||||||
i->premiumRequired = premium && premiumMayBeBought;
|
if (i->canRemove != canRemove
|
||||||
i->ripple.reset();
|
|| i->premiumRequired != premiumRequired) {
|
||||||
|
i->canRemove = canRemove;
|
||||||
|
i->premiumRequired = premiumRequired;
|
||||||
|
i->ripple.reset();
|
||||||
|
}
|
||||||
|
if (i->canRemove && !i->premiumRequired) {
|
||||||
|
i->expanded = false;
|
||||||
|
}
|
||||||
_custom.push_back(std::move(*i));
|
_custom.push_back(std::move(*i));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "chat_helpers/tabbed_selector.h"
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
|
#include "ui/round_rect.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
@ -109,6 +110,7 @@ private:
|
||||||
int rowsTop = 0;
|
int rowsTop = 0;
|
||||||
int rowsBottom = 0;
|
int rowsBottom = 0;
|
||||||
bool premiumRequired = false;
|
bool premiumRequired = false;
|
||||||
|
bool collapsed = false;
|
||||||
};
|
};
|
||||||
struct CustomInstance;
|
struct CustomInstance;
|
||||||
struct CustomOne {
|
struct CustomOne {
|
||||||
|
@ -123,6 +125,7 @@ private:
|
||||||
std::vector<CustomOne> list;
|
std::vector<CustomOne> list;
|
||||||
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
bool painted = false;
|
bool painted = false;
|
||||||
|
bool expanded = false;
|
||||||
bool canRemove = false;
|
bool canRemove = false;
|
||||||
bool premiumRequired = false;
|
bool premiumRequired = false;
|
||||||
};
|
};
|
||||||
|
@ -200,6 +203,7 @@ private:
|
||||||
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
|
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
|
||||||
void selectEmoji(EmojiPtr emoji);
|
void selectEmoji(EmojiPtr emoji);
|
||||||
void selectCustom(not_null<DocumentData*> document);
|
void selectCustom(not_null<DocumentData*> document);
|
||||||
|
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
|
||||||
void drawRecent(
|
void drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
@ -291,6 +295,7 @@ private:
|
||||||
RightButton _add;
|
RightButton _add;
|
||||||
RightButton _unlock;
|
RightButton _unlock;
|
||||||
RightButton _restore;
|
RightButton _restore;
|
||||||
|
Ui::RoundRect _collapsedBg;
|
||||||
|
|
||||||
OverState _selected;
|
OverState _selected;
|
||||||
OverState _pressed;
|
OverState _pressed;
|
||||||
|
|
Loading…
Add table
Reference in a new issue