mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 15:17:07 +02:00
Make nice emoji status selector in profile.
This commit is contained in:
parent
165d3143de
commit
64bd4f0926
10 changed files with 327 additions and 229 deletions
|
@ -364,8 +364,14 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
|||
EmojiListWidget::EmojiListWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
Window::GifPauseReason level)
|
||||
Window::GifPauseReason level,
|
||||
Mode mode)
|
||||
: Inner(parent, controller, level)
|
||||
, _mode(mode)
|
||||
, _staticCount(_mode == Mode::Full ? kEmojiSectionCount : 1)
|
||||
, _premiumIcon(_mode == Mode::EmojiStatus
|
||||
? std::make_unique<GradientPremiumStar>()
|
||||
: nullptr)
|
||||
, _localSetsManager(
|
||||
std::make_unique<LocalStickersManager>(&controller->session()))
|
||||
, _collapsedBg(st::emojiPanExpand.height / 2, st::emojiPanHeaderFg)
|
||||
|
@ -376,7 +382,7 @@ EmojiListWidget::EmojiListWidget(
|
|||
|
||||
_picker->hide();
|
||||
|
||||
for (auto i = 1; i != kEmojiSectionCount; ++i) {
|
||||
for (auto i = 1; i != _staticCount; ++i) {
|
||||
const auto section = static_cast<Section>(i);
|
||||
_counts[i] = Ui::Emoji::GetSectionCount(section);
|
||||
}
|
||||
|
@ -430,8 +436,8 @@ void EmojiListWidget::repaintCustom(uint64 setId) {
|
|||
const auto repaint1 = repaintRecent
|
||||
&& (info.section == int(Section::Recent));
|
||||
const auto repaint2 = !repaint1
|
||||
&& (info.section >= kEmojiSectionCount)
|
||||
&& (setId == _custom[info.section - kEmojiSectionCount].id);
|
||||
&& (info.section >= _staticCount)
|
||||
&& (setId == _custom[info.section - _staticCount].id);
|
||||
if (repaint1 || repaint2) {
|
||||
update(
|
||||
0,
|
||||
|
@ -496,10 +502,10 @@ void EmojiListWidget::unloadCustomIn(const SectionInfo &info) {
|
|||
}
|
||||
}
|
||||
return;
|
||||
} else if (info.section < kEmojiSectionCount) {
|
||||
} else if (info.section < _staticCount) {
|
||||
return;
|
||||
}
|
||||
auto &custom = _custom[info.section - kEmojiSectionCount];
|
||||
auto &custom = _custom[info.section - _staticCount];
|
||||
if (!custom.painted) {
|
||||
return;
|
||||
}
|
||||
|
@ -549,7 +555,7 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
|||
info.top = info.rowsBottom;
|
||||
return true;
|
||||
};
|
||||
for (; i != kEmojiSectionCount; ++i) {
|
||||
for (; i != _staticCount; ++i) {
|
||||
info.section = i;
|
||||
info.count = i ? _counts[i] : _recent.size();
|
||||
if (!next()) {
|
||||
|
@ -599,7 +605,7 @@ EmojiListWidget::SectionInfo EmojiListWidget::sectionInfoByOffset(
|
|||
}
|
||||
|
||||
int EmojiListWidget::sectionsCount() const {
|
||||
return kEmojiSectionCount + int(_custom.size());
|
||||
return _staticCount + int(_custom.size());
|
||||
}
|
||||
|
||||
void EmojiListWidget::setSingleSize(QSize size) {
|
||||
|
@ -612,6 +618,9 @@ void EmojiListWidget::setSingleSize(QSize size) {
|
|||
_innerPosition = QPoint(
|
||||
(area.width() - esize) / 2,
|
||||
(area.height() - esize) / 2);
|
||||
const auto customSize = Ui::Text::AdjustCustomEmojiSize(esize);
|
||||
const auto customSkip = (esize - customSize) / 2;
|
||||
_customPosition = QPoint(customSkip, customSkip);
|
||||
_picker->setSingleSize(_singleSize);
|
||||
}
|
||||
|
||||
|
@ -649,7 +658,7 @@ void EmojiListWidget::ensureLoaded(int section) {
|
|||
fillRecent();
|
||||
}
|
||||
return;
|
||||
} else if (section >= kEmojiSectionCount || !_emoji[section].empty()) {
|
||||
} else if (section >= _staticCount || !_emoji[section].empty()) {
|
||||
return;
|
||||
}
|
||||
_emoji[section] = Ui::Emoji::GetSection(static_cast<Section>(section));
|
||||
|
@ -671,11 +680,17 @@ void EmojiListWidget::fillRecent() {
|
|||
_recentCustomIds.clear();
|
||||
|
||||
const auto &list = Core::App().settings().recentEmoji();
|
||||
_recent.reserve(std::min(int(list.size()), Core::kRecentEmojiLimit));
|
||||
_recent.reserve(std::min(int(list.size()), Core::kRecentEmojiLimit) + 1);
|
||||
if (_mode == Mode::EmojiStatus) {
|
||||
const auto star = QString::fromUtf8("\xe2\xad\x90\xef\xb8\x8f");
|
||||
_recent.push_back({ .id = { Ui::Emoji::Find(star) } });
|
||||
}
|
||||
const auto test = controller()->session().isTestMode();
|
||||
for (const auto &one : list) {
|
||||
const auto document = std::get_if<RecentEmojiDocument>(&one.id.data);
|
||||
if (document && document->test != test) {
|
||||
if (_mode == Mode::EmojiStatus && !document) {
|
||||
continue;
|
||||
} else if (document && document->test != test) {
|
||||
continue;
|
||||
}
|
||||
_recent.push_back({
|
||||
|
@ -730,9 +745,9 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
|||
if (info.section > 0 && r.top() < info.rowsTop) {
|
||||
p.setFont(st::emojiPanHeaderFont);
|
||||
p.setPen(st::emojiPanHeaderFg);
|
||||
auto titleText = (info.section < kEmojiSectionCount)
|
||||
auto titleText = (info.section < _staticCount)
|
||||
? ChatHelpers::EmojiCategoryTitle(info.section)(tr::now)
|
||||
: _custom[info.section - kEmojiSectionCount].title;
|
||||
: _custom[info.section - _staticCount].title;
|
||||
auto titleWidth = st::emojiPanHeaderFont->width(titleText);
|
||||
if (titleWidth > widthForTitle) {
|
||||
titleText = st::emojiPanHeaderFont->elided(titleText, widthForTitle);
|
||||
|
@ -793,10 +808,10 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
if (info.section == int(Section::Recent)) {
|
||||
drawRecent(p, w, now, paused, index);
|
||||
} else if (info.section < kEmojiSectionCount) {
|
||||
} else if (info.section < _staticCount) {
|
||||
drawEmoji(p, w, _emoji[info.section][index]);
|
||||
} else {
|
||||
const auto set = info.section - kEmojiSectionCount;
|
||||
const auto set = info.section - _staticCount;
|
||||
drawCustom(p, w, now, paused, set, index);
|
||||
}
|
||||
}
|
||||
|
@ -834,10 +849,18 @@ void EmojiListWidget::drawRecent(
|
|||
int index) {
|
||||
_recentPainted = true;
|
||||
if (const auto emoji = std::get_if<EmojiPtr>(&_recent[index].id.data)) {
|
||||
drawEmoji(p, position, *emoji);
|
||||
if (_mode == Mode::EmojiStatus) {
|
||||
position += QPoint(
|
||||
(_singleSize.width() - st::stickersPremium.width()) / 2,
|
||||
(_singleSize.height() - st::stickersPremium.height()) / 2
|
||||
) - _areaPosition;
|
||||
p.drawImage(position, _premiumIcon->image());
|
||||
} else {
|
||||
drawEmoji(p, position, *emoji);
|
||||
}
|
||||
} else {
|
||||
Assert(_recent[index].custom != nullptr);
|
||||
position += _innerPosition;
|
||||
position += _innerPosition + _customPosition;
|
||||
_recent[index].custom->paint(
|
||||
p,
|
||||
position.x(),
|
||||
|
@ -868,7 +891,7 @@ void EmojiListWidget::drawCustom(
|
|||
bool paused,
|
||||
int set,
|
||||
int index) {
|
||||
position += _innerPosition;
|
||||
position += _innerPosition + _customPosition;
|
||||
_custom[set].painted = true;
|
||||
_custom[set].list[index].custom->paint(
|
||||
p,
|
||||
|
@ -897,7 +920,7 @@ EmojiPtr EmojiListWidget::lookupOverEmoji(const OverEmoji *over) const {
|
|||
&& v::is<EmojiPtr>(_recent[index].id.data))
|
||||
? v::get<EmojiPtr>(_recent[index].id.data)
|
||||
: (section > int(Section::Recent)
|
||||
&& section < kEmojiSectionCount
|
||||
&& section < _staticCount
|
||||
&& index < _emoji[section].size())
|
||||
? _emoji[section][index]
|
||||
: nullptr;
|
||||
|
@ -958,10 +981,10 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
|||
if (const auto over = std::get_if<OverEmoji>(&_selected)) {
|
||||
const auto section = over->section;
|
||||
const auto index = over->index;
|
||||
if (section >= kEmojiSectionCount
|
||||
if (section >= _staticCount
|
||||
&& sectionInfo(section).collapsed
|
||||
&& index + 1 == _columnCount * kCollapsedRows) {
|
||||
_custom[section - kEmojiSectionCount].expanded = true;
|
||||
_custom[section - _staticCount].expanded = true;
|
||||
resizeToWidth(width());
|
||||
update();
|
||||
return;
|
||||
|
@ -980,19 +1003,19 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
|||
if (custom && custom->sticker()) {
|
||||
selectCustom(custom);
|
||||
}
|
||||
} else if (section >= kEmojiSectionCount
|
||||
&& index < _custom[section - kEmojiSectionCount].list.size()) {
|
||||
auto &set = _custom[section - kEmojiSectionCount];
|
||||
} else if (section >= _staticCount
|
||||
&& index < _custom[section - _staticCount].list.size()) {
|
||||
auto &set = _custom[section - _staticCount];
|
||||
selectCustom(set.list[index].document);
|
||||
}
|
||||
} else if (const auto set = std::get_if<OverSet>(&pressed)) {
|
||||
Assert(set->section >= kEmojiSectionCount
|
||||
&& set->section < kEmojiSectionCount + _custom.size());
|
||||
displaySet(_custom[set->section - kEmojiSectionCount].id);
|
||||
Assert(set->section >= _staticCount
|
||||
&& set->section < _staticCount + _custom.size());
|
||||
displaySet(_custom[set->section - _staticCount].id);
|
||||
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
||||
Assert(button->section >= kEmojiSectionCount
|
||||
&& button->section < kEmojiSectionCount + _custom.size());
|
||||
const auto id = _custom[button->section - kEmojiSectionCount].id;
|
||||
Assert(button->section >= _staticCount
|
||||
&& button->section < _staticCount + _custom.size());
|
||||
const auto id = _custom[button->section - _staticCount].id;
|
||||
if (hasRemoveButton(button->section)) {
|
||||
removeSet(id);
|
||||
} else if (hasAddButton(button->section)) {
|
||||
|
@ -1074,11 +1097,11 @@ void EmojiListWidget::pickerHidden() {
|
|||
}
|
||||
|
||||
bool EmojiListWidget::hasRemoveButton(int index) const {
|
||||
if (index < kEmojiSectionCount
|
||||
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||
if (index < _staticCount
|
||||
|| index >= _staticCount + _custom.size()) {
|
||||
return false;
|
||||
}
|
||||
const auto &set = _custom[index - kEmojiSectionCount];
|
||||
const auto &set = _custom[index - _staticCount];
|
||||
return set.canRemove && !set.premiumRequired;
|
||||
}
|
||||
|
||||
|
@ -1096,11 +1119,11 @@ QRect EmojiListWidget::removeButtonRect(const SectionInfo &info) const {
|
|||
}
|
||||
|
||||
bool EmojiListWidget::hasAddButton(int index) const {
|
||||
if (index < kEmojiSectionCount
|
||||
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||
if (index < _staticCount
|
||||
|| index >= _staticCount + _custom.size()) {
|
||||
return false;
|
||||
}
|
||||
const auto &set = _custom[index - kEmojiSectionCount];
|
||||
const auto &set = _custom[index - _staticCount];
|
||||
return !set.canRemove && !set.premiumRequired;
|
||||
}
|
||||
|
||||
|
@ -1109,24 +1132,24 @@ QRect EmojiListWidget::addButtonRect(int index) const {
|
|||
}
|
||||
|
||||
bool EmojiListWidget::hasUnlockButton(int index) const {
|
||||
if (index < kEmojiSectionCount
|
||||
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||
if (index < _staticCount
|
||||
|| index >= _staticCount + _custom.size()) {
|
||||
return false;
|
||||
}
|
||||
const auto &set = _custom[index - kEmojiSectionCount];
|
||||
const auto &set = _custom[index - _staticCount];
|
||||
return set.premiumRequired;
|
||||
}
|
||||
|
||||
QRect EmojiListWidget::unlockButtonRect(int index) const {
|
||||
Expects(index >= kEmojiSectionCount
|
||||
&& index < kEmojiSectionCount + _custom.size());
|
||||
Expects(index >= _staticCount
|
||||
&& index < _staticCount + _custom.size());
|
||||
|
||||
return buttonRect(sectionInfo(index), rightButton(index));
|
||||
}
|
||||
|
||||
bool EmojiListWidget::hasButton(int index) const {
|
||||
if (index < kEmojiSectionCount
|
||||
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||
if (index < _staticCount
|
||||
|| index >= _staticCount + _custom.size()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1151,11 +1174,11 @@ QRect EmojiListWidget::buttonRect(
|
|||
}
|
||||
|
||||
auto EmojiListWidget::rightButton(int index) const -> const RightButton & {
|
||||
Expects(index >= kEmojiSectionCount
|
||||
&& index < kEmojiSectionCount + _custom.size());
|
||||
Expects(index >= _staticCount
|
||||
&& index < _staticCount + _custom.size());
|
||||
return hasAddButton(index)
|
||||
? _add
|
||||
: _custom[index - kEmojiSectionCount].canRemove
|
||||
: _custom[index - _staticCount].canRemove
|
||||
? _restore
|
||||
: _unlock;
|
||||
}
|
||||
|
@ -1187,7 +1210,7 @@ void EmojiListWidget::colorChosen(EmojiPtr emoji) {
|
|||
const auto over = std::get_if<OverEmoji>(&_pickerSelected);
|
||||
if (over
|
||||
&& over->section > int(Section::Recent)
|
||||
&& over->section < kEmojiSectionCount
|
||||
&& over->section < _staticCount
|
||||
&& over->index < _emoji[over->section].size()) {
|
||||
_emoji[over->section][over->index] = emoji;
|
||||
rtlupdate(emojiRect(over->section, over->index));
|
||||
|
@ -1466,7 +1489,8 @@ std::vector<StickerIcon> EmojiListWidget::fillIcons() {
|
|||
result.reserve(2 + _custom.size());
|
||||
|
||||
result.emplace_back(RecentEmojiSectionSetId());
|
||||
if (_custom.empty()) {
|
||||
if (_mode == Mode::EmojiStatus) {
|
||||
} else if (_custom.empty()) {
|
||||
using Section = Ui::Emoji::Section;
|
||||
for (auto i = int(Section::People); i <= int(Section::Symbols); ++i) {
|
||||
result.emplace_back(EmojiSectionSetId(Section(i)));
|
||||
|
@ -1489,11 +1513,11 @@ int EmojiListWidget::paintButtonGetWidth(
|
|||
const SectionInfo &info,
|
||||
bool selected,
|
||||
QRect clip) const {
|
||||
if (info.section < kEmojiSectionCount
|
||||
|| info.section >= kEmojiSectionCount + _custom.size()) {
|
||||
if (info.section < _staticCount
|
||||
|| info.section >= _staticCount + _custom.size()) {
|
||||
return 0;
|
||||
}
|
||||
auto &custom = _custom[info.section - kEmojiSectionCount];
|
||||
auto &custom = _custom[info.section - _staticCount];
|
||||
if (hasRemoveButton(info.section)) {
|
||||
const auto remove = removeButtonRect(info);
|
||||
if (remove.intersects(clip)) {
|
||||
|
@ -1565,7 +1589,7 @@ void EmojiListWidget::updateSelected() {
|
|||
if (hasButton(section)
|
||||
&& myrtlrect(buttonRect(section)).contains(p.x(), p.y())) {
|
||||
newSelected = OverButton{ section };
|
||||
} else if (section >= kEmojiSectionCount) {
|
||||
} else if (section >= _staticCount) {
|
||||
newSelected = OverSet{ section };
|
||||
}
|
||||
} else if (p.y() >= info.rowsTop && p.y() < info.rowsBottom) {
|
||||
|
@ -1616,18 +1640,18 @@ void EmojiListWidget::setSelected(OverState newSelected) {
|
|||
|
||||
void EmojiListWidget::setPressed(OverState newPressed) {
|
||||
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
||||
Assert(button->section >= kEmojiSectionCount
|
||||
&& button->section < kEmojiSectionCount + _custom.size());
|
||||
auto &set = _custom[button->section - kEmojiSectionCount];
|
||||
Assert(button->section >= _staticCount
|
||||
&& button->section < _staticCount + _custom.size());
|
||||
auto &set = _custom[button->section - _staticCount];
|
||||
if (set.ripple) {
|
||||
set.ripple->lastStop();
|
||||
}
|
||||
}
|
||||
_pressed = newPressed;
|
||||
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
||||
Assert(button->section >= kEmojiSectionCount
|
||||
&& button->section < kEmojiSectionCount + _custom.size());
|
||||
auto &set = _custom[button->section - kEmojiSectionCount];
|
||||
Assert(button->section >= _staticCount
|
||||
&& button->section < _staticCount + _custom.size());
|
||||
auto &set = _custom[button->section - _staticCount];
|
||||
if (!set.ripple) {
|
||||
set.ripple = createButtonRipple(button->section);
|
||||
}
|
||||
|
@ -1675,8 +1699,8 @@ void EmojiListWidget::initButton(
|
|||
|
||||
std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
||||
int section) {
|
||||
Expects(section >= kEmojiSectionCount
|
||||
&& section < kEmojiSectionCount + _custom.size());
|
||||
Expects(section >= _staticCount
|
||||
&& section < _staticCount + _custom.size());
|
||||
|
||||
const auto remove = hasRemoveButton(section);
|
||||
const auto &st = remove
|
||||
|
@ -1694,8 +1718,8 @@ std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
|||
}
|
||||
|
||||
QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
||||
Expects(section >= kEmojiSectionCount
|
||||
&& section < kEmojiSectionCount + _custom.size());
|
||||
Expects(section >= _staticCount
|
||||
&& section < _staticCount + _custom.size());
|
||||
|
||||
return myrtlrect(buttonRect(section)).topLeft()
|
||||
+ (hasRemoveButton(section)
|
||||
|
@ -1727,12 +1751,12 @@ void EmojiListWidget::showSet(uint64 setId) {
|
|||
}
|
||||
|
||||
uint64 EmojiListWidget::sectionSetId(int section) const {
|
||||
Expects(section < kEmojiSectionCount
|
||||
|| (section - kEmojiSectionCount) < _custom.size());
|
||||
Expects(section < _staticCount
|
||||
|| (section - _staticCount) < _custom.size());
|
||||
|
||||
return (section < kEmojiSectionCount)
|
||||
return (section < _staticCount)
|
||||
? EmojiSectionSetId(static_cast<Section>(section))
|
||||
: _custom[section - kEmojiSectionCount].id;
|
||||
: _custom[section - _staticCount].id;
|
||||
}
|
||||
|
||||
tr::phrase<> EmojiCategoryTitle(int index) {
|
||||
|
|
|
@ -50,16 +50,22 @@ inline constexpr auto kEmojiSectionCount = 8;
|
|||
struct StickerIcon;
|
||||
class EmojiColorPicker;
|
||||
class StickersListFooter;
|
||||
class GradientPremiumStar;
|
||||
class LocalStickersManager;
|
||||
|
||||
class EmojiListWidget
|
||||
: public TabbedSelector::Inner
|
||||
, public Ui::AbstractTooltipShower {
|
||||
public:
|
||||
enum class Mode {
|
||||
Full,
|
||||
EmojiStatus,
|
||||
};
|
||||
EmojiListWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
Window::GifPauseReason level);
|
||||
Window::GifPauseReason level,
|
||||
Mode mode);
|
||||
~EmojiListWidget();
|
||||
|
||||
using Section = Ui::Emoji::Section;
|
||||
|
@ -266,7 +272,10 @@ private:
|
|||
DocumentId documentId,
|
||||
uint64 setId);
|
||||
|
||||
Mode _mode = Mode::Full;
|
||||
const int _staticCount = 0;
|
||||
StickersListFooter *_footer = nullptr;
|
||||
std::unique_ptr<GradientPremiumStar> _premiumIcon;
|
||||
std::unique_ptr<LocalStickersManager> _localSetsManager;
|
||||
|
||||
int _counts[kEmojiSectionCount];
|
||||
|
@ -284,6 +293,7 @@ private:
|
|||
QSize _singleSize;
|
||||
QPoint _areaPosition;
|
||||
QPoint _innerPosition;
|
||||
QPoint _customPosition;
|
||||
|
||||
RightButton _add;
|
||||
RightButton _unlock;
|
||||
|
|
|
@ -145,6 +145,42 @@ bool StickersListFooter::ScrollState::animationCallback(crl::time now) {
|
|||
return true;
|
||||
}
|
||||
|
||||
GradientPremiumStar::GradientPremiumStar() {
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_image = QImage();
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
QImage GradientPremiumStar::image() const {
|
||||
if (_image.isNull()) {
|
||||
renderOnDemand();
|
||||
}
|
||||
return _image;
|
||||
}
|
||||
|
||||
void GradientPremiumStar::renderOnDemand() const {
|
||||
const auto size = st::stickersPremium.size();
|
||||
const auto mask = st::stickersPremium.instance(Qt::white);
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
_image = QImage(
|
||||
size * factor,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_image.setDevicePixelRatio(factor);
|
||||
|
||||
QPainter p(&_image);
|
||||
auto gradient = QLinearGradient(
|
||||
QPoint(0, size.height()),
|
||||
QPoint(size.width(), 0));
|
||||
gradient.setStops({
|
||||
{ 0., st::stickerPanPremium1->c },
|
||||
{ 1., st::stickerPanPremium2->c },
|
||||
});
|
||||
p.fillRect(QRect(QPoint(), size), gradient);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.drawImage(QRect(QPoint(), size), mask);
|
||||
}
|
||||
|
||||
StickersListFooter::StickersListFooter(Descriptor &&descriptor)
|
||||
: InnerFooter(descriptor.parent)
|
||||
, _controller(descriptor.controller)
|
||||
|
@ -169,36 +205,6 @@ StickersListFooter::StickersListFooter(Descriptor &&descriptor)
|
|||
) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}, lifetime());
|
||||
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
_premiumIcon = QImage();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void StickersListFooter::validatePremiumIcon() const {
|
||||
if (!_premiumIcon.isNull()) {
|
||||
return;
|
||||
}
|
||||
const auto size = st::stickersPremium.size();
|
||||
const auto mask = st::stickersPremium.instance(Qt::white);
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
_premiumIcon = QImage(
|
||||
size * factor,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_premiumIcon.setDevicePixelRatio(factor);
|
||||
|
||||
QPainter p(&_premiumIcon);
|
||||
auto gradient = QLinearGradient(
|
||||
QPoint(0, size.height()),
|
||||
QPoint(size.width(), 0));
|
||||
gradient.setStops({
|
||||
{ 0., st::stickerPanPremium1->c },
|
||||
{ 1., st::stickerPanPremium2->c },
|
||||
});
|
||||
p.fillRect(QRect(QPoint(), size), gradient);
|
||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
p.drawImage(QRect(QPoint(), size), mask);
|
||||
}
|
||||
|
||||
void StickersListFooter::clearHeavyData() {
|
||||
|
@ -1211,12 +1217,11 @@ void StickersListFooter::paintSetIcon(
|
|||
width(),
|
||||
st::stickerGroupCategorySize);
|
||||
} else if (icon.setId == Data::Stickers::PremiumSetId) {
|
||||
validatePremiumIcon();
|
||||
const auto size = st::stickersPremium.size();
|
||||
p.drawImage(
|
||||
info.adjustedLeft + (_singleWidth - size.width()) / 2,
|
||||
_iconsTop + (st::emojiFooterHeight - size.height()) / 2,
|
||||
_premiumIcon);
|
||||
_premiumIcon.image());
|
||||
} else {
|
||||
using Section = Ui::Emoji::Section;
|
||||
const auto sectionIcon = [&](Section section, bool active) {
|
||||
|
|
|
@ -75,6 +75,20 @@ struct StickerIcon {
|
|||
mutable rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
class GradientPremiumStar {
|
||||
public:
|
||||
GradientPremiumStar();
|
||||
|
||||
[[nodiscard]] QImage image() const;
|
||||
|
||||
private:
|
||||
void renderOnDemand() const;
|
||||
|
||||
mutable QImage _image;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
class StickersListFooter final : public TabbedSelector::InnerFooter {
|
||||
public:
|
||||
struct Descriptor {
|
||||
|
@ -203,7 +217,6 @@ private:
|
|||
void paintSelectionBg(Painter &p) const;
|
||||
void paintSelectionBar(Painter &p) const;
|
||||
void paintLeftRightFading(Painter &p) const;
|
||||
void validatePremiumIcon() const;
|
||||
|
||||
void updateEmojiSectionWidth();
|
||||
void updateEmojiWidthCallback();
|
||||
|
@ -230,7 +243,7 @@ private:
|
|||
OverState _pressed = SpecialOver::None;
|
||||
|
||||
QPoint _iconsMousePos, _iconsMouseDown;
|
||||
mutable QImage _premiumIcon;
|
||||
GradientPremiumStar _premiumIcon;
|
||||
int _iconsLeft = 0;
|
||||
int _iconsRight = 0;
|
||||
int _iconsTop = 0;
|
||||
|
|
|
@ -132,7 +132,19 @@ void TabbedPanel::moveBottomRight(int bottom, int right) {
|
|||
_right = right;
|
||||
// If the panel is already shown, update the position.
|
||||
if (!isHidden() && isNew) {
|
||||
moveByBottom();
|
||||
moveHorizontally();
|
||||
} else {
|
||||
updateContentHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void TabbedPanel::moveTopRight(int top, int right) {
|
||||
const auto isNew = (_top != top || _right != right);
|
||||
_top = top;
|
||||
_right = right;
|
||||
// If the panel is already shown, update the position.
|
||||
if (!isHidden() && isNew) {
|
||||
moveHorizontally();
|
||||
} else {
|
||||
updateContentHeight();
|
||||
}
|
||||
|
@ -148,16 +160,26 @@ void TabbedPanel::setDesiredHeightValues(
|
|||
updateContentHeight();
|
||||
}
|
||||
|
||||
void TabbedPanel::setDropDown(bool dropDown) {
|
||||
selector()->setDropDown(dropDown);
|
||||
_dropDown = dropDown;
|
||||
}
|
||||
|
||||
void TabbedPanel::updateContentHeight() {
|
||||
auto addedHeight = innerPadding().top() + innerPadding().bottom();
|
||||
auto marginsHeight = _selector->marginTop() + _selector->marginBottom();
|
||||
auto availableHeight = _bottom - marginsHeight;
|
||||
auto wantedContentHeight = qRound(_heightRatio * availableHeight) - addedHeight;
|
||||
auto availableHeight = _dropDown
|
||||
? (parentWidget()->height() - _top - marginsHeight)
|
||||
: (_bottom - marginsHeight);
|
||||
auto wantedContentHeight = qRound(_heightRatio * availableHeight)
|
||||
- addedHeight;
|
||||
auto contentHeight = marginsHeight + std::clamp(
|
||||
wantedContentHeight,
|
||||
_minContentHeight,
|
||||
_maxContentHeight);
|
||||
auto resultTop = _bottom - addedHeight - contentHeight;
|
||||
auto resultTop = _dropDown
|
||||
? _top
|
||||
: (_bottom - addedHeight - contentHeight);
|
||||
if (contentHeight == _contentHeight) {
|
||||
move(x(), resultTop);
|
||||
return;
|
||||
|
@ -204,7 +226,7 @@ void TabbedPanel::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void TabbedPanel::moveByBottom() {
|
||||
void TabbedPanel::moveHorizontally() {
|
||||
const auto right = std::max(parentWidget()->width() - _right, 0);
|
||||
moveToRight(right, y());
|
||||
updateContentHeight();
|
||||
|
@ -318,7 +340,7 @@ void TabbedPanel::startShowAnimation() {
|
|||
if (!_a_show.animating()) {
|
||||
auto image = grabForAnimation();
|
||||
|
||||
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomRight);
|
||||
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, _dropDown ? Ui::PanelAnimation::Origin::TopRight : Ui::PanelAnimation::Origin::BottomRight);
|
||||
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
||||
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
||||
_showAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||
|
@ -402,7 +424,7 @@ void TabbedPanel::showStarted() {
|
|||
}
|
||||
if (isHidden()) {
|
||||
_selector->showStarted();
|
||||
moveByBottom();
|
||||
moveHorizontally();
|
||||
raise();
|
||||
show();
|
||||
startShowAnimation();
|
||||
|
@ -424,7 +446,7 @@ bool TabbedPanel::eventFilter(QObject *obj, QEvent *e) {
|
|||
|
||||
void TabbedPanel::showFromSelector() {
|
||||
if (isHidden()) {
|
||||
moveByBottom();
|
||||
moveHorizontally();
|
||||
startShowAnimation();
|
||||
show();
|
||||
}
|
||||
|
|
|
@ -41,10 +41,12 @@ public:
|
|||
[[nodiscard]] not_null<TabbedSelector*> selector() const;
|
||||
|
||||
void moveBottomRight(int bottom, int right);
|
||||
void moveTopRight(int top, int right);
|
||||
void setDesiredHeightValues(
|
||||
float64 ratio,
|
||||
int minHeight,
|
||||
int maxHeight);
|
||||
void setDropDown(bool dropDown);
|
||||
|
||||
void hideFast();
|
||||
bool hiding() const {
|
||||
|
@ -76,7 +78,7 @@ private:
|
|||
TabbedSelector *nonOwnedSelector);
|
||||
|
||||
void hideByTimerOrLeave();
|
||||
void moveByBottom();
|
||||
void moveHorizontally();
|
||||
void showFromSelector();
|
||||
|
||||
style::margins innerPadding() const;
|
||||
|
@ -103,6 +105,7 @@ private:
|
|||
|
||||
int _contentMaxHeight = 0;
|
||||
int _contentHeight = 0;
|
||||
int _top = 0;
|
||||
int _bottom = 0;
|
||||
int _right = 0;
|
||||
float64 _heightRatio = 1.;
|
||||
|
@ -113,6 +116,7 @@ private:
|
|||
Ui::Animations::Simple _a_show;
|
||||
|
||||
bool _shouldFinishHide = false;
|
||||
bool _dropDown = false;
|
||||
|
||||
bool _hiding = false;
|
||||
bool _hideAfterSlide = false;
|
||||
|
|
|
@ -439,7 +439,14 @@ TabbedSelector::Tab TabbedSelector::createTab(SelectorTab type, int index) {
|
|||
auto createWidget = [&]() -> object_ptr<Inner> {
|
||||
switch (type) {
|
||||
case SelectorTab::Emoji:
|
||||
return object_ptr<EmojiListWidget>(this, _controller, _level);
|
||||
using EmojiMode = EmojiListWidget::Mode;
|
||||
return object_ptr<EmojiListWidget>(
|
||||
this,
|
||||
_controller,
|
||||
_level,
|
||||
(_mode == Mode::EmojiStatus
|
||||
? EmojiMode::EmojiStatus
|
||||
: EmojiMode::Full));
|
||||
case SelectorTab::Stickers:
|
||||
return object_ptr<StickersListWidget>(this, _controller, _level);
|
||||
case SelectorTab::Gifs:
|
||||
|
@ -561,7 +568,7 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
|||
}
|
||||
|
||||
auto scrollWidth = width() - st::roundRadiusSmall;
|
||||
auto scrollHeight = height() - scrollTop() - marginBottom();
|
||||
auto scrollHeight = height() - scrollTop() - scrollBottom();
|
||||
auto inner = currentTab()->widget();
|
||||
auto innerWidth = scrollWidth - st::emojiScroll.width;
|
||||
auto updateScrollGeometry = [&] {
|
||||
|
@ -591,7 +598,7 @@ void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
|||
st::lineWidth);
|
||||
updateRestrictedLabelGeometry();
|
||||
|
||||
_footerTop = height() - st::emojiFooterHeight;
|
||||
_footerTop = _dropDown ? 0 : (height() - st::emojiFooterHeight);
|
||||
for (auto &tab : _tabs) {
|
||||
tab.footer()->resizeToWidth(width());
|
||||
tab.footer()->moveToLeft(0, _footerTop);
|
||||
|
@ -630,21 +637,7 @@ void TabbedSelector::paintEvent(QPaintEvent *e) {
|
|||
|
||||
void TabbedSelector::paintSlideFrame(Painter &p) {
|
||||
if (_roundRadius > 0) {
|
||||
const auto topPart = QRect(
|
||||
0,
|
||||
0,
|
||||
width(),
|
||||
_tabsSlider
|
||||
? _tabsSlider->height() + _roundRadius
|
||||
: 3 * _roundRadius);
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
topPart,
|
||||
st::emojiPanBg,
|
||||
ImageRoundRadius::Small,
|
||||
tabbed()
|
||||
? RectPart::FullTop | RectPart::NoTopBottom
|
||||
: RectPart::FullTop);
|
||||
paintBgRoundedPart(p);
|
||||
} else if (_tabsSlider) {
|
||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||
}
|
||||
|
@ -652,43 +645,53 @@ void TabbedSelector::paintSlideFrame(Painter &p) {
|
|||
_slideAnimation->paintFrame(p, slideDt, 1.);
|
||||
}
|
||||
|
||||
void TabbedSelector::paintContent(Painter &p) {
|
||||
auto &bottomBg = hasSectionIcons()
|
||||
? st::emojiPanCategories
|
||||
: st::emojiPanBg;
|
||||
if (_roundRadius > 0) {
|
||||
const auto topPart = QRect(
|
||||
void TabbedSelector::paintBgRoundedPart(Painter &p) {
|
||||
const auto threeRadius = 3 * _roundRadius;
|
||||
const auto topOrBottomPart = _dropDown
|
||||
? QRect(0, height() - threeRadius, width(), threeRadius)
|
||||
: QRect(
|
||||
0,
|
||||
0,
|
||||
width(),
|
||||
_tabsSlider
|
||||
(_tabsSlider
|
||||
? _tabsSlider->height() + _roundRadius
|
||||
: 3 * _roundRadius);
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
topPart,
|
||||
st::emojiPanBg,
|
||||
ImageRoundRadius::Small,
|
||||
tabbed()
|
||||
? RectPart::FullTop | RectPart::NoTopBottom
|
||||
: RectPart::FullTop);
|
||||
: threeRadius));
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
topOrBottomPart,
|
||||
st::emojiPanBg,
|
||||
ImageRoundRadius::Small,
|
||||
(_dropDown
|
||||
? RectPart::FullBottom
|
||||
: tabbed()
|
||||
? (RectPart::FullTop | RectPart::NoTopBottom)
|
||||
: RectPart::FullTop));
|
||||
}
|
||||
|
||||
const auto bottomPart = QRect(
|
||||
void TabbedSelector::paintContent(Painter &p) {
|
||||
auto &footerBg = hasSectionIcons()
|
||||
? st::emojiPanCategories
|
||||
: st::emojiPanBg;
|
||||
if (_roundRadius > 0) {
|
||||
paintBgRoundedPart(p);
|
||||
|
||||
const auto footerPart = QRect(
|
||||
0,
|
||||
_footerTop - _roundRadius,
|
||||
_footerTop - (_dropDown ? 0 : _roundRadius),
|
||||
width(),
|
||||
st::emojiFooterHeight + _roundRadius);
|
||||
Ui::FillRoundRect(
|
||||
p,
|
||||
bottomPart,
|
||||
bottomBg,
|
||||
footerPart,
|
||||
footerBg,
|
||||
ImageRoundRadius::Small,
|
||||
RectPart::NoTopBottom | RectPart::FullBottom);
|
||||
(RectPart::NoTopBottom
|
||||
| (_dropDown ? RectPart::FullTop : RectPart::FullBottom)));
|
||||
} else {
|
||||
if (_tabsSlider) {
|
||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||
}
|
||||
p.fillRect(0, _footerTop, width(), st::emojiFooterHeight, bottomBg);
|
||||
p.fillRect(0, _footerTop, width(), st::emojiFooterHeight, footerBg);
|
||||
}
|
||||
|
||||
auto sidesTop = marginTop();
|
||||
|
@ -710,17 +713,23 @@ void TabbedSelector::paintContent(Painter &p) {
|
|||
}
|
||||
|
||||
int TabbedSelector::marginTop() const {
|
||||
return _tabsSlider
|
||||
return _dropDown
|
||||
? st::emojiFooterHeight
|
||||
: _tabsSlider
|
||||
? (_tabsSlider->height() - st::lineWidth)
|
||||
: _roundRadius;
|
||||
}
|
||||
|
||||
int TabbedSelector::scrollTop() const {
|
||||
return tabbed() ? marginTop() : 0;
|
||||
return tabbed() ? marginTop() : _dropDown ? st::emojiFooterHeight : 0;
|
||||
}
|
||||
|
||||
int TabbedSelector::marginBottom() const {
|
||||
return st::emojiFooterHeight;
|
||||
return _dropDown ? _roundRadius : st::emojiFooterHeight;
|
||||
}
|
||||
|
||||
int TabbedSelector::scrollBottom() const {
|
||||
return _dropDown ? 0 : marginBottom();
|
||||
}
|
||||
|
||||
void TabbedSelector::refreshStickers() {
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
Full,
|
||||
EmojiOnly,
|
||||
MediaEditor,
|
||||
EmojiStatus,
|
||||
};
|
||||
enum class Action {
|
||||
Update,
|
||||
|
@ -110,9 +111,10 @@ public:
|
|||
void beforeHiding();
|
||||
void afterShown();
|
||||
|
||||
int marginTop() const;
|
||||
int marginBottom() const;
|
||||
int scrollTop() const;
|
||||
[[nodiscard]] int marginTop() const;
|
||||
[[nodiscard]] int marginBottom() const;
|
||||
[[nodiscard]] int scrollTop() const;
|
||||
[[nodiscard]] int scrollBottom() const;
|
||||
|
||||
bool preventAutoHide() const;
|
||||
bool isSliding() const {
|
||||
|
@ -128,6 +130,9 @@ public:
|
|||
}
|
||||
|
||||
void showMenuWithType(SendMenu::Type type);
|
||||
void setDropDown(bool dropDown) {
|
||||
_dropDown = dropDown;
|
||||
}
|
||||
|
||||
// Float player interface.
|
||||
bool floatPlayerHandleWheelEvent(QEvent *e);
|
||||
|
@ -193,6 +198,7 @@ private:
|
|||
Tab createTab(SelectorTab type, int index);
|
||||
|
||||
void paintSlideFrame(Painter &p);
|
||||
void paintBgRoundedPart(Painter &p);
|
||||
void paintContent(Painter &p);
|
||||
|
||||
void checkRestrictedPeer();
|
||||
|
@ -252,6 +258,7 @@ private:
|
|||
const bool _hasGifsTab;
|
||||
const bool _hasMasksTab;
|
||||
const bool _tabbed;
|
||||
bool _dropDown = false;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/text/text_block.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/unread_badge.h"
|
||||
|
@ -215,29 +216,25 @@ void Cover::setBadge(Badge badge, DocumentId emojiStatusId) {
|
|||
_badge = badge;
|
||||
_emojiStatusId = emojiStatusId;
|
||||
_emojiStatus = nullptr;
|
||||
_verifiedCheck.destroy();
|
||||
_scamFakeBadge.destroy();
|
||||
_badgeView.destroy();
|
||||
switch (_badge) {
|
||||
case Badge::Verified:
|
||||
case Badge::Premium: {
|
||||
const auto icon = (_badge == Badge::Verified)
|
||||
? &st::infoVerifiedCheck
|
||||
: &st::infoPremiumStar;
|
||||
_verifiedCheck.create(this);
|
||||
_verifiedCheck->show();
|
||||
_verifiedCheck->resize(icon->size());
|
||||
_badgeView.create(this);
|
||||
_badgeView->show();
|
||||
if (_emojiStatusId) {
|
||||
auto &owner = _controller->session().data();
|
||||
_emojiStatus = owner.customEmojiManager().create(
|
||||
_emojiStatusId,
|
||||
[raw = _verifiedCheck.data()]{ raw->update(); },
|
||||
Data::CustomEmojiManager::SizeTag::Normal);
|
||||
}
|
||||
|
||||
_verifiedCheck->paintRequest(
|
||||
) | rpl::start_with_next([=, check = _verifiedCheck.data()] {
|
||||
Painter p(check);
|
||||
if (_emojiStatus) {
|
||||
[raw = _badgeView.data()]{ raw->update(); },
|
||||
Data::CustomEmojiManager::SizeTag::Large);
|
||||
const auto size = Ui::Emoji::GetSizeLarge()
|
||||
/ style::DevicePixelRatio();
|
||||
const auto emoji = Ui::Text::AdjustCustomEmojiSize(size);
|
||||
_badgeView->resize(emoji, emoji);
|
||||
_badgeView->paintRequest(
|
||||
) | rpl::start_with_next([=, check = _badgeView.data()]{
|
||||
Painter p(check);
|
||||
_emojiStatus->paint(
|
||||
p,
|
||||
0,
|
||||
|
@ -246,24 +243,17 @@ void Cover::setBadge(Badge badge, DocumentId emojiStatusId) {
|
|||
st::windowBgOver->c,
|
||||
_controller->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::Layer));
|
||||
} else {
|
||||
icon->paint(p, 0, 0, check->width());
|
||||
}
|
||||
}, _verifiedCheck->lifetime());
|
||||
|
||||
if (_badge == Badge::Premium) {
|
||||
const auto userId = peerToUser(_peer->id).bare;
|
||||
_verifiedCheck->setClickedCallback([=] {
|
||||
if (_peer->isSelf()) {
|
||||
showEmojiStatusSelector();
|
||||
} else {
|
||||
::Settings::ShowPremium(
|
||||
_controller,
|
||||
u"profile__%1"_q.arg(userId));
|
||||
}
|
||||
});
|
||||
}, _badgeView->lifetime());
|
||||
} else {
|
||||
_verifiedCheck->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
const auto icon = (_badge == Badge::Verified)
|
||||
? &st::infoVerifiedCheck
|
||||
: &st::infoPremiumStar;
|
||||
_badgeView->resize(icon->size());
|
||||
_badgeView->paintRequest(
|
||||
) | rpl::start_with_next([=, check = _badgeView.data()]{
|
||||
Painter p(check);
|
||||
icon->paint(p, 0, 0, check->width());
|
||||
}, _badgeView->lifetime());
|
||||
}
|
||||
} break;
|
||||
case Badge::Scam:
|
||||
|
@ -271,13 +261,13 @@ void Cover::setBadge(Badge badge, DocumentId emojiStatusId) {
|
|||
const auto fake = (_badge == Badge::Fake);
|
||||
const auto size = Ui::ScamBadgeSize(fake);
|
||||
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||
_scamFakeBadge.create(this);
|
||||
_scamFakeBadge->show();
|
||||
_scamFakeBadge->resize(
|
||||
_badgeView.create(this);
|
||||
_badgeView->show();
|
||||
_badgeView->resize(
|
||||
size.width() + 2 * skip,
|
||||
size.height() + 2 * skip);
|
||||
_scamFakeBadge->paintRequest(
|
||||
) | rpl::start_with_next([=, badge = _scamFakeBadge.data()]{
|
||||
_badgeView->paintRequest(
|
||||
) | rpl::start_with_next([=, badge = _badgeView.data()]{
|
||||
Painter p(badge);
|
||||
Ui::DrawScamBadge(
|
||||
fake,
|
||||
|
@ -285,28 +275,51 @@ void Cover::setBadge(Badge badge, DocumentId emojiStatusId) {
|
|||
badge->rect().marginsRemoved({ skip, skip, skip, skip }),
|
||||
badge->width(),
|
||||
st::attentionButtonFg);
|
||||
}, _scamFakeBadge->lifetime());
|
||||
}, _badgeView->lifetime());
|
||||
} break;
|
||||
}
|
||||
|
||||
if (_badge == Badge::Premium) {
|
||||
const auto userId = peerToUser(_peer->id).bare;
|
||||
_badgeView->setClickedCallback([=] {
|
||||
if (_peer->isSelf()) {
|
||||
showEmojiStatusSelector();
|
||||
} else {
|
||||
::Settings::ShowPremium(
|
||||
_controller,
|
||||
u"profile__%1"_q.arg(userId));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_badgeView->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
}
|
||||
|
||||
refreshNameGeometry(width());
|
||||
}
|
||||
|
||||
void Cover::showEmojiStatusSelector() {
|
||||
Expects(_verifiedCheck != nullptr);
|
||||
Expects(_badgeView != nullptr);
|
||||
|
||||
if (!_emojiStatusPanel) {
|
||||
createEmojiStatusSelector();
|
||||
}
|
||||
const auto parent = _emojiStatusPanel->parentWidget();
|
||||
const auto global = _verifiedCheck->mapToGlobal({ 0, 0 });
|
||||
const auto global = _badgeView->mapToGlobal({ 0, 0 });
|
||||
const auto local = parent->mapFromGlobal(global);
|
||||
_emojiStatusPanel->moveBottomRight(
|
||||
local.y(),
|
||||
local.x() + _verifiedCheck->width() * 3);
|
||||
_emojiStatusPanel->moveTopRight(
|
||||
local.y() + _badgeView->height(),
|
||||
local.x() + _badgeView->width() * 3);
|
||||
_emojiStatusPanel->toggleAnimated();
|
||||
}
|
||||
|
||||
void Cover::createEmojiStatusSelector() {
|
||||
const auto set = [=](DocumentId id) {
|
||||
_controller->session().user()->setEmojiStatus(id);
|
||||
_controller->session().api().request(MTPaccount_UpdateEmojiStatus(
|
||||
id ? MTP_emojiStatus(MTP_long(id)) : MTP_emojiStatusEmpty()
|
||||
)).send();
|
||||
_emojiStatusPanel->hideAnimated();
|
||||
};
|
||||
const auto container = _controller->window().widget()->bodyWidget();
|
||||
using Selector = ChatHelpers::TabbedSelector;
|
||||
_emojiStatusPanel = base::make_unique_q<ChatHelpers::TabbedPanel>(
|
||||
|
@ -316,20 +329,21 @@ void Cover::createEmojiStatusSelector() {
|
|||
nullptr,
|
||||
_controller,
|
||||
Window::GifPauseReason::Layer,
|
||||
ChatHelpers::TabbedSelector::Mode::EmojiOnly));
|
||||
ChatHelpers::TabbedSelector::Mode::EmojiStatus));
|
||||
_emojiStatusPanel->setDropDown(true);
|
||||
_emojiStatusPanel->setDesiredHeightValues(
|
||||
1.,
|
||||
st::emojiPanMinHeight / 2,
|
||||
st::emojiPanMinHeight);
|
||||
_emojiStatusPanel->hide();
|
||||
_emojiStatusPanel->selector()->setAllowEmojiWithoutPremium(false);
|
||||
_emojiStatusPanel->selector()->emojiChosen(
|
||||
) | rpl::start_with_next([=] {
|
||||
set(0);
|
||||
}, _emojiStatusPanel->lifetime());
|
||||
_emojiStatusPanel->selector()->customEmojiChosen(
|
||||
) | rpl::start_with_next([=](Selector::FileChosen data) {
|
||||
_controller->session().user()->setEmojiStatus(data.document->id);
|
||||
_controller->session().api().request(MTPaccount_UpdateEmojiStatus(
|
||||
MTP_emojiStatus(MTP_long(data.document->id))
|
||||
)).send();
|
||||
_emojiStatusPanel->hideAnimated();
|
||||
set(data.document->id);
|
||||
}, _emojiStatusPanel->lifetime());
|
||||
_emojiStatusPanel->selector()->showPromoForPremiumEmoji();
|
||||
}
|
||||
|
@ -392,31 +406,22 @@ void Cover::refreshNameGeometry(int newWidth) {
|
|||
auto nameWidth = newWidth
|
||||
- nameLeft
|
||||
- st::infoProfileNameRight;
|
||||
if (_verifiedCheck) {
|
||||
nameWidth -= st::infoVerifiedCheckPosition.x()
|
||||
+ _verifiedCheck->width();
|
||||
} else if (_scamFakeBadge) {
|
||||
nameWidth -= st::infoVerifiedCheckPosition.x()
|
||||
+ _scamFakeBadge->width();
|
||||
if (_badgeView) {
|
||||
nameWidth -= st::infoVerifiedCheckPosition.x() + _badgeView->width();
|
||||
}
|
||||
_name->resizeToNaturalWidth(nameWidth);
|
||||
_name->moveToLeft(nameLeft, nameTop, newWidth);
|
||||
if (_verifiedCheck) {
|
||||
const auto checkLeft = nameLeft
|
||||
+ _name->width()
|
||||
+ st::infoVerifiedCheckPosition.x();
|
||||
const auto checkTop = nameTop
|
||||
+ st::infoVerifiedCheckPosition.y();
|
||||
_verifiedCheck->moveToLeft(checkLeft, checkTop, newWidth);
|
||||
} else if (_scamFakeBadge) {
|
||||
const auto skip = st::infoVerifiedCheckPosition.x();
|
||||
const auto badgeLeft = nameLeft
|
||||
+ _name->width()
|
||||
+ st::infoVerifiedCheckPosition.x()
|
||||
- skip;
|
||||
if (_badgeView) {
|
||||
const auto star = !_emojiStatus
|
||||
&& (_badge == Badge::Premium || _badge == Badge::Verified);
|
||||
const auto fake = !_emojiStatus && !star;
|
||||
const auto skip = fake ? 0 : st::infoVerifiedCheckPosition.x();
|
||||
const auto badgeLeft = nameLeft + _name->width() + skip;
|
||||
const auto badgeTop = nameTop
|
||||
+ (_name->height() - _scamFakeBadge->height()) / 2;
|
||||
_scamFakeBadge->moveToLeft(badgeLeft, badgeTop, newWidth);
|
||||
+ (star
|
||||
? st::infoVerifiedCheckPosition.y()
|
||||
: (_name->height() - _badgeView->height()) / 2);
|
||||
_badgeView->moveToLeft(badgeLeft, badgeTop, newWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,8 +82,7 @@ private:
|
|||
|
||||
object_ptr<Ui::UserpicButton> _userpic;
|
||||
object_ptr<Ui::FlatLabel> _name = { nullptr };
|
||||
object_ptr<Ui::AbstractButton> _verifiedCheck = { nullptr };
|
||||
object_ptr<Ui::RpWidget> _scamFakeBadge = { nullptr };
|
||||
object_ptr<Ui::AbstractButton> _badgeView = { nullptr };
|
||||
object_ptr<Ui::FlatLabel> _status = { nullptr };
|
||||
//object_ptr<CoverDropArea> _dropArea = { nullptr };
|
||||
base::Timer _refreshStatusTimer;
|
||||
|
|
Loading…
Add table
Reference in a new issue