Allow choosing emoji color for all emoji.
This commit is contained in:
parent
ecaf3340f6
commit
ed9028e1c4
BIN
Telegram/Resources/icons/emoji/emoji_skin.png
Normal file
BIN
Telegram/Resources/icons/emoji/emoji_skin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 412 B |
BIN
Telegram/Resources/icons/emoji/emoji_skin@2x.png
Normal file
BIN
Telegram/Resources/icons/emoji/emoji_skin@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 698 B |
BIN
Telegram/Resources/icons/emoji/emoji_skin@3x.png
Normal file
BIN
Telegram/Resources/icons/emoji/emoji_skin@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 952 B |
|
@ -1807,6 +1807,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_emoji_set_active" = "Current set";
|
"lng_emoji_set_active" = "Current set";
|
||||||
"lng_emoji_set_download" = "Download {size}";
|
"lng_emoji_set_download" = "Download {size}";
|
||||||
"lng_emoji_set_loading" = "{percent}, {progress}";
|
"lng_emoji_set_loading" = "{percent}, {progress}";
|
||||||
|
"lng_emoji_color_all" = "Choose color for all emoji";
|
||||||
|
|
||||||
"lng_recent_stickers" = "Frequently used";
|
"lng_recent_stickers" = "Frequently used";
|
||||||
"lng_faved_stickers_add" = "Add to Favorites";
|
"lng_faved_stickers_add" = "Add to Favorites";
|
||||||
|
|
|
@ -118,6 +118,8 @@ EmojiPan {
|
||||||
tabs: SettingsSlider;
|
tabs: SettingsSlider;
|
||||||
search: TabbedSearch;
|
search: TabbedSearch;
|
||||||
searchMargin: margins;
|
searchMargin: margins;
|
||||||
|
colorAll: IconButton;
|
||||||
|
colorAllLabel: FlatLabel;
|
||||||
removeSet: IconButton;
|
removeSet: IconButton;
|
||||||
boxLabel: FlatLabel;
|
boxLabel: FlatLabel;
|
||||||
icons: ComposeIcons;
|
icons: ComposeIcons;
|
||||||
|
@ -448,6 +450,7 @@ inlineResultsMaxHeight: 640px;
|
||||||
emojiPanHeaderFont: semiboldFont;
|
emojiPanHeaderFont: semiboldFont;
|
||||||
emojiPanRemoveSkip: 10px;
|
emojiPanRemoveSkip: 10px;
|
||||||
emojiPanRemoveTop: 10px;
|
emojiPanRemoveTop: 10px;
|
||||||
|
emojiPanColorAllSkip: 9px;
|
||||||
|
|
||||||
emojiColorsPadding: 5px;
|
emojiColorsPadding: 5px;
|
||||||
emojiColorsSep: 1px;
|
emojiColorsSep: 1px;
|
||||||
|
@ -490,6 +493,25 @@ stickerIconMove: 400;
|
||||||
stickerPreviewDuration: 150;
|
stickerPreviewDuration: 150;
|
||||||
stickerPreviewMin: 0.1;
|
stickerPreviewMin: 0.1;
|
||||||
|
|
||||||
|
emojiPanColorAll: IconButton(stickerPanRemoveSet) {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
rippleAreaSize: 24px;
|
||||||
|
icon: icon {{ "emoji/emoji_skin", smallCloseIconFg }};
|
||||||
|
iconOver: icon {{ "emoji/emoji_skin", smallCloseIconFgOver }};
|
||||||
|
}
|
||||||
|
emojiPanColorAllLabel: FlatLabel(defaultFlatLabel) {
|
||||||
|
textFg: windowSubTextFg;
|
||||||
|
align: align(top);
|
||||||
|
minWidth: 40px;
|
||||||
|
style: TextStyle(defaultTextStyle) {
|
||||||
|
font: font(12px);
|
||||||
|
linkFont: font(12px);
|
||||||
|
linkFontOver: font(12px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emojiPanColorAllPadding: margins(10px, 6px, 10px, -1px);
|
||||||
|
|
||||||
stickerGroupCategorySize: 28px;
|
stickerGroupCategorySize: 28px;
|
||||||
stickerGroupCategoryAbout: defaultTextStyle;
|
stickerGroupCategoryAbout: defaultTextStyle;
|
||||||
stickerGroupCategoryAddMargin: margins(0px, 10px, 0px, 5px);
|
stickerGroupCategoryAddMargin: margins(0px, 10px, 0px, 5px);
|
||||||
|
@ -626,6 +648,8 @@ defaultEmojiPan: EmojiPan {
|
||||||
tabs: emojiTabs;
|
tabs: emojiTabs;
|
||||||
search: defaultTabbedSearch;
|
search: defaultTabbedSearch;
|
||||||
searchMargin: margins(1px, 11px, 2px, 5px);
|
searchMargin: margins(1px, 11px, 2px, 5px);
|
||||||
|
colorAll: emojiPanColorAll;
|
||||||
|
colorAllLabel: emojiPanColorAllLabel;
|
||||||
removeSet: stickerPanRemoveSet;
|
removeSet: stickerPanRemoveSet;
|
||||||
boxLabel: boxLabel;
|
boxLabel: boxLabel;
|
||||||
icons: defaultComposeIcons;
|
icons: defaultComposeIcons;
|
||||||
|
|
|
@ -672,17 +672,9 @@ std::vector<Result> EmojiKeywords::PrioritizeRecent(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Result> EmojiKeywords::ApplyVariants(std::vector<Result> list) {
|
std::vector<Result> EmojiKeywords::ApplyVariants(std::vector<Result> list) {
|
||||||
|
auto &settings = Core::App().settings();
|
||||||
for (auto &item : list) {
|
for (auto &item : list) {
|
||||||
item.emoji = [&] {
|
item.emoji = settings.lookupEmojiVariant(item.emoji);
|
||||||
const auto result = item.emoji;
|
|
||||||
const auto &variants = Core::App().settings().emojiVariants();
|
|
||||||
const auto i = result->hasVariants()
|
|
||||||
? variants.find(result->nonColoredId())
|
|
||||||
: end(variants);
|
|
||||||
return (i != end(variants))
|
|
||||||
? result->variant(i->second)
|
|
||||||
: result;
|
|
||||||
}();
|
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ class EmojiColorPicker final : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
EmojiColorPicker(QWidget *parent, const style::EmojiPan &st);
|
EmojiColorPicker(QWidget *parent, const style::EmojiPan &st);
|
||||||
|
|
||||||
void showEmoji(EmojiPtr emoji);
|
void showEmoji(EmojiPtr emoji, bool allLabel = false);
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
void handleMouseMove(QPoint globalPos);
|
void handleMouseMove(QPoint globalPos);
|
||||||
|
@ -79,8 +79,10 @@ protected:
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void createAllLabel();
|
||||||
void animationCallback();
|
void animationCallback();
|
||||||
void updateSize();
|
void updateSize();
|
||||||
|
[[nodiscard]] int topColorAllSkip() const;
|
||||||
|
|
||||||
void drawVariant(QPainter &p, int variant);
|
void drawVariant(QPainter &p, int variant);
|
||||||
|
|
||||||
|
@ -106,6 +108,8 @@ private:
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
Ui::Animations::Simple _a_opacity;
|
Ui::Animations::Simple _a_opacity;
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::FlatLabel> _allLabel;
|
||||||
|
|
||||||
rpl::event_stream<EmojiChosen> _chosen;
|
rpl::event_stream<EmojiChosen> _chosen;
|
||||||
rpl::event_stream<> _hidden;
|
rpl::event_stream<> _hidden;
|
||||||
|
|
||||||
|
@ -131,10 +135,15 @@ EmojiColorPicker::EmojiColorPicker(
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::showEmoji(EmojiPtr emoji) {
|
void EmojiColorPicker::showEmoji(EmojiPtr emoji, bool allLabel) {
|
||||||
if (!emoji || !emoji->hasVariants()) {
|
if (!emoji || !emoji->hasVariants()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!allLabel) {
|
||||||
|
_allLabel = nullptr;
|
||||||
|
} else if (!_allLabel) {
|
||||||
|
createAllLabel();
|
||||||
|
}
|
||||||
_ignoreShow = false;
|
_ignoreShow = false;
|
||||||
|
|
||||||
_variants.resize(emoji->variantsCount() + 1);
|
_variants.resize(emoji->variantsCount() + 1);
|
||||||
|
@ -144,10 +153,21 @@ void EmojiColorPicker::showEmoji(EmojiPtr emoji) {
|
||||||
|
|
||||||
updateSize();
|
updateSize();
|
||||||
|
|
||||||
if (!_cache.isNull()) _cache = QPixmap();
|
if (!_cache.isNull()) {
|
||||||
|
_cache = QPixmap();
|
||||||
|
}
|
||||||
showAnimated();
|
showAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiColorPicker::createAllLabel() {
|
||||||
|
_allLabel = std::make_unique<Ui::FlatLabel>(
|
||||||
|
this,
|
||||||
|
tr::lng_emoji_color_all(),
|
||||||
|
_st.colorAllLabel);
|
||||||
|
_allLabel->show();
|
||||||
|
_allLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::updateSize() {
|
void EmojiColorPicker::updateSize() {
|
||||||
auto width = st::emojiPanMargins.left()
|
auto width = st::emojiPanMargins.left()
|
||||||
+ _singleSize.width() * _variants.size()
|
+ _singleSize.width() * _variants.size()
|
||||||
|
@ -158,6 +178,17 @@ void EmojiColorPicker::updateSize() {
|
||||||
+ 2 * st::emojiColorsPadding
|
+ 2 * st::emojiColorsPadding
|
||||||
+ _singleSize.height()
|
+ _singleSize.height()
|
||||||
+ st::emojiPanMargins.bottom();
|
+ st::emojiPanMargins.bottom();
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->resizeToWidth(width
|
||||||
|
- st::emojiPanMargins.left()
|
||||||
|
- st::emojiPanMargins.right()
|
||||||
|
- st::emojiPanColorAllPadding.left()
|
||||||
|
- st::emojiPanColorAllPadding.right());
|
||||||
|
_allLabel->move(
|
||||||
|
st::emojiPanMargins.left() + st::emojiPanColorAllPadding.left(),
|
||||||
|
st::emojiPanMargins.top() + st::emojiPanColorAllPadding.top());
|
||||||
|
height += topColorAllSkip();
|
||||||
|
}
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
update();
|
update();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -186,11 +217,15 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
||||||
Ui::Shadow::paint(p, inner, width(), _st.showAnimation.shadow);
|
Ui::Shadow::paint(p, inner, width(), _st.showAnimation.shadow);
|
||||||
_backgroundRect.paint(p, inner);
|
_backgroundRect.paint(p, inner);
|
||||||
|
|
||||||
|
const auto skip = topColorAllSkip();
|
||||||
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + _singleSize.width();
|
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + _singleSize.width();
|
||||||
if (rtl()) x = width() - x - st::emojiColorsSep;
|
if (rtl()) x = width() - x - st::emojiColorsSep;
|
||||||
p.fillRect(x, st::emojiPanMargins.top() + st::emojiColorsPadding, st::emojiColorsSep, inner.height() - st::emojiColorsPadding * 2, st::emojiColorsSepColor);
|
p.fillRect(x, st::emojiPanMargins.top() + skip + st::emojiColorsPadding, st::emojiColorsSep, inner.height() - st::emojiColorsPadding * 2 - skip, st::emojiColorsSepColor);
|
||||||
|
|
||||||
if (_variants.isEmpty()) return;
|
if (_variants.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.translate(0, skip);
|
||||||
for (auto i = 0, count = int(_variants.size()); i != count; ++i) {
|
for (auto i = 0, count = int(_variants.size()); i != count; ++i) {
|
||||||
drawVariant(p, i);
|
drawVariant(p, i);
|
||||||
}
|
}
|
||||||
|
@ -248,6 +283,9 @@ void EmojiColorPicker::animationCallback() {
|
||||||
update();
|
update();
|
||||||
if (!_a_opacity.animating()) {
|
if (!_a_opacity.animating()) {
|
||||||
_cache = QPixmap();
|
_cache = QPixmap();
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->show();
|
||||||
|
}
|
||||||
if (_hiding) {
|
if (_hiding) {
|
||||||
hide();
|
hide();
|
||||||
_hidden.fire({});
|
_hidden.fire({});
|
||||||
|
@ -276,10 +314,16 @@ rpl::producer<> EmojiColorPicker::hidden() const {
|
||||||
|
|
||||||
void EmojiColorPicker::hideAnimated() {
|
void EmojiColorPicker::hideAnimated() {
|
||||||
if (_cache.isNull()) {
|
if (_cache.isNull()) {
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->show();
|
||||||
|
}
|
||||||
_cache = Ui::GrabWidget(this);
|
_cache = Ui::GrabWidget(this);
|
||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->hide();
|
||||||
|
}
|
||||||
_a_opacity.start([this] { animationCallback(); }, 1., 0., st::emojiPanDuration);
|
_a_opacity.start([this] { animationCallback(); }, 1., 0., st::emojiPanDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,10 +335,16 @@ void EmojiColorPicker::showAnimated() {
|
||||||
}
|
}
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
if (_cache.isNull()) {
|
if (_cache.isNull()) {
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->show();
|
||||||
|
}
|
||||||
_cache = Ui::GrabWidget(this);
|
_cache = Ui::GrabWidget(this);
|
||||||
clearSelection();
|
clearSelection();
|
||||||
}
|
}
|
||||||
show();
|
show();
|
||||||
|
if (_allLabel) {
|
||||||
|
_allLabel->hide();
|
||||||
|
}
|
||||||
_a_opacity.start([this] { animationCallback(); }, 0., 1., st::emojiPanDuration);
|
_a_opacity.start([this] { animationCallback(); }, 0., 1., st::emojiPanDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,10 +354,18 @@ void EmojiColorPicker::clearSelection() {
|
||||||
_lastMousePos = mapToGlobal(QPoint(-10, -10));
|
_lastMousePos = mapToGlobal(QPoint(-10, -10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EmojiColorPicker::topColorAllSkip() const {
|
||||||
|
return _allLabel
|
||||||
|
? (st::emojiPanColorAllPadding.top()
|
||||||
|
+ _allLabel->height()
|
||||||
|
+ st::emojiPanColorAllPadding.bottom())
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::updateSelected() {
|
void EmojiColorPicker::updateSelected() {
|
||||||
auto newSelected = -1;
|
auto newSelected = -1;
|
||||||
auto p = mapFromGlobal(_lastMousePos);
|
auto p = mapFromGlobal(_lastMousePos);
|
||||||
auto sx = rtl() ? (width() - p.x()) : p.x(), y = p.y() - st::emojiPanMargins.top() - st::emojiColorsPadding;
|
auto sx = rtl() ? (width() - p.x()) : p.x(), y = p.y() - st::emojiPanMargins.top() - topColorAllSkip() - st::emojiColorsPadding;
|
||||||
if (y >= 0 && y < _singleSize.height()) {
|
if (y >= 0 && y < _singleSize.height()) {
|
||||||
auto x = sx - st::emojiPanMargins.left() - st::emojiColorsPadding;
|
auto x = sx - st::emojiPanMargins.left() - st::emojiColorsPadding;
|
||||||
if (x >= 0 && x < _singleSize.width()) {
|
if (x >= 0 && x < _singleSize.width()) {
|
||||||
|
@ -327,7 +385,8 @@ void EmojiColorPicker::setSelected(int newSelected) {
|
||||||
if (_selected == newSelected) {
|
if (_selected == newSelected) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto updateSelectedRect = [this] {
|
const auto skip = topColorAllSkip();
|
||||||
|
const auto updateSelectedRect = [&] {
|
||||||
if (_selected < 0) return;
|
if (_selected < 0) return;
|
||||||
auto addedSkip = (_selected > 0)
|
auto addedSkip = (_selected > 0)
|
||||||
? (2 * st::emojiColorsPadding + st::emojiColorsSep)
|
? (2 * st::emojiColorsPadding + st::emojiColorsSep)
|
||||||
|
@ -338,7 +397,7 @@ void EmojiColorPicker::setSelected(int newSelected) {
|
||||||
+ addedSkip;
|
+ addedSkip;
|
||||||
rtlupdate(
|
rtlupdate(
|
||||||
left,
|
left,
|
||||||
st::emojiPanMargins.top() + st::emojiColorsPadding,
|
st::emojiPanMargins.top() + st::emojiColorsPadding + skip,
|
||||||
_singleSize.width(),
|
_singleSize.width(),
|
||||||
_singleSize.height());
|
_singleSize.height());
|
||||||
};
|
};
|
||||||
|
@ -851,6 +910,31 @@ void EmojiListWidget::setSingleSize(QSize size) {
|
||||||
_picker->setSingleSize(_singleSize);
|
_picker->setSingleSize(_singleSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::setColorAllForceRippled(bool force) {
|
||||||
|
_colorAllRippleForced = force;
|
||||||
|
if (_colorAllRippleForced) {
|
||||||
|
_colorAllRippleForcedLifetime = style::PaletteChanged(
|
||||||
|
) | rpl::filter([=] {
|
||||||
|
return _colorAllRipple != nullptr;
|
||||||
|
}) | rpl::start_with_next([=] {
|
||||||
|
_colorAllRipple->forceRepaint();
|
||||||
|
});
|
||||||
|
if (!_colorAllRipple) {
|
||||||
|
_colorAllRipple = createButtonRipple(int(Section::People));
|
||||||
|
}
|
||||||
|
if (_colorAllRipple->empty()) {
|
||||||
|
_colorAllRipple->addFading();
|
||||||
|
} else {
|
||||||
|
_colorAllRipple->lastUnstop();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_colorAllRipple) {
|
||||||
|
_colorAllRipple->lastStop();
|
||||||
|
}
|
||||||
|
_colorAllRippleForcedLifetime.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int EmojiListWidget::countDesiredHeight(int newWidth) {
|
int EmojiListWidget::countDesiredHeight(int newWidth) {
|
||||||
const auto fullWidth = st().margin.left()
|
const auto fullWidth = st().margin.left()
|
||||||
+ newWidth
|
+ newWidth
|
||||||
|
@ -897,14 +981,9 @@ void EmojiListWidget::ensureLoaded(int section) {
|
||||||
_emoji[section] = Ui::Emoji::GetSection(static_cast<Section>(section));
|
_emoji[section] = Ui::Emoji::GetSection(static_cast<Section>(section));
|
||||||
_counts[section] = _emoji[section].size();
|
_counts[section] = _emoji[section].size();
|
||||||
|
|
||||||
const auto &variants = Core::App().settings().emojiVariants();
|
const auto &settings = Core::App().settings();
|
||||||
for (auto &emoji : _emoji[section]) {
|
for (auto &emoji : _emoji[section]) {
|
||||||
if (emoji->hasVariants()) {
|
emoji = settings.lookupEmojiVariant(emoji);
|
||||||
const auto j = variants.find(emoji->nonColoredId());
|
|
||||||
if (j != end(variants)) {
|
|
||||||
emoji = emoji->variant(j->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1366,8 +1445,7 @@ void EmojiListWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
if (emoji && emoji->hasVariants()) {
|
if (emoji && emoji->hasVariants()) {
|
||||||
_pickerSelected = _selected;
|
_pickerSelected = _selected;
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
const auto &variants = Core::App().settings().emojiVariants();
|
if (!Core::App().settings().hasChosenEmojiVariant(emoji)) {
|
||||||
if (!variants.contains(emoji->nonColoredId())) {
|
|
||||||
showPicker();
|
showPicker();
|
||||||
} else {
|
} else {
|
||||||
_showPickerTimer.callOnce(500);
|
_showPickerTimer.callOnce(500);
|
||||||
|
@ -1385,12 +1463,11 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
return _picker->handleMouseRelease(QCursor::pos());
|
return _picker->handleMouseRelease(QCursor::pos());
|
||||||
} else if (const auto over = std::get_if<OverEmoji>(&_pickerSelected)) {
|
} else if (const auto over = std::get_if<OverEmoji>(&_pickerSelected)) {
|
||||||
const auto emoji = lookupOverEmoji(over);
|
const auto emoji = lookupOverEmoji(over);
|
||||||
if (emoji && emoji->hasVariants()) {
|
if (emoji
|
||||||
const auto &variants = Core::App().settings().emojiVariants();
|
&& emoji->hasVariants()
|
||||||
if (variants.contains(emoji->nonColoredId())) {
|
&& Core::App().settings().hasChosenEmojiVariant(emoji)) {
|
||||||
_picker->hideAnimated();
|
_picker->hideAnimated();
|
||||||
_pickerSelected = v::null;
|
_pickerSelected = v::null;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1429,11 +1506,15 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
&& set->section < _staticCount + _custom.size());
|
&& set->section < _staticCount + _custom.size());
|
||||||
displaySet(_custom[set->section - _staticCount].id);
|
displaySet(_custom[set->section - _staticCount].id);
|
||||||
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
||||||
Assert(button->section >= _staticCount
|
Assert(hasButton(button->section));
|
||||||
&& button->section < _staticCount + _custom.size());
|
const auto id = hasColorButton(button->section)
|
||||||
const auto id = _custom[button->section - _staticCount].id;
|
? 0
|
||||||
|
: _custom[button->section - _staticCount].id;
|
||||||
const auto usage = ChatHelpers::WindowUsage::PremiumPromo;
|
const auto usage = ChatHelpers::WindowUsage::PremiumPromo;
|
||||||
if (hasRemoveButton(button->section)) {
|
if (hasColorButton(button->section)) {
|
||||||
|
_pickerSelected = pressed;
|
||||||
|
showPicker();
|
||||||
|
} else if (hasRemoveButton(button->section)) {
|
||||||
removeSet(id);
|
removeSet(id);
|
||||||
} else if (hasAddButton(button->section)) {
|
} else if (hasAddButton(button->section)) {
|
||||||
_localSetsManager->install(id);
|
_localSetsManager->install(id);
|
||||||
|
@ -1496,23 +1577,35 @@ void EmojiListWidget::showPicker() {
|
||||||
if (v::is_null(_pickerSelected)) {
|
if (v::is_null(_pickerSelected)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto showAt = [&](float64 xCoef, int y, int height) {
|
||||||
const auto over = std::get_if<OverEmoji>(&_pickerSelected);
|
|
||||||
const auto emoji = lookupOverEmoji(over);
|
|
||||||
if (emoji && emoji->hasVariants()) {
|
|
||||||
_picker->showEmoji(emoji);
|
|
||||||
|
|
||||||
auto y = emojiRect(over->section, over->index).y();
|
|
||||||
y -= _picker->height() - st::emojiPanRadius + getVisibleTop();
|
y -= _picker->height() - st::emojiPanRadius + getVisibleTop();
|
||||||
if (y < st().header) {
|
if (y < st().header) {
|
||||||
y += _picker->height() - st::emojiPanRadius + _singleSize.height() - st::emojiPanRadius;
|
y += _picker->height() + height;
|
||||||
}
|
}
|
||||||
auto xmax = width() - _picker->width();
|
auto xmax = width() - _picker->width();
|
||||||
auto coef = float64(over->index % _columnCount) / float64(_columnCount - 1);
|
if (rtl()) xCoef = 1. - xCoef;
|
||||||
if (rtl()) coef = 1. - coef;
|
_picker->move(qRound(xmax * xCoef), y);
|
||||||
_picker->move(qRound(xmax * coef), y);
|
|
||||||
|
|
||||||
disableScroll(true);
|
disableScroll(true);
|
||||||
|
};
|
||||||
|
if (const auto button = std::get_if<OverButton>(&_pickerSelected)) {
|
||||||
|
const auto hand = QString::fromUtf8("\xF0\x9F\x91\x8B");
|
||||||
|
const auto emoji = Ui::Emoji::Find(hand);
|
||||||
|
Assert(emoji != nullptr && emoji->hasVariants());
|
||||||
|
_picker->showEmoji(emoji, true);
|
||||||
|
setColorAllForceRippled(true);
|
||||||
|
const auto rect = buttonRect(button->section);
|
||||||
|
showAt(1., rect.y(), rect.height() - 2 * st::emojiPanRadius);
|
||||||
|
} else if (const auto over = std::get_if<OverEmoji>(&_pickerSelected)) {
|
||||||
|
const auto emoji = lookupOverEmoji(over);
|
||||||
|
if (emoji && emoji->hasVariants()) {
|
||||||
|
_picker->showEmoji(emoji);
|
||||||
|
|
||||||
|
const auto coef = float64(over->index % _columnCount)
|
||||||
|
/ float64(_columnCount - 1);
|
||||||
|
const auto h = _singleSize.height() - 2 * st::emojiPanRadius;
|
||||||
|
showAt(coef, emojiRect(over->section, over->index).y(), h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1520,11 +1613,34 @@ void EmojiListWidget::pickerHidden() {
|
||||||
_pickerSelected = v::null;
|
_pickerSelected = v::null;
|
||||||
update();
|
update();
|
||||||
disableScroll(false);
|
disableScroll(false);
|
||||||
|
setColorAllForceRippled(false);
|
||||||
|
|
||||||
_lastMousePos = QCursor::pos();
|
_lastMousePos = QCursor::pos();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EmojiListWidget::hasColorButton(int index) const {
|
||||||
|
return (_staticCount > int(Section::People))
|
||||||
|
&& (index == int(Section::People));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::colorButtonRect(int index) const {
|
||||||
|
return colorButtonRect(sectionInfo(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::colorButtonRect(const SectionInfo &info) const {
|
||||||
|
if (_mode != Mode::Full) {
|
||||||
|
return QRect();
|
||||||
|
}
|
||||||
|
const auto &colorSt = st().colorAll;
|
||||||
|
const auto buttonw = colorSt.rippleAreaPosition.x()
|
||||||
|
+ colorSt.rippleAreaSize;
|
||||||
|
const auto buttonh = colorSt.height;
|
||||||
|
const auto buttonx = emojiRight() - st::emojiPanColorAllSkip - buttonw;
|
||||||
|
const auto buttony = info.top + st::emojiPanRemoveTop;
|
||||||
|
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||||
|
}
|
||||||
|
|
||||||
bool EmojiListWidget::hasRemoveButton(int index) const {
|
bool EmojiListWidget::hasRemoveButton(int index) const {
|
||||||
if (index < _staticCount
|
if (index < _staticCount
|
||||||
|| index >= _staticCount + _custom.size()) {
|
|| index >= _staticCount + _custom.size()) {
|
||||||
|
@ -1581,15 +1697,18 @@ QRect EmojiListWidget::unlockButtonRect(int index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmojiListWidget::hasButton(int index) const {
|
bool EmojiListWidget::hasButton(int index) const {
|
||||||
if (index < _staticCount
|
if (hasColorButton(index)
|
||||||
|| index >= _staticCount + _custom.size()) {
|
|| (index >= _staticCount
|
||||||
return false;
|
&& index < _staticCount + _custom.size())) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect EmojiListWidget::buttonRect(int index) const {
|
QRect EmojiListWidget::buttonRect(int index) const {
|
||||||
return hasRemoveButton(index)
|
return hasColorButton(index)
|
||||||
|
? colorButtonRect(index)
|
||||||
|
: hasRemoveButton(index)
|
||||||
? removeButtonRect(index)
|
? removeButtonRect(index)
|
||||||
: hasAddButton(index)
|
: hasAddButton(index)
|
||||||
? addButtonRect(index)
|
? addButtonRect(index)
|
||||||
|
@ -1637,19 +1756,33 @@ QRect EmojiListWidget::emojiRect(int section, int index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::colorChosen(EmojiChosen data) {
|
void EmojiListWidget::colorChosen(EmojiChosen data) {
|
||||||
|
Expects(data.emoji != nullptr && data.emoji->hasVariants());
|
||||||
|
|
||||||
const auto emoji = data.emoji;
|
const auto emoji = data.emoji;
|
||||||
if (emoji->hasVariants()) {
|
auto &settings = Core::App().settings();
|
||||||
Core::App().settings().saveEmojiVariant(emoji);
|
if (const auto button = std::get_if<OverButton>(&_pickerSelected)) {
|
||||||
|
settings.saveAllEmojiVariants(emoji);
|
||||||
|
for (auto section = int(Section::People)
|
||||||
|
; section < _staticCount
|
||||||
|
; ++section) {
|
||||||
|
for (auto &emoji : _emoji[section]) {
|
||||||
|
emoji = settings.lookupEmojiVariant(emoji);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
} else {
|
||||||
|
settings.saveEmojiVariant(emoji);
|
||||||
|
|
||||||
|
const auto over = std::get_if<OverEmoji>(&_pickerSelected);
|
||||||
|
if (over
|
||||||
|
&& over->section > int(Section::Recent)
|
||||||
|
&& over->section < _staticCount
|
||||||
|
&& over->index < _emoji[over->section].size()) {
|
||||||
|
_emoji[over->section][over->index] = emoji;
|
||||||
|
rtlupdate(emojiRect(over->section, over->index));
|
||||||
|
}
|
||||||
|
selectEmoji(data);
|
||||||
}
|
}
|
||||||
const auto over = std::get_if<OverEmoji>(&_pickerSelected);
|
|
||||||
if (over
|
|
||||||
&& over->section > int(Section::Recent)
|
|
||||||
&& over->section < _staticCount
|
|
||||||
&& over->index < _emoji[over->section].size()) {
|
|
||||||
_emoji[over->section][over->index] = emoji;
|
|
||||||
rtlupdate(emojiRect(over->section, over->index));
|
|
||||||
}
|
|
||||||
selectEmoji(data);
|
|
||||||
_picker->hideAnimated();
|
_picker->hideAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1967,47 +2100,54 @@ int EmojiListWidget::paintButtonGetWidth(
|
||||||
const SectionInfo &info,
|
const SectionInfo &info,
|
||||||
bool selected,
|
bool selected,
|
||||||
QRect clip) const {
|
QRect clip) const {
|
||||||
if (info.section < _staticCount
|
if (!hasButton(info.section)) {
|
||||||
|| info.section >= _staticCount + _custom.size()) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto &custom = _custom[info.section - _staticCount];
|
auto &ripple = (info.section >= _staticCount)
|
||||||
if (hasRemoveButton(info.section)) {
|
? _custom[info.section - _staticCount].ripple
|
||||||
const auto remove = removeButtonRect(info);
|
: _colorAllRipple;
|
||||||
if (remove.isEmpty()) {
|
const auto colorAll = hasColorButton(info.section);
|
||||||
|
if (colorAll || hasRemoveButton(info.section)) {
|
||||||
|
const auto rect = colorAll
|
||||||
|
? colorButtonRect(info)
|
||||||
|
: removeButtonRect(info);
|
||||||
|
if (rect.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (remove.intersects(clip)) {
|
} else if (rect.intersects(clip)) {
|
||||||
const auto &removeSt = st().removeSet;
|
const auto &bst = colorAll ? st().colorAll : st().removeSet;
|
||||||
if (custom.ripple) {
|
if (colorAll && _colorAllRippleForced) {
|
||||||
custom.ripple->paint(
|
selected = true;
|
||||||
|
}
|
||||||
|
if (ripple) {
|
||||||
|
ripple->paint(
|
||||||
p,
|
p,
|
||||||
remove.x() + removeSt.rippleAreaPosition.x(),
|
rect.x() + bst.rippleAreaPosition.x(),
|
||||||
remove.y() + removeSt.rippleAreaPosition.y(),
|
rect.y() + bst.rippleAreaPosition.y(),
|
||||||
width());
|
width());
|
||||||
if (custom.ripple->empty()) {
|
if (ripple->empty()) {
|
||||||
custom.ripple.reset();
|
ripple.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto &icon = selected ? removeSt.iconOver : removeSt.icon;
|
const auto &icon = selected ? bst.iconOver : bst.icon;
|
||||||
icon.paint(
|
icon.paint(
|
||||||
p,
|
p,
|
||||||
(remove.topLeft()
|
(rect.topLeft()
|
||||||
+ QPoint(
|
+ QPoint(
|
||||||
remove.width() - icon.width(),
|
rect.width() - icon.width(),
|
||||||
remove.height() - icon.height()) / 2),
|
rect.height() - icon.height()) / 2),
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
return emojiRight() - remove.x();
|
return emojiRight() - rect.x();
|
||||||
}
|
}
|
||||||
const auto canAdd = hasAddButton(info.section);
|
const auto canAdd = hasAddButton(info.section);
|
||||||
const auto &button = rightButton(info.section);
|
const auto &button = rightButton(info.section);
|
||||||
const auto rect = buttonRect(info, button);
|
const auto rect = buttonRect(info, button);
|
||||||
p.drawImage(rect.topLeft(), selected ? button.backOver : button.back);
|
p.drawImage(rect.topLeft(), selected ? button.backOver : button.back);
|
||||||
if (custom.ripple) {
|
if (ripple) {
|
||||||
const auto ripple = QColor(0, 0, 0, 36);
|
const auto color = QColor(0, 0, 0, 36);
|
||||||
custom.ripple->paint(p, rect.x(), rect.y(), width(), &ripple);
|
ripple->paint(p, rect.x(), rect.y(), width(), &color);
|
||||||
if (custom.ripple->empty()) {
|
if (ripple->empty()) {
|
||||||
custom.ripple.reset();
|
ripple.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.setPen(!canAdd
|
p.setPen(!canAdd
|
||||||
|
@ -2108,22 +2248,28 @@ void EmojiListWidget::setSelected(OverState newSelected) {
|
||||||
|
|
||||||
void EmojiListWidget::setPressed(OverState newPressed) {
|
void EmojiListWidget::setPressed(OverState newPressed) {
|
||||||
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
||||||
Assert(button->section >= _staticCount
|
Assert(hasColorButton(button->section)
|
||||||
&& button->section < _staticCount + _custom.size());
|
|| (button->section >= _staticCount
|
||||||
auto &set = _custom[button->section - _staticCount];
|
&& button->section < _staticCount + _custom.size()));
|
||||||
if (set.ripple) {
|
auto &ripple = (button->section >= _staticCount)
|
||||||
set.ripple->lastStop();
|
? _custom[button->section - _staticCount].ripple
|
||||||
|
: _colorAllRipple;
|
||||||
|
if (ripple) {
|
||||||
|
ripple->lastStop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_pressed = newPressed;
|
_pressed = newPressed;
|
||||||
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
if (auto button = std::get_if<OverButton>(&_pressed)) {
|
||||||
Assert(button->section >= _staticCount
|
Assert(hasColorButton(button->section)
|
||||||
&& button->section < _staticCount + _custom.size());
|
|| (button->section >= _staticCount
|
||||||
auto &set = _custom[button->section - _staticCount];
|
&& button->section < _staticCount + _custom.size()));
|
||||||
if (!set.ripple) {
|
auto &ripple = (button->section >= _staticCount)
|
||||||
set.ripple = createButtonRipple(button->section);
|
? _custom[button->section - _staticCount].ripple
|
||||||
|
: _colorAllRipple;
|
||||||
|
if (!ripple) {
|
||||||
|
ripple = createButtonRipple(button->section);
|
||||||
}
|
}
|
||||||
set.ripple->add(mapFromGlobal(QCursor::pos()) - buttonRippleTopLeft(button->section));
|
ripple->add(mapFromGlobal(QCursor::pos()) - buttonRippleTopLeft(button->section));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2167,16 +2313,18 @@ void EmojiListWidget::initButton(
|
||||||
|
|
||||||
std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
||||||
int section) {
|
int section) {
|
||||||
Expects(section >= _staticCount
|
Expects(hasButton(section));
|
||||||
&& section < _staticCount + _custom.size());
|
|
||||||
|
|
||||||
|
const auto colorAll = hasColorButton(section);
|
||||||
const auto remove = hasRemoveButton(section);
|
const auto remove = hasRemoveButton(section);
|
||||||
const auto &removeSt = st().removeSet;
|
const auto &staticSt = colorAll ? st().colorAll : st().removeSet;
|
||||||
const auto &st = remove ? removeSt.ripple : st::emojiPanButton.ripple;
|
const auto &st = (colorAll || remove)
|
||||||
auto mask = remove
|
? staticSt.ripple
|
||||||
|
: st::emojiPanButton.ripple;
|
||||||
|
auto mask = (colorAll || remove)
|
||||||
? Ui::RippleAnimation::EllipseMask(QSize(
|
? Ui::RippleAnimation::EllipseMask(QSize(
|
||||||
removeSt.rippleAreaSize,
|
staticSt.rippleAreaSize,
|
||||||
removeSt.rippleAreaSize))
|
staticSt.rippleAreaSize))
|
||||||
: rightButton(section).rippleMask;
|
: rightButton(section).rippleMask;
|
||||||
return std::make_unique<Ui::RippleAnimation>(
|
return std::make_unique<Ui::RippleAnimation>(
|
||||||
st,
|
st,
|
||||||
|
@ -2185,11 +2333,12 @@ std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
||||||
Expects(section >= _staticCount
|
Expects(hasButton(section));
|
||||||
&& section < _staticCount + _custom.size());
|
|
||||||
|
|
||||||
return myrtlrect(buttonRect(section)).topLeft()
|
return myrtlrect(buttonRect(section)).topLeft()
|
||||||
+ (hasRemoveButton(section)
|
+ (hasColorButton(section)
|
||||||
|
? st().colorAll.rippleAreaPosition
|
||||||
|
: hasRemoveButton(section)
|
||||||
? st().removeSet.rippleAreaPosition
|
? st().removeSet.rippleAreaPosition
|
||||||
: QPoint());
|
: QPoint());
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,6 +247,7 @@ private:
|
||||||
[[nodiscard]] SectionInfo sectionInfoByOffset(int yOffset) const;
|
[[nodiscard]] SectionInfo sectionInfoByOffset(int yOffset) const;
|
||||||
[[nodiscard]] int sectionsCount() const;
|
[[nodiscard]] int sectionsCount() const;
|
||||||
void setSingleSize(QSize size);
|
void setSingleSize(QSize size);
|
||||||
|
void setColorAllForceRippled(bool force);
|
||||||
|
|
||||||
void showPicker();
|
void showPicker();
|
||||||
void pickerHidden();
|
void pickerHidden();
|
||||||
|
@ -297,6 +298,9 @@ private:
|
||||||
int set,
|
int set,
|
||||||
int index);
|
int index);
|
||||||
void validateEmojiPaintContext(const ExpandingContext &context);
|
void validateEmojiPaintContext(const ExpandingContext &context);
|
||||||
|
[[nodiscard]] bool hasColorButton(int index) const;
|
||||||
|
[[nodiscard]] QRect colorButtonRect(int index) const;
|
||||||
|
[[nodiscard]] QRect colorButtonRect(const SectionInfo &info) const;
|
||||||
[[nodiscard]] bool hasRemoveButton(int index) const;
|
[[nodiscard]] bool hasRemoveButton(int index) const;
|
||||||
[[nodiscard]] QRect removeButtonRect(int index) const;
|
[[nodiscard]] QRect removeButtonRect(int index) const;
|
||||||
[[nodiscard]] QRect removeButtonRect(const SectionInfo &info) const;
|
[[nodiscard]] QRect removeButtonRect(const SectionInfo &info) const;
|
||||||
|
@ -378,6 +382,10 @@ private:
|
||||||
Ui::RoundRect _overBg;
|
Ui::RoundRect _overBg;
|
||||||
QImage _searchExpandCache;
|
QImage _searchExpandCache;
|
||||||
|
|
||||||
|
mutable std::unique_ptr<Ui::RippleAnimation> _colorAllRipple;
|
||||||
|
bool _colorAllRippleForced = false;
|
||||||
|
rpl::lifetime _colorAllRippleForcedLifetime;
|
||||||
|
|
||||||
std::vector<QString> _nextSearchQuery;
|
std::vector<QString> _nextSearchQuery;
|
||||||
std::vector<QString> _searchQuery;
|
std::vector<QString> _searchQuery;
|
||||||
base::flat_set<EmojiPtr> _searchEmoji;
|
base::flat_set<EmojiPtr> _searchEmoji;
|
||||||
|
|
|
@ -1076,11 +1076,40 @@ void Settings::setLegacyRecentEmojiPreload(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmojiPtr Settings::lookupEmojiVariant(EmojiPtr emoji) const {
|
||||||
|
if (emoji->hasVariants()) {
|
||||||
|
const auto i = _emojiVariants.find(emoji->nonColoredId());
|
||||||
|
if (i != end(_emojiVariants)) {
|
||||||
|
return emoji->variant(i->second);
|
||||||
|
}
|
||||||
|
const auto j = _emojiVariants.find(QString());
|
||||||
|
if (j != end(_emojiVariants)) {
|
||||||
|
return emoji->variant(j->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::hasChosenEmojiVariant(EmojiPtr emoji) const {
|
||||||
|
return _emojiVariants.contains(QString())
|
||||||
|
|| _emojiVariants.contains(emoji->nonColoredId());
|
||||||
|
}
|
||||||
|
|
||||||
void Settings::saveEmojiVariant(EmojiPtr emoji) {
|
void Settings::saveEmojiVariant(EmojiPtr emoji) {
|
||||||
|
Expects(emoji->hasVariants());
|
||||||
|
|
||||||
_emojiVariants[emoji->nonColoredId()] = emoji->variantIndex(emoji);
|
_emojiVariants[emoji->nonColoredId()] = emoji->variantIndex(emoji);
|
||||||
_saveDelayed.fire({});
|
_saveDelayed.fire({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings::saveAllEmojiVariants(EmojiPtr emoji) {
|
||||||
|
Expects(emoji->hasVariants());
|
||||||
|
|
||||||
|
_emojiVariants.clear();
|
||||||
|
_emojiVariants[QString()] = emoji->variantIndex(emoji);
|
||||||
|
_saveDelayed.fire({});
|
||||||
|
}
|
||||||
|
|
||||||
void Settings::setLegacyEmojiVariants(QMap<QString, int> data) {
|
void Settings::setLegacyEmojiVariants(QMap<QString, int> data) {
|
||||||
if (!_emojiVariants.empty() || data.isEmpty()) {
|
if (!_emojiVariants.empty() || data.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -668,7 +668,10 @@ public:
|
||||||
[[nodiscard]] const base::flat_map<QString, uint8> &emojiVariants() const {
|
[[nodiscard]] const base::flat_map<QString, uint8> &emojiVariants() const {
|
||||||
return _emojiVariants;
|
return _emojiVariants;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] EmojiPtr lookupEmojiVariant(EmojiPtr emoji) const;
|
||||||
|
[[nodiscard]] bool hasChosenEmojiVariant(EmojiPtr emoji) const;
|
||||||
void saveEmojiVariant(EmojiPtr emoji);
|
void saveEmojiVariant(EmojiPtr emoji);
|
||||||
|
void saveAllEmojiVariants(EmojiPtr emoji);
|
||||||
void setLegacyEmojiVariants(QMap<QString, int> data);
|
void setLegacyEmojiVariants(QMap<QString, int> data);
|
||||||
|
|
||||||
[[nodiscard]] bool disableOpenGL() const {
|
[[nodiscard]] bool disableOpenGL() const {
|
||||||
|
|
|
@ -282,15 +282,10 @@ rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
|
||||||
|
|
||||||
const Ui::Emoji::One *UiIntegration::defaultEmojiVariant(
|
const Ui::Emoji::One *UiIntegration::defaultEmojiVariant(
|
||||||
const Ui::Emoji::One *emoji) {
|
const Ui::Emoji::One *emoji) {
|
||||||
if (!emoji || !emoji->hasVariants()) {
|
if (!emoji) {
|
||||||
return emoji;
|
return emoji;
|
||||||
}
|
}
|
||||||
const auto nonColored = emoji->nonColoredId();
|
const auto result = Core::App().settings().lookupEmojiVariant(emoji);
|
||||||
const auto &variants = Core::App().settings().emojiVariants();
|
|
||||||
const auto i = variants.find(nonColored);
|
|
||||||
const auto result = (i != end(variants))
|
|
||||||
? emoji->variant(i->second)
|
|
||||||
: emoji;
|
|
||||||
Core::App().settings().incrementRecentEmoji({ result });
|
Core::App().settings().incrementRecentEmoji({ result });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -479,6 +479,14 @@ storiesRemoveSet: IconButton(stickerPanRemoveSet) {
|
||||||
iconOver: icon {{ "simple_close", storiesComposeGrayIcon }};
|
iconOver: icon {{ "simple_close", storiesComposeGrayIcon }};
|
||||||
ripple: storiesComposeRippleLight;
|
ripple: storiesComposeRippleLight;
|
||||||
}
|
}
|
||||||
|
storiesColorAll: IconButton(emojiPanColorAll) {
|
||||||
|
icon: icon {{ "emoji/emoji_skin", storiesComposeGrayIcon }};
|
||||||
|
iconOver: icon {{ "emoji/emoji_skin", storiesComposeGrayIcon }};
|
||||||
|
ripple: storiesComposeRippleLight;
|
||||||
|
}
|
||||||
|
storiesColorAllLabel: FlatLabel(emojiPanColorAllLabel) {
|
||||||
|
textFg: storiesComposeGrayText;
|
||||||
|
}
|
||||||
storiesMenuSeparator: mediaviewMenuSeparator;
|
storiesMenuSeparator: mediaviewMenuSeparator;
|
||||||
storiesMenu: Menu(defaultMenu) {
|
storiesMenu: Menu(defaultMenu) {
|
||||||
itemBg: groupCallMenuBg;
|
itemBg: groupCallMenuBg;
|
||||||
|
@ -588,6 +596,8 @@ storiesEmojiPan: EmojiPan(defaultEmojiPan) {
|
||||||
rippleBgActive: storiesComposeBgOver;
|
rippleBgActive: storiesComposeBgOver;
|
||||||
}
|
}
|
||||||
search: storiesEmojiTabbedSearch;
|
search: storiesEmojiTabbedSearch;
|
||||||
|
colorAll: storiesColorAll;
|
||||||
|
colorAllLabel: storiesColorAllLabel;
|
||||||
removeSet: storiesRemoveSet;
|
removeSet: storiesRemoveSet;
|
||||||
boxLabel: storiesBoxLabel;
|
boxLabel: storiesBoxLabel;
|
||||||
icons: ComposeIcons {
|
icons: ComposeIcons {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user