Improve group sticker set setup box.

This commit is contained in:
John Preston 2017-08-05 22:01:20 +02:00
parent 7f5a91d2bb
commit fa818407e6
12 changed files with 478 additions and 167 deletions

View File

@ -922,6 +922,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_stickers_masks_pack" = "This is a pack of mask stickers. You can use them in the photo editor on our mobile apps.";
"lng_stickers_group_set" = "Group sticker set";
"lng_stickers_remove_group_set" = "Remove group sticker set?";
"lng_stickers_group_from_your" = "Choose from your stickers";
"lng_in_dlg_photo" = "Photo";
"lng_in_dlg_video" = "Video";

View File

@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "boxes/abstract_box.h"
#include "styles/style_boxes.h"
#include "styles/style_profile.h"
#include "storage/localstorage.h"
#include "lang/lang_keys.h"
#include "ui/effects/widget_fade_wrap.h"
@ -30,9 +31,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "mainwidget.h"
#include "mainwindow.h"
BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxLayerTitleShadow) {
}
QPointer<Ui::RoundButton> BoxContent::addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback) {
return addButton(std::move(textFactory), std::move(clickCallback), st::defaultBoxButton);
}
@ -421,3 +419,22 @@ void AbstractBox::keyPressEvent(QKeyEvent *e) {
LayerWidget::keyPressEvent(e);
}
}
BoxLayerTitleShadow::BoxLayerTitleShadow(QWidget *parent) : Ui::PlainShadow(parent, st::boxLayerTitleShadow) {
}
BoxContentDivider::BoxContentDivider(QWidget *parent) : TWidget(parent) {
}
int BoxContentDivider::resizeGetHeight(int newWidth) {
return st::rightsDividerHeight;
}
void BoxContentDivider::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), st::contactsAboutBg);
auto dividerFillTop = myrtlrect(0, 0, width(), st::profileDividerTop.height());
st::profileDividerTop.fill(p, dividerFillTop);
auto dividerFillBottom = myrtlrect(0, height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height());
st::profileDividerBottom.fill(p, dividerFillBottom);
}

View File

@ -36,11 +36,7 @@ namespace Window {
class Controller;
} // namespace Window
class BoxLayerTitleShadow : public Ui::PlainShadow {
public:
BoxLayerTitleShadow(QWidget *parent);
};
class BoxLayerTitleShadow;
class BoxContentDelegate {
public:
@ -287,6 +283,22 @@ private:
};
class BoxLayerTitleShadow : public Ui::PlainShadow {
public:
BoxLayerTitleShadow(QWidget *parent);
};
class BoxContentDivider : public TWidget {
public:
BoxContentDivider(QWidget *parent);
protected:
int resizeGetHeight(int newWidth) override;
void paintEvent(QPaintEvent *e) override;
};
enum CreatingGroupType {
CreatingGroupNone,
CreatingGroupGroup,

View File

@ -679,3 +679,16 @@ muteChatTitle: FlatLabel(boxLabel) {
font: font(boxFontSize semibold);
}
}
groupStickersRemove: contactsSearchCancel;
groupStickersRemovePosition: point(6px, 6px);
groupStickersFieldPadding: margins(8px, 6px, 8px, 6px);
groupStickersField: InputField(contactsSearchField) {
placeholderFont: boxTextFont;
font: boxTextFont;
placeholderMargins: margins(0px, 0px, 0px, 0px);
textMargins: margins(0px, 7px, 0px, 0px);
textBg: boxBg;
heightMin: 32px;
}
groupStickersSubTitleHeight: 36px;

View File

@ -25,7 +25,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "styles/style_boxes.h"
#include "styles/style_profile.h"
#include "ui/special_buttons.h"
#include "boxes/calendar_box.h"
@ -74,30 +73,6 @@ void ApplyDependencies(CheckboxesMap &checkboxes, DependenciesMap &dependencies,
} // namespace
class EditParticipantBox::Divider : public TWidget {
public:
Divider(QWidget *parent) : TWidget(parent) {
}
protected:
int resizeGetHeight(int newWidth) override;
void paintEvent(QPaintEvent *e) override;
};
int EditParticipantBox::Divider::resizeGetHeight(int newWidth) {
return st::rightsDividerHeight;
}
void EditParticipantBox::Divider::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), st::contactsAboutBg);
auto dividerFillTop = myrtlrect(0, 0, width(), st::profileDividerTop.height());
st::profileDividerTop.fill(p, dividerFillTop);
auto dividerFillBottom = myrtlrect(0, height() - st::profileDividerBottom.height(), width(), st::profileDividerBottom.height());
st::profileDividerBottom.fill(p, dividerFillBottom);
}
class EditParticipantBox::Inner : public TWidget {
public:
Inner(QWidget *parent, gsl::not_null<ChannelData*> channel, gsl::not_null<UserData*> user, bool hasAdminRights);
@ -236,7 +211,7 @@ void EditAdminBox::prepare() {
auto hadRights = _oldRights.c_channelAdminRights().vflags.v;
setTitle(langFactory(hadRights ? lng_rights_edit_admin : lng_channel_add_admin));
addControl(object_ptr<Divider>(this), QMargins());
addControl(object_ptr<BoxContentDivider>(this), QMargins());
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
auto prepareRights = (hadRights ? _oldRights : DefaultRights(channel()));
@ -355,7 +330,7 @@ void EditRestrictedBox::prepare() {
setTitle(langFactory(lng_rights_user_restrictions));
addControl(object_ptr<Divider>(this), QMargins());
addControl(object_ptr<BoxContentDivider>(this), QMargins());
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_user_restrictions_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
auto prepareRights = (_oldRights.c_channelBannedRights().vflags.v ? _oldRights : DefaultRights(channel()));
@ -378,7 +353,7 @@ void EditRestrictedBox::prepare() {
addCheckbox(Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline, lang(lng_rights_chat_send_stickers));
addCheckbox(Flag::f_embed_links, lang(lng_rights_chat_send_links));
addControl(object_ptr<Divider>(this), st::rightsUntilMargin);
addControl(object_ptr<BoxContentDivider>(this), st::rightsUntilMargin);
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_chat_banned_until_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
setRestrictUntil(_until);

View File

@ -57,8 +57,6 @@ protected:
return _hasAdminRights;
}
class Divider;
private:
gsl::not_null<ChannelData*> _channel;
gsl::not_null<UserData*> _user;

View File

@ -31,16 +31,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "styles/style_boxes.h"
#include "styles/style_chat_helpers.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/scroll_area.h"
#include "ui/effects/ripple_animation.h"
#include "ui/effects/slide_animation.h"
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/input_fields.h"
#include "auth_session.h"
#include "messenger.h"
namespace {
constexpr int kArchivedLimitFirstRequest = 10;
constexpr int kArchivedLimitPerPage = 30;
constexpr auto kArchivedLimitFirstRequest = 10;
constexpr auto kArchivedLimitPerPage = 30;
constexpr auto kHandleMegagroupSetAddressChangeTimeout = TimeMs(1000);
} // namespace
@ -156,6 +160,7 @@ StickersBox::StickersBox(QWidget*, gsl::not_null<ChannelData*> megagroup)
: _section(Section::Installed)
, _installed(0, this, megagroup)
, _megagroupSet(megagroup) {
subscribe(_installed.widget()->scrollToY, [this](int y) { onScrollToY(y); });
}
void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedStickers &result) {
@ -264,7 +269,12 @@ void StickersBox::prepare() {
_archived.widget()->setLoadMoreCallback([this] { loadMoreArchived(); });
}
addButton(langFactory(lng_about_done), [this] { closeBox(); });
if (_megagroupSet) {
addButton(langFactory(lng_settings_save), [this] { _installed.widget()->saveGroupSet(); closeBox(); });
addButton(langFactory(lng_cancel), [this] { closeBox(); });
} else {
addButton(langFactory(lng_about_done), [this] { closeBox(); });
}
if (_section == Section::Installed) {
_tab = &_installed;
@ -554,7 +564,7 @@ void StickersBox::rebuildList(Tab *tab) {
}
void StickersBox::closeHook() {
if (!_installed.widget()) {
if (!_installed.widget() || _megagroupSet) {
return;
}
@ -569,8 +579,30 @@ void StickersBox::closeHook() {
}
}
void StickersBox::setInnerFocus() {
if (_megagroupSet) {
_installed.widget()->setInnerFocus();
}
}
StickersBox::~StickersBox() = default;
StickersBox::Inner::Row::Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh) : id(id)
, sticker(sticker)
, count(count)
, title(title)
, titleWidth(titleWidth)
, installed(installed)
, official(official)
, unread(unread)
, archived(archived)
, removed(removed)
, pixw(pixw)
, pixh(pixh) {
}
StickersBox::Inner::Row::~Row() = default;
StickersBox::Inner::Inner(QWidget *parent, StickersBox::Section section) : TWidget(parent)
, _section(section)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
@ -599,7 +631,17 @@ StickersBox::Inner::Inner(QWidget *parent, gsl::not_null<ChannelData*> megagroup
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _a_shifting(animation(this, &Inner::step_shifting))
, _itemsTop(st::membersMarginTop)
, _megagroupSet(megagroup) {
, _megagroupSet(megagroup)
, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet)
, _megagroupSetField(this, st::groupStickersField, [] { return qsl("stickerset"); }, QString(), true)
, _megagroupDivider(this)
, _megagroupSubTitle(this, lang(lng_stickers_group_from_your), Ui::FlatLabel::InitType::Simple, st::boxTitle) {
_megagroupSetField->setLinkPlaceholder(Messenger::Instance().createInternalLink(qsl("addstickers/")));
_megagroupSetField->setPlaceholderHidden(false);
_megagroupSetAddressChangedTimer.setCallback([this] { handleMegagroupSetAddressChange(); });
connect(_megagroupSetField, &Ui::MaskedInputField::changed, this, [this] { _megagroupSetAddressChangedTimer.callOnce(kHandleMegagroupSetAddressChangeTimeout); });
connect(_megagroupSetField, &Ui::MaskedInputField::submitted, this, [this] { _megagroupSetAddressChangedTimer.cancel(); handleMegagroupSetAddressChange(); });
setup();
}
@ -611,41 +653,76 @@ void StickersBox::Inner::setup() {
setMouseTracking(true);
}
void StickersBox::Inner::setInnerFocus() {
if (_megagroupSetField) {
_megagroupSetField->setFocusFast();
}
}
void StickersBox::Inner::paintEvent(QPaintEvent *e) {
QRect r(e->rect());
Painter p(this);
_a_shifting.step();
auto clip = e->rect();
auto ms = getms();
p.fillRect(r, st::boxBg);
p.setClipRect(r);
p.fillRect(clip, st::boxBg);
p.setClipRect(clip);
if (_megagroupSelectedSet) {
auto setTop = _megagroupDivider->y() - _rowHeight;
p.translate(0, setTop);
paintRow(p, _megagroupSelectedSet.get(), -1, ms);
p.translate(0, -setTop);
}
auto y = _itemsTop;
if (_rows.isEmpty()) {
if (_rows.empty()) {
p.setFont(st::noContactsFont);
p.setPen(st::noContactsColor);
p.drawText(QRect(0, y, width(), st::noContactsHeight), lang(lng_contacts_loading), style::al_center);
} else {
p.translate(0, _itemsTop);
int32 yFrom = r.y() - _itemsTop, yTo = r.y() + r.height() - _itemsTop;
int32 yFrom = clip.y() - _itemsTop, yTo = clip.y() + clip.height() - _itemsTop;
int32 from = floorclamp(yFrom - _rowHeight, _rowHeight, 0, _rows.size());
int32 to = ceilclamp(yTo + _rowHeight, _rowHeight, 0, _rows.size());
p.translate(0, from * _rowHeight);
for (int32 i = from; i < to; ++i) {
if (i != _above) {
paintRow(p, i, ms);
paintRow(p, _rows[i].get(), i, ms);
}
p.translate(0, _rowHeight);
}
if (from <= _above && _above < to) {
p.translate(0, (_above - to) * _rowHeight);
paintRow(p, _above, ms);
paintRow(p, _rows[_above].get(), _above, ms);
}
}
}
void StickersBox::Inner::resizeEvent(QResizeEvent *e) {
updateControlsGeometry();
}
void StickersBox::Inner::updateControlsGeometry() {
if (_megagroupSet) {
auto top = st::groupStickersFieldPadding.top();
auto fieldLeft = st::boxLayerTitlePosition.x();
_megagroupSetField->setGeometryToLeft(fieldLeft, top, width() - fieldLeft - st::groupStickersFieldPadding.right(), _megagroupSetField->height());
top += _megagroupSetField->height() + st::groupStickersFieldPadding.bottom();
if (_megagroupSelectedRemove) {
_megagroupSelectedShadow->setGeometryToLeft(0, top, width(), st::lineWidth);
top += st::lineWidth;
_megagroupSelectedRemove->moveToRight(st::groupStickersRemovePosition.x(), top + st::groupStickersRemovePosition.y());
top += _rowHeight;
}
_megagroupDivider->setGeometryToLeft(0, top, width(), _megagroupDivider->height());
top += _megagroupDivider->height();
_megagroupSubTitle->moveToLeft(st::boxLayerTitlePosition.x(), top + st::boxLayerTitlePosition.y());
}
}
QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
auto buttonw = st::stickersRemove.width;
auto buttonh = st::stickersRemove.height;
@ -662,14 +739,21 @@ QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
return QRect(buttonx, buttony, buttonw, buttonh);
}
void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
auto s = _rows.at(index);
auto xadd = 0, yadd = qRound(s->yadd.current());
void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) {
auto xadd = 0, yadd = qRound(set->yadd.current());
if (xadd || yadd) p.translate(xadd, yadd);
if (_megagroupSet) {
if (index >= 0 && index == _selected) {
p.fillRect(0, 0, width(), _rowHeight, st::contactsBgOver);
if (set->ripple) {
set->ripple->paint(p, 0, 0, width(), ms);
}
}
}
if (_section == Section::Installed) {
if (index == _above) {
if (index >= 0 && index == _above) {
auto current = _aboveShadowFadeOpacity.current();
if (_started >= 0) {
auto reachedOpacity = aboveShadowOpacity();
@ -686,16 +770,16 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
App::roundRect(p, row, st::boxBg, BoxCorners);
p.setOpacity(1. - current);
paintFakeButton(p, index, ms);
paintFakeButton(p, set, index, ms);
p.setOpacity(1.);
} else if (!_megagroupSet) {
paintFakeButton(p, index, ms);
paintFakeButton(p, set, index, ms);
}
} else if (!_megagroupSet) {
paintFakeButton(p, index, ms);
paintFakeButton(p, set, index, ms);
}
if (s->removed && _section == Section::Installed) {
if (set->removed && _section == Section::Installed) {
p.setOpacity(st::stickersRowDisabledOpacity);
}
@ -703,15 +787,15 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
if (!_megagroupSet && _section == Section::Installed) {
stickerx += st::stickersReorderIcon.width() + st::stickersReorderSkip;
if (!s->isRecentSet()) {
if (!set->isRecentSet()) {
st::stickersReorderIcon.paint(p, st::contactsPadding.left(), (_rowHeight - st::stickersReorderIcon.height()) / 2, width());
}
}
if (s->sticker) {
s->sticker->thumb->load();
QPixmap pix(s->sticker->thumb->pix(s->pixw, s->pixh));
p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - s->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - s->pixh) / 2, width(), pix);
if (set->sticker) {
set->sticker->thumb->load();
auto pix = set->sticker->thumb->pix(set->pixw, set->pixh);
p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix);
}
int namex = stickerx + st::contactsPhotoSize + st::contactsPadding.left();
@ -722,19 +806,19 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
p.setFont(st::contactsNameStyle.font);
p.setPen(st::contactsNameFg);
p.drawTextLeft(namex, namey, width(), s->title, s->titleWidth);
p.drawTextLeft(namex, namey, width(), set->title, set->titleWidth);
if (s->unread) {
if (set->unread) {
p.setPen(Qt::NoPen);
p.setBrush(st::stickersFeaturedUnreadBg);
{
PainterHighQualityEnabler hq(p);
p.drawEllipse(rtlrect(namex + s->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
p.drawEllipse(rtlrect(namex + set->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
}
}
auto statusText = (s->count > 0) ? lng_stickers_count(lt_count, s->count) : lang(lng_contacts_loading);
auto statusText = (set->count > 0) ? lng_stickers_count(lt_count, set->count) : lang(lng_contacts_loading);
p.setFont(st::contactsStatusFont);
p.setPen(st::contactsStatusFg);
@ -744,8 +828,7 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
if (xadd || yadd) p.translate(-xadd, -yadd);
}
void StickersBox::Inner::paintFakeButton(Painter &p, int index, TimeMs ms) {
auto set = _rows[index];
void StickersBox::Inner::paintFakeButton(Painter &p, Row *set, int index, TimeMs ms) {
auto removeButton = (_section == Section::Installed && !set->removed);
auto rect = relativeButtonRect(removeButton);
if (_section != Section::Installed && set->installed && !set->archived && !set->removed) {
@ -794,7 +877,7 @@ void StickersBox::Inner::mousePressEvent(QMouseEvent *e) {
_mouse = e->globalPos();
onUpdateSelected();
_pressed = _selected;
setPressed(_selected);
if (_actionSel >= 0) {
setActionDown(_actionSel);
update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
@ -810,7 +893,7 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
}
if (_actionDown >= 0 && _actionDown < _rows.size()) {
update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight);
auto set = _rows[_actionDown];
auto &set = _rows[_actionDown];
if (set->ripple) {
set->ripple->lastStop();
}
@ -818,7 +901,7 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
_actionDown = newActionDown;
if (_actionDown >= 0 && _actionDown < _rows.size()) {
update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight);
auto set = _rows[_actionDown];
auto &set = _rows[_actionDown];
auto removeButton = (_section == Section::Installed && !set->removed);
if (!set->ripple) {
if (_section == Section::Installed) {
@ -844,8 +927,46 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
}
}
void StickersBox::Inner::setSelected(int selected) {
if (_selected == selected) {
return;
}
if (_megagroupSet && _selected >= 0 && _selected < _rows.size()) {
update(0, _itemsTop + _selected * _rowHeight, width(), _rowHeight);
}
_selected = selected;
if (_megagroupSet && _selected >= 0 && _selected < _rows.size()) {
update(0, _itemsTop + _selected * _rowHeight, width(), _rowHeight);
}
}
void StickersBox::Inner::setPressed(int pressed) {
if (_pressed == pressed) {
return;
}
if (_megagroupSet && _pressed >= 0 && _pressed < _rows.size()) {
update(0, _itemsTop + _pressed * _rowHeight, width(), _rowHeight);
auto &set = _rows[_pressed];
if (set->ripple) {
set->ripple->lastStop();
}
}
_pressed = pressed;
if (_megagroupSet && _pressed >= 0 && _pressed < _rows.size()) {
update(0, _itemsTop + _pressed * _rowHeight, width(), _rowHeight);
auto &set = _rows[_pressed];
auto rippleMask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight));
if (!_rows[_pressed]->ripple) {
_rows[_pressed]->ripple = std::make_unique<Ui::RippleAnimation>(st::contactsRipple, std::move(rippleMask), [this, index = _pressed] {
update(0, _itemsTop + index * _rowHeight, width(), _rowHeight);
});
}
_rows[_pressed]->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(0, _itemsTop + _pressed * _rowHeight));
}
}
void StickersBox::Inner::ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton) {
_rows[_actionDown]->ripple = MakeShared<Ui::RippleAnimation>(st, std::move(mask), [this, index = _actionDown, removeButton] {
_rows[_actionDown]->ripple = std::make_unique<Ui::RippleAnimation>(st, std::move(mask), [this, index = _actionDown, removeButton] {
update(myrtlrect(relativeButtonRect(removeButton).translated(0, _itemsTop + index * _rowHeight)));
});
}
@ -906,10 +1027,10 @@ void StickersBox::Inner::onUpdateSelected() {
auto selected = -1;
auto actionSel = -1;
auto inDragArea = false;
if (in && !_rows.isEmpty()) {
if (in && !_rows.empty()) {
selected = floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1);
local.setY(local.y() - _itemsTop - selected * _rowHeight);
auto set = _rows[selected];
auto &set = _rows[selected];
if (!_megagroupSet && (_section == Section::Installed || !set->installed || set->archived || set->removed)) {
auto removeButton = (_section == Section::Installed && !set->removed);
auto rect = myrtlrect(relativeButtonRect(removeButton));
@ -931,7 +1052,7 @@ void StickersBox::Inner::onUpdateSelected() {
setCursor((selected >= 0 || _pressed >= 0) ? style::cur_pointer : style::cur_default);
}
}
_selected = selected;
setSelected(selected);
}
if (_inDragArea != inDragArea) {
_inDragArea = inDragArea;
@ -978,16 +1099,14 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
} else if (pressed == _selected && _actionSel < 0 && _actionDown < 0) {
if (_selected >= 0 && !_inDragArea) {
auto &sets = Global::RefStickerSets();
auto row = _rows[pressed];
auto &row = _rows[pressed];
if (!row->isRecentSet()) {
auto it = sets.find(row->id);
if (it != sets.cend()) {
_selected = -1;
if (_megagroupSet) {
Auth().api().setGroupStickerSet(_megagroupSet, Stickers::inputSetId(*it));
Ui::hideLayer();
App::main()->onStickersInstalled(Stickers::MegagroupSetId);
setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)));
} else {
setSelected(-1);
Ui::show(Box<StickerSetBox>(Stickers::inputSetId(*it)), KeepOtherLayers);
}
}
@ -997,8 +1116,18 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
setActionDown(-1);
}
void StickersBox::Inner::saveGroupSet() {
Expects(_megagroupSet != nullptr);
auto oldId = (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) ? _megagroupSet->mgInfo->stickerSet.c_inputStickerSetID().vid.v : 0;
auto newId = (_megagroupSetInput.type() == mtpc_inputStickerSetID) ? _megagroupSetInput.c_inputStickerSetID().vid.v : 0;
if (newId != oldId) {
Auth().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput);
App::main()->onStickersInstalled(Stickers::MegagroupSetId);
}
}
void StickersBox::Inner::setRowRemoved(int index, bool removed) {
auto row = _rows[index];
auto &row = _rows[index];
if (row->removed != removed) {
row->removed = removed;
row->ripple.reset();
@ -1012,6 +1141,11 @@ void StickersBox::Inner::leaveEventHook(QEvent *e) {
onUpdateSelected();
}
void StickersBox::Inner::leaveToChildEvent(QEvent *e, QWidget *child) {
_mouse = QPoint(-1, -1);
onUpdateSelected();
}
void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
auto animating = false;
auto updateMin = -1;
@ -1062,19 +1196,16 @@ void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
}
void StickersBox::Inner::clear() {
for (int32 i = 0, l = _rows.size(); i < l; ++i) {
delete _rows.at(i);
}
_rows.clear();
_animStartTimes.clear();
_aboveShadowFadeStart = 0;
_aboveShadowFadeOpacity = anim::value();
_a_shifting.stop();
_above = _dragging = _started = -1;
_selected = -1;
_pressed = -1;
_actionDown = -1;
setSelected(-1);
setPressed(-1);
setActionSel(-1);
setActionDown(-1);
update();
}
@ -1089,10 +1220,86 @@ void StickersBox::Inner::setActionSel(int32 actionSel) {
}
}
void StickersBox::Inner::handleMegagroupSetAddressChange() {
auto text = _megagroupSetField->getLastText().trimmed();
if (text.isEmpty()) {
if (_megagroupSelectedSet) {
auto it = Global::StickerSets().constFind(_megagroupSelectedSet->id);
if (it != Global::StickerSets().end() && !it->shortName.isEmpty()) {
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
}
}
} else if (!_megagroupSetRequestId) {
_megagroupSetRequestId = request(MTPmessages_GetStickerSet(MTP_inputStickerSetShortName(MTP_string(text)))).done([this](const MTPmessages_StickerSet &result) {
_megagroupSetRequestId = 0;
auto set = Stickers::FeedSetFull(result);
setMegagroupSelectedSet(MTP_inputStickerSetID(MTP_long(set->id), MTP_long(set->access)));
}).fail([this](const RPCError &error) {
_megagroupSetRequestId = 0;
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
}).send();
} else {
_megagroupSetAddressChangedTimer.callOnce(kHandleMegagroupSetAddressChangeTimeout);
}
}
void StickersBox::Inner::rebuildMegagroupSet() {
Expects(_megagroupSet != nullptr);
if (_megagroupSetInput.type() != mtpc_inputStickerSetID) {
if (_megagroupSelectedSet) {
_megagroupSetField->setText(QString());
_megagroupSetField->finishAnimations();
}
_megagroupSelectedSet.reset();
_megagroupSelectedRemove.destroy();
_megagroupSelectedShadow.destroy();
return;
}
auto &set = _megagroupSetInput.c_inputStickerSetID();
auto setId = set.vid.v;
auto &sets = Global::StickerSets();
auto it = sets.find(setId);
if (it == sets.cend() || (it->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
Auth().api().scheduleStickerSetRequest(set.vid.v, set.vaccess_hash.v);
return;
}
auto maxNameWidth = countMaxNameWidth();
auto titleWidth = 0;
auto title = fillSetTitle(*it, maxNameWidth, &titleWidth);
auto count = fillSetCount(*it);
auto sticker = (DocumentData*)nullptr;
auto pixw = 0, pixh = 0;
fillSetCover(*it, &sticker, &pixw, &pixh);
auto installed = true, official = false, unread = false, archived = false, removed = false;
if (!_megagroupSelectedSet || _megagroupSelectedSet->id != it->id) {
_megagroupSetField->setText(it->shortName);
_megagroupSetField->finishAnimations();
}
_megagroupSelectedSet = std::make_unique<Row>(it->id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh);
_itemsTop += st::lineWidth + _rowHeight;
if (!_megagroupSelectedRemove) {
_megagroupSelectedRemove.create(this, st::groupStickersRemove);
_megagroupSelectedRemove->showFast();
_megagroupSelectedRemove->setClickedCallback([this] {
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
});
_megagroupSelectedShadow.create(this);
updateControlsGeometry();
}
}
void StickersBox::Inner::rebuild() {
_itemsTop = st::membersMarginTop;
int maxNameWidth = countMaxNameWidth();
if (_megagroupSet) {
_itemsTop += st::groupStickersFieldPadding.top() + _megagroupSetField->height() + st::groupStickersFieldPadding.bottom();
_itemsTop += _megagroupDivider->height() + st::groupStickersSubTitleHeight;
rebuildMegagroupSet();
}
auto maxNameWidth = countMaxNameWidth();
clear();
auto &order = ([this]() -> const Stickers::Order & {
@ -1131,21 +1338,34 @@ void StickersBox::Inner::rebuild() {
updateSize();
}
void StickersBox::Inner::updateSize() {
resize(width(), _itemsTop + _rows.size() * _rowHeight + st::membersMarginBottom);
void StickersBox::Inner::setMegagroupSelectedSet(const MTPInputStickerSet &set) {
_megagroupSetInput = set;
rebuild();
scrollToY.notify(0, true);
onUpdateSelected();
}
void StickersBox::Inner::setMinHeight(int newWidth, int minHeight) {
_minHeight = minHeight;
updateSize(newWidth);
}
void StickersBox::Inner::updateSize(int newWidth) {
auto naturalHeight = _itemsTop + int(_rows.size()) * _rowHeight + st::membersMarginBottom;
resize(newWidth ? newWidth : width(), qMax(_minHeight, naturalHeight));
checkLoadMore();
}
void StickersBox::Inner::updateRows() {
int maxNameWidth = countMaxNameWidth();
auto &sets = Global::StickerSets();
for_const (auto row, _rows) {
for_const (auto &row, _rows) {
auto it = sets.constFind(row->id);
if (it != sets.cend()) {
auto &set = it.value();
if (!row->sticker) {
DocumentData *sticker = nullptr;
int pixw = 0, pixh = 0;
auto sticker = (DocumentData*)nullptr;
auto pixw = 0, pixh = 0;
fillSetCover(set, &sticker, &pixw, &pixh);
if (sticker) {
row->sticker = sticker;
@ -1172,7 +1392,7 @@ void StickersBox::Inner::updateRows() {
}
bool StickersBox::Inner::appendSet(const Stickers::Set &set) {
for_const (auto row, _rows) {
for_const (auto &row, _rows) {
if (row->id == set.id) {
return false;
}
@ -1212,7 +1432,7 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW
QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
int count = fillSetCount(set);
_rows.push_back(new Row(set.id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh));
_rows.push_back(std::make_unique<Row>(set.id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh));
_animStartTimes.push_back(0);
}
@ -1288,8 +1508,8 @@ template <typename Check>
Stickers::Order StickersBox::Inner::collectSets(Check check) const {
Stickers::Order result;
result.reserve(_rows.size());
for_const (auto row, _rows) {
if (check(row)) {
for_const (auto &row, _rows) {
if (check(row.get())) {
result.push_back(row->id);
}
}
@ -1315,8 +1535,8 @@ Stickers::Order StickersBox::Inner::getRemovedSets() const {
}
int StickersBox::Inner::getRowIndex(uint64 setId) const {
for (auto i = 0, count = _rows.size(); i != count; ++i) {
auto row = _rows[i];
for (auto i = 0, count = int(_rows.size()); i != count; ++i) {
auto &row = _rows[i];
if (row->id == setId) {
return i;
}
@ -1328,18 +1548,18 @@ void StickersBox::Inner::setFullOrder(const Stickers::Order &order) {
for_const (auto setId, order) {
auto index = getRowIndex(setId);
if (index >= 0) {
auto row = _rows[index];
auto row = std::move(_rows[index]);
auto count = _rows.size();
for (auto i = index + 1; i != count; ++i) {
_rows[i - 1] = _rows[i];
_rows[i - 1] = std::move(_rows[i]);
}
_rows[count - 1] = row;
_rows[count - 1] = std::move(row);
}
}
}
void StickersBox::Inner::setRemovedSets(const Stickers::Order &removed) {
for (auto i = 0, count = _rows.size(); i != count; ++i) {
for (auto i = 0, count = int(_rows.size()); i != count; ++i) {
setRowRemoved(i, removed.contains(_rows[i]->id));
}
}

View File

@ -21,6 +21,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#pragma once
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "mtproto/sender.h"
class ConfirmBox;
@ -33,6 +35,8 @@ class PlainShadow;
class RippleAnimation;
class SettingsSlider;
class SlideAnimation;
class UsernameInput;
class CrossButton;
} // namespace Ui
class StickersBox : public BoxContent, public RPCSender {
@ -48,6 +52,7 @@ public:
StickersBox(QWidget*, gsl::not_null<ChannelData*> megagroup);
void closeHook() override;
void setInnerFocus() override;
~StickersBox();
@ -142,7 +147,7 @@ private:
int stickerPacksCount(bool includeArchivedOfficial = false);
// This class is hold in header because it requires Qt preprocessing.
class StickersBox::Inner : public TWidget, private base::Subscriber {
class StickersBox::Inner : public TWidget, private base::Subscriber, private MTP::Sender {
Q_OBJECT
public:
@ -151,8 +156,13 @@ public:
Inner(QWidget *parent, const Stickers::Order &archivedIds);
Inner(QWidget *parent, gsl::not_null<ChannelData*> megagroup);
base::Observable<int> scrollToY;
void setInnerFocus();
void saveGroupSet();
void rebuild();
void updateSize();
void updateSize(int newWidth = 0);
void updateRows(); // refresh only pack cover stickers
bool appendSet(const Stickers::Set &set);
@ -171,6 +181,7 @@ public:
}
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
void setMinHeight(int newWidth, int minHeight);
int getVisibleTop() const {
return _visibleTop;
@ -180,10 +191,12 @@ public:
protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void leaveEventHook(QEvent *e) override;
void leaveToChildEvent(QEvent *e, QWidget *child) override;
signals:
void draggingScrollDelta(int delta);
@ -192,6 +205,29 @@ public slots:
void onUpdateSelected();
private:
struct Row {
Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh);
bool isRecentSet() const {
return (id == Stickers::CloudRecentSetId);
}
~Row();
uint64 id = 0;
DocumentData *sticker = nullptr;
int32 count = 0;
QString title;
int titleWidth = 0;
bool installed = false;
bool official = false;
bool unread = false;
bool archived = false;
bool removed = false;
int32 pixw = 0;
int32 pixh = 0;
anim::value yadd;
std::unique_ptr<Ui::RippleAnimation> ripple;
};
template <typename Check>
Stickers::Order collectSets(Check check) const;
@ -200,63 +236,40 @@ private:
int getRowIndex(uint64 setId) const;
void setRowRemoved(int index, bool removed);
void setSelected(int selected);
void setActionDown(int newActionDown);
void setPressed(int pressed);
void setup();
QRect relativeButtonRect(bool removeButton) const;
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
void step_shifting(TimeMs ms, bool timer);
void paintRow(Painter &p, int index, TimeMs ms);
void paintFakeButton(Painter &p, int index, TimeMs ms);
void paintRow(Painter &p, Row *set, int index, TimeMs ms);
void paintFakeButton(Painter &p, Row *set, int index, TimeMs ms);
void clear();
void setActionSel(int32 actionSel);
float64 aboveShadowOpacity() const;
void readVisibleSets();
Section _section;
Stickers::Order _archivedIds;
int32 _rowHeight;
struct Row {
Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh) : id(id)
, sticker(sticker)
, count(count)
, title(title)
, titleWidth(titleWidth)
, installed(installed)
, official(official)
, unread(unread)
, archived(archived)
, removed(removed)
, pixw(pixw)
, pixh(pixh)
, yadd(0, 0) {
}
bool isRecentSet() const {
return (id == Stickers::CloudRecentSetId);
}
uint64 id;
DocumentData *sticker;
int32 count;
QString title;
int titleWidth;
bool installed, official, unread, archived, removed;
int32 pixw, pixh;
anim::value yadd;
QSharedPointer<Ui::RippleAnimation> ripple;
};
using Rows = QList<Row*>;
void updateControlsGeometry();
void rebuildAppendSet(const Stickers::Set &set, int maxNameWidth);
void fillSetCover(const Stickers::Set &set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
int fillSetCount(const Stickers::Set &set) const;
QString fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const;
void fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived);
void rebuildMegagroupSet();
void handleMegagroupSetAddressChange();
void setMegagroupSelectedSet(const MTPInputStickerSet &set);
int countMaxNameWidth() const;
Rows _rows;
Section _section;
Stickers::Order _archivedIds;
int32 _rowHeight;
std::vector<std::unique_ptr<Row>> _rows;
QList<TimeMs> _animStartTimes;
TimeMs _aboveShadowFadeStart = 0;
anim::value _aboveShadowFadeOpacity;
@ -288,7 +301,18 @@ private:
int _dragging = -1;
int _above = -1;
int _minHeight = 0;
int _scrollbar = 0;
ChannelData *_megagroupSet = nullptr;
MTPInputStickerSet _megagroupSetInput = MTP_inputStickerSetEmpty();
std::unique_ptr<Row> _megagroupSelectedSet;
object_ptr<Ui::UsernameInput> _megagroupSetField = { nullptr };
object_ptr<BoxLayerTitleShadow> _megagroupSelectedShadow = { nullptr };
object_ptr<Ui::CrossButton> _megagroupSelectedRemove = { nullptr };
object_ptr<BoxContentDivider> _megagroupDivider = { nullptr };
object_ptr<Ui::FlatLabel> _megagroupSubTitle = { nullptr };
base::Timer _megagroupSetAddressChangedTimer;
mtpRequestId _megagroupSetRequestId = 0;
};

View File

@ -436,10 +436,10 @@ void StickersListWidget::Footer::step_icons(TimeMs ms, bool timer) {
StickersListWidget::StickersListWidget(QWidget *parent, gsl::not_null<Window::Controller*> controller) : Inner(parent, controller)
, _section(Section::Stickers)
, _megagroupSetAbout(st::emojiPanWidth - st::emojiScroll.width - st::emojiPanHeaderLeft)
, _addText(lang(lng_stickers_featured_add).toUpper())
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
, _settings(this, lang(lng_stickers_you_have))
, _megagroupSetAbout(st::emojiPanWidth - st::emojiScroll.width - st::emojiPanHeaderLeft) {
, _settings(this, lang(lng_stickers_you_have)) {
resize(st::emojiPanWidth - st::emojiScroll.width - st::buttonRadius, countHeight());
setMouseTracking(true);
@ -877,7 +877,10 @@ bool StickersListWidget::hasRemoveButton(int index) const {
}
if (set.id == Stickers::MegagroupSetId) {
t_assert(_megagroupSet != nullptr);
return set.pack.empty() ? (index + 1 != _mySets.size()) : _megagroupSet->canEditStickers();
if (index + 1 != _mySets.size()) {
return true;
}
return !set.pack.empty() && _megagroupSet->canEditStickers();
}
return false;
}
@ -1015,7 +1018,9 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
if (_section == Section::Featured) {
installSet(sets[button->section].id);
} else if (sets[button->section].id == Stickers::MegagroupSetId) {
removeMegagroupSet(sets[button->section].pack.empty());
auto removeLocally = sets[button->section].pack.empty()
|| !_megagroupSet->canEditStickers();
removeMegagroupSet(removeLocally);
} else {
removeSet(sets[button->section].id);
}
@ -1293,36 +1298,53 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
if (!_megagroupSet) {
return;
}
auto canEdit = _megagroupSet->canEditStickers();
auto isShownHere = [place](bool hidden) {
return (hidden == (place == GroupStickersPlace::Hidden));
};
if (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetEmpty) {
if (_megagroupSet->canEditStickers()) {
if (canEdit) {
auto hidden = Auth().data().isGroupStickersSectionHidden(_megagroupSet->id);
if (hidden == (place == GroupStickersPlace::Hidden)) {
if (isShownHere(hidden)) {
_mySets.push_back(Set(Stickers::MegagroupSetId, qFlags(MTPDstickerSet_ClientFlag::f_special), lang(lng_group_stickers), 0));
}
}
return;
}
if (place != GroupStickersPlace::Visible) {
return;
}
if (Auth().data().isGroupStickersSectionHidden(_megagroupSet->id)) {
Auth().data().removeGroupStickersSectionHidden(_megagroupSet->id);
Local::writeUserSettings();
auto hidden = Auth().data().isGroupStickersSectionHidden(_megagroupSet->id);
auto removeHiddenForGroup = [this, &hidden] {
if (hidden) {
Auth().data().removeGroupStickersSectionHidden(_megagroupSet->id);
Local::writeUserSettings();
hidden = false;
}
};
if (canEdit && hidden) {
removeHiddenForGroup();
}
if (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) {
auto &set = _megagroupSet->mgInfo->stickerSet.c_inputStickerSetID();
auto &sets = Global::StickerSets();
auto it = sets.constFind(set.vid.v);
if (it != sets.cend()) {
_mySets.push_back(Set(Stickers::MegagroupSetId, qFlags(MTPDstickerSet_ClientFlag::f_special), lang(lng_group_stickers), it->stickers.size() + 1, it->stickers));
auto isInstalled = (it->flags & MTPDstickerSet::Flag::f_installed)
&& !(it->flags & MTPDstickerSet::Flag::f_archived);
if (isInstalled && !canEdit) {
removeHiddenForGroup();
} else if (isShownHere(hidden)) {
_mySets.push_back(Set(Stickers::MegagroupSetId, qFlags(MTPDstickerSet_ClientFlag::f_special), lang(lng_group_stickers), it->stickers.size() + 1, it->stickers));
}
return;
}
}
if (!isShownHere(hidden)) {
return;
}
request(MTPmessages_GetStickerSet(_megagroupSet->mgInfo->stickerSet)).done([this](const MTPmessages_StickerSet &result) {
if (auto set = Stickers::FeedSetFull(result)) {
refreshStickers();
}
});
}).send();
}
void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
@ -1417,6 +1439,9 @@ void StickersListWidget::updateSelected() {
newSelected = OverButton { section };
} else if (!(sets[section].flags & MTPDstickerSet_ClientFlag::f_special)) {
newSelected = OverSet { section };
} else if (sets[section].id == Stickers::MegagroupSetId
&& (_megagroupSet->canEditStickers() || !sets[section].pack.empty())) {
newSelected = OverSet { section };
}
} else if (p.y() >= info.rowsTop && p.y() < info.rowsBottom && sx >= 0) {
auto yOffset = p.y() - info.rowsTop;
@ -1578,6 +1603,21 @@ void StickersListWidget::showMegagroupSet(ChannelData *megagroup) {
}
void StickersListWidget::displaySet(uint64 setId) {
if (setId == Stickers::MegagroupSetId) {
if (_megagroupSet->canEditStickers()) {
_displayingSetId = setId;
auto box = Ui::show(Box<StickersBox>(_megagroupSet));
connect(box, &QObject::destroyed, this, [this] {
_displayingSetId = 0;
emit checkForHide();
});
return;
} else if (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetID) {
setId = _megagroupSet->mgInfo->stickerSet.c_inputStickerSetID().vid.v;
} else {
return;
}
}
auto &sets = Global::StickerSets();
auto it = sets.constFind(setId);
if (it != sets.cend()) {
@ -1608,8 +1648,8 @@ void StickersListWidget::installSet(uint64 setId) {
}
}
void StickersListWidget::removeMegagroupSet(bool empty) {
if (empty) {
void StickersListWidget::removeMegagroupSet(bool locally) {
if (locally) {
Auth().data().setGroupStickersSectionHidden(_megagroupSet->id);
Local::writeUserSettings();
refreshStickers();
@ -1675,4 +1715,6 @@ void StickersListWidget::removeSet(uint64 setId) {
}
}
StickersListWidget::~StickersListWidget() = default;
} // namespace ChatHelpers

View File

@ -62,6 +62,8 @@ public:
void notInstalledLocally(uint64 setId);
void clearInstalledLocally();
~StickersListWidget();
protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
@ -148,7 +150,7 @@ private:
void displaySet(uint64 setId);
void installSet(uint64 setId);
void removeMegagroupSet(bool empty);
void removeMegagroupSet(bool locally);
void removeSet(uint64 setId);
bool setHasTitle(const Set &set) const;

View File

@ -3435,7 +3435,7 @@ void MaskedInputField::paintEvent(QPaintEvent *e) {
auto placeholderTop = anim::interpolate(0, _st.placeholderShift, placeholderShiftDegree);
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
QRect r(rect().marginsRemoved(_textMargins + _st.placeholderMargins));
r.moveTop(r.top() + placeholderTop);
if (rtl()) r.moveLeft(width() - r.left() - r.width());
@ -3460,7 +3460,7 @@ void MaskedInputField::paintEvent(QPaintEvent *e) {
auto placeholderLeft = anim::interpolate(0, -_st.placeholderShift, placeholderHiddenDegree);
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
QRect r(rect().marginsRemoved(_textMargins + _st.placeholderMargins));
r.moveLeft(r.left() + placeholderLeft);
if (rtl()) r.moveLeft(width() - r.left() - r.width());
@ -3469,6 +3469,7 @@ void MaskedInputField::paintEvent(QPaintEvent *e) {
p.drawText(r, _placeholder, _st.placeholderAlign);
p.restore();
p.setOpacity(1.);
}
}
@ -3525,7 +3526,7 @@ void MaskedInputField::resizeEvent(QResizeEvent *e) {
void MaskedInputField::refreshPlaceholder() {
auto placeholderText = _placeholderFactory ? _placeholderFactory() : QString();
auto availableWidth = width() - _st.textMargins.left() - _st.textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1;
auto availableWidth = width() - _textMargins.left() - _textMargins.right() - _st.placeholderMargins.left() - _st.placeholderMargins.right() - 1;
if (_st.placeholderScale > 0.) {
auto placeholderFont = _st.placeholderFont->f;
placeholderFont.setStyleStrategy(QFont::PreferMatch);
@ -3609,7 +3610,7 @@ void MaskedInputField::startPlaceholderAnimation() {
}
QRect MaskedInputField::placeholderRect() const {
return rect().marginsRemoved(_st.textMargins + _st.placeholderMargins);
return rect().marginsRemoved(_textMargins + _st.placeholderMargins);
}
void MaskedInputField::placeholderAdditionalPrepare(Painter &p, TimeMs ms) {
@ -3893,8 +3894,12 @@ void PortInput::correctValue(const QString &was, int32 wasCursor, QString &now,
setCorrectedText(now, nowCursor, newText, newPos);
}
UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, base::lambda<QString()> placeholderFactory, const QString &val, bool isLink) : MaskedInputField(parent, st, std::move(placeholderFactory), val)
, _linkPlaceholder(isLink ? Messenger::Instance().createInternalLink(QString()) : QString()) {
UsernameInput::UsernameInput(QWidget *parent, const style::InputField &st, base::lambda<QString()> placeholderFactory, const QString &val, bool isLink) : MaskedInputField(parent, st, std::move(placeholderFactory), val) {
setLinkPlaceholder(isLink ? Messenger::Instance().createInternalLink(QString()) : QString());
}
void UsernameInput::setLinkPlaceholder(const QString &placeholder) {
_linkPlaceholder = placeholder;
if (!_linkPlaceholder.isEmpty()) {
setTextMargins(style::margins(_st.textMargins.left() + _st.font->width(_linkPlaceholder), _st.textMargins.top(), _st.textMargins.right(), _st.textMargins.bottom()));
setPlaceholderHidden(true);

View File

@ -878,6 +878,8 @@ class UsernameInput : public MaskedInputField {
public:
UsernameInput(QWidget *parent, const style::InputField &st, base::lambda<QString()> placeholderFactory, const QString &val, bool isLink);
void setLinkPlaceholder(const QString &placeholder);
protected:
void correctValue(const QString &was, int wasCursor, QString &now, int &nowCursor) override;
void paintAdditionalPlaceholder(Painter &p, TimeMs ms) override;