mirror of https://github.com/procxx/kepka.git
Support any size in the tabbed selector.
This commit is contained in:
parent
5c12b0e5fa
commit
0255d0c59e
|
@ -133,11 +133,13 @@ emojiObjectsActive: icon {{ "emoji_objects", emojiIconFgActive }};
|
||||||
emojiSymbols: icon {{ "emoji_symbols", emojiIconFg }};
|
emojiSymbols: icon {{ "emoji_symbols", emojiIconFg }};
|
||||||
emojiSymbolsActive: icon {{ "emoji_symbols", emojiIconFgActive }};
|
emojiSymbolsActive: icon {{ "emoji_symbols", emojiIconFgActive }};
|
||||||
|
|
||||||
|
emojiFooterHeight: 46px;
|
||||||
|
emojiCategorySkip: 4px;
|
||||||
emojiCategory: IconButton {
|
emojiCategory: IconButton {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
height: 46px;
|
height: emojiFooterHeight;
|
||||||
|
|
||||||
iconPosition: point(8px, 9px);
|
iconPosition: point(-1px, 9px);
|
||||||
}
|
}
|
||||||
emojiCategoryRecent: IconButton(emojiCategory) { icon: emojiRecent; }
|
emojiCategoryRecent: IconButton(emojiCategory) { icon: emojiRecent; }
|
||||||
emojiCategoryPeople: IconButton(emojiCategory) { icon: emojiPeople; }
|
emojiCategoryPeople: IconButton(emojiCategory) { icon: emojiPeople; }
|
||||||
|
@ -152,7 +154,6 @@ emojiPanAnimation: PanelAnimation(defaultPanelAnimation) {
|
||||||
fadeBg: emojiPanBg;
|
fadeBg: emojiPanBg;
|
||||||
}
|
}
|
||||||
emojiPanPadding: 12px;
|
emojiPanPadding: 12px;
|
||||||
emojiPanSize: size(45px, 41px);
|
|
||||||
emojiPanWidth: 345px;
|
emojiPanWidth: 345px;
|
||||||
emojiPanMinHeight: 278px;
|
emojiPanMinHeight: 278px;
|
||||||
emojiPanMaxHeight: 640px;
|
emojiPanMaxHeight: 640px;
|
||||||
|
@ -192,7 +193,8 @@ hashtagClose: IconButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stickerPanSize: size(64px, 64px);
|
stickerPanWidthMin: 64px;
|
||||||
|
stickerPanSize: size(stickerPanWidthMin, stickerPanWidthMin);
|
||||||
stickerPanPadding: 11px;
|
stickerPanPadding: 11px;
|
||||||
stickerPanDeleteIconBg: icon {{ "emoji_delete_bg", stickerPanDeleteBg }};
|
stickerPanDeleteIconBg: icon {{ "emoji_delete_bg", stickerPanDeleteBg }};
|
||||||
stickerPanDeleteIconFg: icon {{ "emoji_delete", stickerPanDeleteFg }};
|
stickerPanDeleteIconFg: icon {{ "emoji_delete", stickerPanDeleteFg }};
|
||||||
|
@ -201,6 +203,8 @@ stickerPanDeleteOpacityBgOver: 0.5;
|
||||||
stickerPanDeleteOpacityFg: 0.8;
|
stickerPanDeleteOpacityFg: 0.8;
|
||||||
stickerPanDeleteOpacityFgOver: 1.;
|
stickerPanDeleteOpacityFgOver: 1.;
|
||||||
stickerPanRemoveSet: hashtagClose;
|
stickerPanRemoveSet: hashtagClose;
|
||||||
|
stickerIconWidth: 42px;
|
||||||
|
stickerIconHeight: emojiFooterHeight;
|
||||||
stickerIconPadding: 5px;
|
stickerIconPadding: 5px;
|
||||||
stickerIconOpacity: 0.7;
|
stickerIconOpacity: 0.7;
|
||||||
stickerIconSel: 2px;
|
stickerIconSel: 2px;
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void processPanelHideFinished() override;
|
void processPanelHideFinished() override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void prepareSection(int &left, int top, int _width, Ui::IconButton *sectionIcon, Section section);
|
void prepareSection(int &left, int top, int _width, Ui::IconButton *sectionIcon, Section section);
|
||||||
|
@ -63,16 +64,27 @@ EmojiListWidget::Footer::Footer(not_null<EmojiListWidget*> parent) : InnerFooter
|
||||||
object_ptr<Ui::IconButton>(this, st::emojiCategoryObjects),
|
object_ptr<Ui::IconButton>(this, st::emojiCategoryObjects),
|
||||||
object_ptr<Ui::IconButton>(this, st::emojiCategorySymbols),
|
object_ptr<Ui::IconButton>(this, st::emojiCategorySymbols),
|
||||||
} } {
|
} } {
|
||||||
auto left = (st::emojiPanWidth - _sections.size() * st::emojiCategory.width) / 2;
|
|
||||||
for (auto i = 0; i != _sections.size(); ++i) {
|
for (auto i = 0; i != _sections.size(); ++i) {
|
||||||
auto &button = _sections[i];
|
auto value = static_cast<Section>(i);
|
||||||
button->moveToLeft(left, 0);
|
_sections[i]->setClickedCallback([=] {
|
||||||
left += button->width();
|
setActiveSection(value);
|
||||||
button->setClickedCallback([this, value = static_cast<Section>(i)] { setActiveSection(value); });
|
});
|
||||||
}
|
}
|
||||||
setCurrentSectionIcon(Section::Recent);
|
setCurrentSectionIcon(Section::Recent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::Footer::resizeEvent(QResizeEvent *e) {
|
||||||
|
auto availableWidth = (width() - st::emojiCategorySkip * 2);
|
||||||
|
auto buttonWidth = availableWidth / _sections.size();
|
||||||
|
auto buttonsWidth = buttonWidth * _sections.size();
|
||||||
|
auto left = (width() - buttonsWidth) / 2;
|
||||||
|
for (auto &button : _sections) {
|
||||||
|
button->resizeToWidth(buttonWidth);
|
||||||
|
button->moveToLeft(left, 0);
|
||||||
|
left += button->width();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiListWidget::Footer::processPanelHideFinished() {
|
void EmojiListWidget::Footer::processPanelHideFinished() {
|
||||||
// Preserve panel state through visibility toggles.
|
// Preserve panel state through visibility toggles.
|
||||||
//setCurrentSectionIcon(Section::Recent);
|
//setCurrentSectionIcon(Section::Recent);
|
||||||
|
@ -101,10 +113,6 @@ void EmojiListWidget::Footer::setActiveSection(Ui::Emoji::Section section) {
|
||||||
EmojiColorPicker::EmojiColorPicker(QWidget *parent) : TWidget(parent) {
|
EmojiColorPicker::EmojiColorPicker(QWidget *parent) : TWidget(parent) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
auto w = st::emojiPanMargins.left() + st::emojiPanSize.width() + st::emojiColorsSep + st::emojiPanMargins.right();
|
|
||||||
auto h = st::emojiPanMargins.top() + 2 * st::emojiColorsPadding + st::emojiPanSize.height() + st::emojiPanMargins.bottom();
|
|
||||||
resize(w, h);
|
|
||||||
|
|
||||||
_hideTimer.setSingleShot(true);
|
_hideTimer.setSingleShot(true);
|
||||||
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideAnimated()));
|
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideAnimated()));
|
||||||
}
|
}
|
||||||
|
@ -120,14 +128,27 @@ void EmojiColorPicker::showEmoji(EmojiPtr emoji) {
|
||||||
_variants[i] = emoji->variant(i);
|
_variants[i] = emoji->variant(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto w = st::emojiPanMargins.left() + st::emojiPanSize.width() * _variants.size() + (_variants.size() - 2) * st::emojiColorsPadding + st::emojiColorsSep + st::emojiPanMargins.right();
|
updateSize();
|
||||||
auto h = st::emojiPanMargins.top() + 2 * st::emojiColorsPadding + st::emojiPanSize.height() + st::emojiPanMargins.bottom();
|
|
||||||
resize(w, h);
|
|
||||||
|
|
||||||
if (!_cache.isNull()) _cache = QPixmap();
|
if (!_cache.isNull()) _cache = QPixmap();
|
||||||
showAnimated();
|
showAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiColorPicker::updateSize() {
|
||||||
|
auto width = st::emojiPanMargins.left()
|
||||||
|
+ _singleSize.width() * _variants.size()
|
||||||
|
+ (_variants.size() - 2) * st::emojiColorsPadding
|
||||||
|
+ st::emojiColorsSep
|
||||||
|
+ st::emojiPanMargins.right();
|
||||||
|
auto height = st::emojiPanMargins.top()
|
||||||
|
+ 2 * st::emojiColorsPadding
|
||||||
|
+ _singleSize.height()
|
||||||
|
+ st::emojiPanMargins.bottom();
|
||||||
|
resize(width, height);
|
||||||
|
update();
|
||||||
|
updateSelected();
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
@ -151,7 +172,7 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) {
|
||||||
Ui::Shadow::paint(p, inner, width(), st::defaultRoundShadow);
|
Ui::Shadow::paint(p, inner, width(), st::defaultRoundShadow);
|
||||||
App::roundRect(p, inner, st::boxBg, BoxCorners);
|
App::roundRect(p, inner, st::boxBg, BoxCorners);
|
||||||
|
|
||||||
auto x = st::emojiPanMargins.left() + 2 * st::emojiColorsPadding + st::emojiPanSize.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() + st::emojiColorsPadding, st::emojiColorsSep, inner.height() - st::emojiColorsPadding * 2, st::emojiColorsSepColor);
|
||||||
|
|
||||||
|
@ -197,6 +218,11 @@ void EmojiColorPicker::handleMouseRelease(QPoint globalPos) {
|
||||||
hideAnimated();
|
hideAnimated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiColorPicker::setSingleSize(QSize size) {
|
||||||
|
_singleSize = size;
|
||||||
|
updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::handleMouseMove(QPoint globalPos) {
|
void EmojiColorPicker::handleMouseMove(QPoint globalPos) {
|
||||||
_lastMousePos = globalPos;
|
_lastMousePos = globalPos;
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -262,14 +288,14 @@ 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() - st::emojiColorsPadding;
|
||||||
if (y >= 0 && y < st::emojiPanSize.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 < st::emojiPanSize.width()) {
|
if (x >= 0 && x < _singleSize.width()) {
|
||||||
newSelected = 0;
|
newSelected = 0;
|
||||||
} else {
|
} else {
|
||||||
x -= st::emojiPanSize.width() + 2 * st::emojiColorsPadding + st::emojiColorsSep;
|
x -= _singleSize.width() + 2 * st::emojiColorsPadding + st::emojiColorsSep;
|
||||||
if (x >= 0 && x < st::emojiPanSize.width() * (_variants.size() - 1)) {
|
if (x >= 0 && x < _singleSize.width() * (_variants.size() - 1)) {
|
||||||
newSelected = (x / st::emojiPanSize.width()) + 1;
|
newSelected = (x / _singleSize.width()) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +309,18 @@ void EmojiColorPicker::setSelected(int newSelected) {
|
||||||
}
|
}
|
||||||
auto updateSelectedRect = [this] {
|
auto updateSelectedRect = [this] {
|
||||||
if (_selected < 0) return;
|
if (_selected < 0) return;
|
||||||
rtlupdate(st::emojiPanMargins.left() + st::emojiColorsPadding + _selected * st::emojiPanSize.width() + (_selected ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::emojiPanMargins.top() + st::emojiColorsPadding, st::emojiPanSize.width(), st::emojiPanSize.height());
|
auto addedSkip = (_selected > 0)
|
||||||
|
? (2 * st::emojiColorsPadding + st::emojiColorsSep)
|
||||||
|
: 0;
|
||||||
|
auto left = st::emojiPanMargins.left()
|
||||||
|
+ st::emojiColorsPadding
|
||||||
|
+ _selected * _singleSize.width()
|
||||||
|
+ addedSkip;
|
||||||
|
rtlupdate(
|
||||||
|
left,
|
||||||
|
st::emojiPanMargins.top() + st::emojiColorsPadding,
|
||||||
|
_singleSize.width(),
|
||||||
|
_singleSize.height());
|
||||||
};
|
};
|
||||||
updateSelectedRect();
|
updateSelectedRect();
|
||||||
_selected = newSelected;
|
_selected = newSelected;
|
||||||
|
@ -292,20 +329,18 @@ void EmojiColorPicker::setSelected(int newSelected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
void EmojiColorPicker::drawVariant(Painter &p, int variant) {
|
||||||
QPoint w(st::emojiPanMargins.left() + st::emojiColorsPadding + variant * st::emojiPanSize.width() + (variant ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::emojiPanMargins.top() + st::emojiColorsPadding);
|
QPoint w(st::emojiPanMargins.left() + st::emojiColorsPadding + variant * _singleSize.width() + (variant ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::emojiPanMargins.top() + st::emojiColorsPadding);
|
||||||
if (variant == _selected) {
|
if (variant == _selected) {
|
||||||
QPoint tl(w);
|
QPoint tl(w);
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::emojiPanSize.width());
|
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||||
App::roundRect(p, QRect(tl, st::emojiPanSize), st::emojiPanHover, StickerHoverCorners);
|
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||||
}
|
}
|
||||||
auto esize = Ui::Emoji::Size(Ui::Emoji::Index() + 1);
|
auto esize = Ui::Emoji::Size(Ui::Emoji::Index() + 1);
|
||||||
p.drawPixmapLeft(w.x() + (st::emojiPanSize.width() - (esize / cIntRetinaFactor())) / 2, w.y() + (st::emojiPanSize.height() - (esize / cIntRetinaFactor())) / 2, width(), App::emojiLarge(), QRect(_variants[variant]->x() * esize, _variants[variant]->y() * esize, esize, esize));
|
p.drawPixmapLeft(w.x() + (_singleSize.width() - (esize / cIntRetinaFactor())) / 2, w.y() + (_singleSize.height() - (esize / cIntRetinaFactor())) / 2, width(), App::emojiLarge(), QRect(_variants[variant]->x() * esize, _variants[variant]->y() * esize, esize, esize));
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
EmojiListWidget::EmojiListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
||||||
, _picker(this) {
|
, _picker(this) {
|
||||||
updateSize();
|
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
|
@ -347,7 +382,7 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
||||||
info.count = _counts[i];
|
info.count = _counts[i];
|
||||||
info.rowsCount = (info.count / kEmojiPanelPerRow) + ((info.count % kEmojiPanelPerRow) ? 1 : 0);
|
info.rowsCount = (info.count / kEmojiPanelPerRow) + ((info.count % kEmojiPanelPerRow) ? 1 : 0);
|
||||||
info.rowsTop = info.top + (i == 0 ? st::emojiPanPadding : st::emojiPanHeader);
|
info.rowsTop = info.top + (i == 0 ? st::emojiPanPadding : st::emojiPanHeader);
|
||||||
info.rowsBottom = info.rowsTop + info.rowsCount * st::emojiPanSize.height();
|
info.rowsBottom = info.rowsTop + info.rowsCount * _singleSize.height();
|
||||||
if (!callback(info)) {
|
if (!callback(info)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +416,14 @@ EmojiListWidget::SectionInfo EmojiListWidget::sectionInfoByOffset(int yOffset) c
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmojiListWidget::countDesiredHeight() {
|
int EmojiListWidget::countDesiredHeight(int newWidth) {
|
||||||
|
auto fullWidth = (st::buttonRadius + newWidth + st::emojiScroll.width);
|
||||||
|
_rowsLeft = fullWidth / (kEmojiPanelPerRow * 4 + 2);
|
||||||
|
auto rowsRight = std::max(_rowsLeft, st::emojiScroll.width);
|
||||||
|
auto singleWidth = (fullWidth - _rowsLeft - rowsRight)
|
||||||
|
/ kEmojiPanelPerRow;
|
||||||
|
_singleSize = QSize(singleWidth, singleWidth - 4 * st::lineWidth);
|
||||||
|
_picker->setSingleSize(_singleSize);
|
||||||
return sectionInfo(kEmojiSectionCount - 1).rowsBottom + st::emojiPanPadding;
|
return sectionInfo(kEmojiSectionCount - 1).rowsBottom + st::emojiPanPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +455,8 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
p.fillRect(r, st::emojiPanBg);
|
p.fillRect(r, st::emojiPanBg);
|
||||||
|
|
||||||
auto fromColumn = floorclamp(r.x() - st::emojiPanPadding, st::emojiPanSize.width(), 0, kEmojiPanelPerRow);
|
auto fromColumn = floorclamp(r.x() - _rowsLeft, _singleSize.width(), 0, kEmojiPanelPerRow);
|
||||||
auto toColumn = ceilclamp(r.x() + r.width() - st::emojiPanPadding, st::emojiPanSize.width(), 0, kEmojiPanelPerRow);
|
auto toColumn = ceilclamp(r.x() + r.width() - _rowsLeft, _singleSize.width(), 0, kEmojiPanelPerRow);
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
qSwap(fromColumn, toColumn);
|
qSwap(fromColumn, toColumn);
|
||||||
fromColumn = kEmojiPanelPerRow - fromColumn;
|
fromColumn = kEmojiPanelPerRow - fromColumn;
|
||||||
|
@ -434,8 +476,8 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
if (r.top() + r.height() > info.rowsTop) {
|
if (r.top() + r.height() > info.rowsTop) {
|
||||||
ensureLoaded(info.section);
|
ensureLoaded(info.section);
|
||||||
auto fromRow = floorclamp(r.y() - info.rowsTop, st::emojiPanSize.height(), 0, info.rowsCount);
|
auto fromRow = floorclamp(r.y() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
||||||
auto toRow = ceilclamp(r.y() + r.height() - info.rowsTop, st::emojiPanSize.height(), 0, info.rowsCount);
|
auto toRow = ceilclamp(r.y() + r.height() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
||||||
for (auto i = fromRow; i < toRow; ++i) {
|
for (auto i = fromRow; i < toRow; ++i) {
|
||||||
for (auto j = fromColumn; j < toColumn; ++j) {
|
for (auto j = fromColumn; j < toColumn; ++j) {
|
||||||
auto index = i * kEmojiPanelPerRow + j;
|
auto index = i * kEmojiPanelPerRow + j;
|
||||||
|
@ -443,15 +485,15 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
auto selected = (!_picker->isHidden() && info.section * MatrixRowShift + index == _pickerSel) || (info.section * MatrixRowShift + index == _selected);
|
auto selected = (!_picker->isHidden() && info.section * MatrixRowShift + index == _pickerSel) || (info.section * MatrixRowShift + index == _selected);
|
||||||
|
|
||||||
auto w = QPoint(st::emojiPanPadding + j * st::emojiPanSize.width(), info.rowsTop + i * st::emojiPanSize.height());
|
auto w = QPoint(_rowsLeft + j * _singleSize.width(), info.rowsTop + i * _singleSize.height());
|
||||||
if (selected) {
|
if (selected) {
|
||||||
auto tl = w;
|
auto tl = w;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::emojiPanSize.width());
|
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||||
App::roundRect(p, QRect(tl, st::emojiPanSize), st::emojiPanHover, StickerHoverCorners);
|
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||||
}
|
}
|
||||||
auto sourceRect = QRect(_emoji[info.section][index]->x() * _esize, _emoji[info.section][index]->y() * _esize, _esize, _esize);
|
auto sourceRect = QRect(_emoji[info.section][index]->x() * _esize, _emoji[info.section][index]->y() * _esize, _esize, _esize);
|
||||||
auto imageLeft = w.x() + (st::emojiPanSize.width() - (_esize / cIntRetinaFactor())) / 2;
|
auto imageLeft = w.x() + (_singleSize.width() - (_esize / cIntRetinaFactor())) / 2;
|
||||||
auto imageTop = w.y() + (st::emojiPanSize.height() - (_esize / cIntRetinaFactor())) / 2;
|
auto imageTop = w.y() + (_singleSize.height() - (_esize / cIntRetinaFactor())) / 2;
|
||||||
p.drawPixmapLeft(imageLeft, imageTop, width(), App::emojiLarge(), sourceRect);
|
p.drawPixmapLeft(imageLeft, imageTop, width(), App::emojiLarge(), sourceRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,7 +594,7 @@ void EmojiListWidget::onShowPicker() {
|
||||||
auto y = emojiRect(section, sel).y();
|
auto y = emojiRect(section, sel).y();
|
||||||
y -= _picker->height() - st::buttonRadius + getVisibleTop();
|
y -= _picker->height() - st::buttonRadius + getVisibleTop();
|
||||||
if (y < st::emojiPanHeader) {
|
if (y < st::emojiPanHeader) {
|
||||||
y += _picker->height() - st::buttonRadius + st::emojiPanSize.height() - st::buttonRadius;
|
y += _picker->height() - st::buttonRadius + _singleSize.height() - st::buttonRadius;
|
||||||
}
|
}
|
||||||
auto xmax = width() - _picker->width();
|
auto xmax = width() - _picker->width();
|
||||||
auto coef = float64(sel % kEmojiPanelPerRow) / float64(kEmojiPanelPerRow - 1);
|
auto coef = float64(sel % kEmojiPanelPerRow) / float64(kEmojiPanelPerRow - 1);
|
||||||
|
@ -576,9 +618,9 @@ QRect EmojiListWidget::emojiRect(int section, int sel) {
|
||||||
auto info = sectionInfo(section);
|
auto info = sectionInfo(section);
|
||||||
auto countTillItem = (sel - (sel % kEmojiPanelPerRow));
|
auto countTillItem = (sel - (sel % kEmojiPanelPerRow));
|
||||||
auto rowsToSkip = (countTillItem / kEmojiPanelPerRow) + ((countTillItem % kEmojiPanelPerRow) ? 1 : 0);
|
auto rowsToSkip = (countTillItem / kEmojiPanelPerRow) + ((countTillItem % kEmojiPanelPerRow) ? 1 : 0);
|
||||||
auto x = st::emojiPanPadding + ((sel % kEmojiPanelPerRow) * st::emojiPanSize.width());
|
auto x = _rowsLeft + ((sel % kEmojiPanelPerRow) * _singleSize.width());
|
||||||
auto y = info.rowsTop + rowsToSkip * st::emojiPanSize.height();
|
auto y = info.rowsTop + rowsToSkip * _singleSize.height();
|
||||||
return QRect(x, y, st::emojiPanSize.width(), st::emojiPanSize.height());
|
return QRect(x, y, _singleSize.width(), _singleSize.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::onColorSelected(EmojiPtr emoji) {
|
void EmojiListWidget::onColorSelected(EmojiPtr emoji) {
|
||||||
|
@ -648,7 +690,7 @@ void EmojiListWidget::refreshRecent() {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
_emoji[0] = Ui::Emoji::GetSection(Section::Recent);
|
_emoji[0] = Ui::Emoji::GetSection(Section::Recent);
|
||||||
_counts[0] = _emoji[0].size();
|
_counts[0] = _emoji[0].size();
|
||||||
updateSize();
|
resizeToWidth(width());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmojiListWidget::eventHook(QEvent *e) {
|
bool EmojiListWidget::eventHook(QEvent *e) {
|
||||||
|
@ -668,9 +710,9 @@ void EmojiListWidget::updateSelected() {
|
||||||
auto p = mapFromGlobal(_lastMousePos);
|
auto p = mapFromGlobal(_lastMousePos);
|
||||||
auto info = sectionInfoByOffset(p.y());
|
auto info = sectionInfoByOffset(p.y());
|
||||||
if (p.y() >= info.rowsTop && p.y() < info.rowsBottom) {
|
if (p.y() >= info.rowsTop && p.y() < info.rowsBottom) {
|
||||||
auto sx = (rtl() ? width() - p.x() : p.x()) - st::emojiPanPadding;
|
auto sx = (rtl() ? width() - p.x() : p.x()) - _rowsLeft;
|
||||||
if (sx >= 0 && sx < kEmojiPanelPerRow * st::emojiPanSize.width()) {
|
if (sx >= 0 && sx < kEmojiPanelPerRow * _singleSize.width()) {
|
||||||
newSelected = qFloor((p.y() - info.rowsTop) / st::emojiPanSize.height()) * kEmojiPanelPerRow + qFloor(sx / st::emojiPanSize.width());
|
newSelected = qFloor((p.y() - info.rowsTop) / _singleSize.height()) * kEmojiPanelPerRow + qFloor(sx / _singleSize.width());
|
||||||
if (newSelected >= _emoji[info.section].size()) {
|
if (newSelected >= _emoji[info.section].size()) {
|
||||||
newSelected = -1;
|
newSelected = -1;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
void handleMouseMove(QPoint globalPos);
|
void handleMouseMove(QPoint globalPos);
|
||||||
void handleMouseRelease(QPoint globalPos);
|
void handleMouseRelease(QPoint globalPos);
|
||||||
|
void setSingleSize(QSize size);
|
||||||
|
|
||||||
void hideFast();
|
void hideFast();
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void animationCallback();
|
void animationCallback();
|
||||||
|
void updateSize();
|
||||||
|
|
||||||
void drawVariant(Painter &p, int variant);
|
void drawVariant(Painter &p, int variant);
|
||||||
|
|
||||||
|
@ -75,6 +77,7 @@ private:
|
||||||
int _selected = -1;
|
int _selected = -1;
|
||||||
int _pressedSel = -1;
|
int _pressedSel = -1;
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
|
QSize _singleSize;
|
||||||
|
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
|
@ -126,7 +129,7 @@ protected:
|
||||||
|
|
||||||
TabbedSelector::InnerFooter *getFooter() const override;
|
TabbedSelector::InnerFooter *getFooter() const override;
|
||||||
void processHideFinished() override;
|
void processHideFinished() override;
|
||||||
int countDesiredHeight() override;
|
int countDesiredHeight(int newWidth) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Footer;
|
class Footer;
|
||||||
|
@ -159,7 +162,9 @@ private:
|
||||||
int _counts[kEmojiSectionCount];
|
int _counts[kEmojiSectionCount];
|
||||||
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
|
QVector<EmojiPtr> _emoji[kEmojiSectionCount];
|
||||||
|
|
||||||
int32 _esize;
|
int _rowsLeft = 0;
|
||||||
|
QSize _singleSize;
|
||||||
|
int _esize = 0;
|
||||||
|
|
||||||
int _selected = -1;
|
int _selected = -1;
|
||||||
int _pressedSel = -1;
|
int _pressedSel = -1;
|
||||||
|
|
|
@ -39,7 +39,6 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kSaveChosenTabTimeout = 1000;
|
constexpr auto kSaveChosenTabTimeout = 1000;
|
||||||
constexpr auto kSearchRequestDelay = 400;
|
constexpr auto kSearchRequestDelay = 400;
|
||||||
constexpr auto kStickersPanelPerRow = Stickers::kPanelPerRow;
|
|
||||||
constexpr auto kInlineItemsMaxPerRow = 5;
|
constexpr auto kInlineItemsMaxPerRow = 5;
|
||||||
constexpr auto kSearchBotUsername = str_const("gif");
|
constexpr auto kSearchBotUsername = str_const("gif");
|
||||||
|
|
||||||
|
@ -57,6 +56,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
void processPanelHideFinished() override;
|
void processPanelHideFinished() override;
|
||||||
|
|
||||||
|
@ -74,8 +74,6 @@ GifsListWidget::Footer::Footer(not_null<GifsListWidget*> parent) : InnerFooter(p
|
||||||
, _pan(parent)
|
, _pan(parent)
|
||||||
, _field(this, st::gifsSearchField, langFactory(lng_gifs_search))
|
, _field(this, st::gifsSearchField, langFactory(lng_gifs_search))
|
||||||
, _cancel(this, st::gifsSearchCancel) {
|
, _cancel(this, st::gifsSearchCancel) {
|
||||||
_field->resize(width() - st::gifsSearchFieldPosition.x() - st::gifsSearchCancelPosition.x() - st::gifsSearchCancel.width, _field->height());
|
|
||||||
_field->moveToLeft(st::gifsSearchFieldPosition.x(), st::gifsSearchFieldPosition.y());
|
|
||||||
connect(_field, &Ui::InputField::submitted, this, [this](bool ctrlShiftEnter) {
|
connect(_field, &Ui::InputField::submitted, this, [this](bool ctrlShiftEnter) {
|
||||||
_pan->sendInlineRequest();
|
_pan->sendInlineRequest();
|
||||||
});
|
});
|
||||||
|
@ -90,7 +88,6 @@ GifsListWidget::Footer::Footer(not_null<GifsListWidget*> parent) : InnerFooter(p
|
||||||
_cancel->toggleAnimated(!_field->getLastText().isEmpty());
|
_cancel->toggleAnimated(!_field->getLastText().isEmpty());
|
||||||
_pan->searchForGifs(_field->getLastText());
|
_pan->searchForGifs(_field->getLastText());
|
||||||
});
|
});
|
||||||
_cancel->moveToRight(st::gifsSearchCancelPosition.x(), st::gifsSearchCancelPosition.y());
|
|
||||||
_cancel->setClickedCallback([this] {
|
_cancel->setClickedCallback([this] {
|
||||||
_field->setText(QString());
|
_field->setText(QString());
|
||||||
});
|
});
|
||||||
|
@ -117,6 +114,16 @@ void GifsListWidget::Footer::paintEvent(QPaintEvent *e) {
|
||||||
st::gifsSearchIcon.paint(p, st::gifsSearchIconPosition.x(), st::gifsSearchIconPosition.y(), width());
|
st::gifsSearchIcon.paint(p, st::gifsSearchIconPosition.x(), st::gifsSearchIconPosition.y(), width());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GifsListWidget::Footer::resizeEvent(QResizeEvent *e) {
|
||||||
|
auto fieldWidth = width()
|
||||||
|
- st::gifsSearchFieldPosition.x()
|
||||||
|
- st::gifsSearchCancelPosition.x()
|
||||||
|
- st::gifsSearchCancel.width;
|
||||||
|
_field->resizeToWidth(fieldWidth);
|
||||||
|
_field->moveToLeft(st::gifsSearchFieldPosition.x(), st::gifsSearchFieldPosition.y());
|
||||||
|
_cancel->moveToRight(st::gifsSearchCancelPosition.x(), st::gifsSearchCancelPosition.y());
|
||||||
|
}
|
||||||
|
|
||||||
void GifsListWidget::Footer::processPanelHideFinished() {
|
void GifsListWidget::Footer::processPanelHideFinished() {
|
||||||
// Preserve panel state through visibility toggles.
|
// Preserve panel state through visibility toggles.
|
||||||
//_field->setText(QString());
|
//_field->setText(QString());
|
||||||
|
@ -127,8 +134,6 @@ GifsListWidget::GifsListWidget(
|
||||||
not_null<Window::Controller*> controller)
|
not_null<Window::Controller*> controller)
|
||||||
: Inner(parent, controller)
|
: Inner(parent, controller)
|
||||||
, _section(Section::Gifs) {
|
, _section(Section::Gifs) {
|
||||||
updateSize();
|
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
|
@ -180,9 +185,10 @@ void GifsListWidget::checkLoadMore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int GifsListWidget::countDesiredHeight() {
|
int GifsListWidget::countDesiredHeight(int newWidth) {
|
||||||
auto result = st::stickerPanPadding;
|
auto result = st::stickerPanPadding;
|
||||||
for (int i = 0, l = _rows.count(); i < l; ++i) {
|
for (int i = 0, l = _rows.count(); i < l; ++i) {
|
||||||
|
layoutInlineRow(_rows[i], newWidth);
|
||||||
result += _rows[i].height;
|
result += _rows[i].height;
|
||||||
}
|
}
|
||||||
return result + st::stickerPanPadding;
|
return result + st::stickerPanPadding;
|
||||||
|
@ -448,9 +454,16 @@ bool GifsListWidget::inlineRowFinalize(Row &row, int32 &sumWidth, bool force) {
|
||||||
if (row.items.isEmpty()) return false;
|
if (row.items.isEmpty()) return false;
|
||||||
|
|
||||||
auto full = (row.items.size() >= kInlineItemsMaxPerRow);
|
auto full = (row.items.size() >= kInlineItemsMaxPerRow);
|
||||||
auto big = (sumWidth >= st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft);
|
|
||||||
|
// Currently use the same GIFs layout for all widget sizes.
|
||||||
|
// auto big = (sumWidth >= st::buttonRadius + width() - st::inlineResultsLeft);
|
||||||
|
auto big = (sumWidth >= st::emojiPanWidth - st::inlineResultsLeft);
|
||||||
if (full || big || force) {
|
if (full || big || force) {
|
||||||
_rows.push_back(layoutInlineRow(row, (full || big) ? sumWidth : 0));
|
row.maxWidth = (full || big) ? sumWidth : 0;
|
||||||
|
layoutInlineRow(
|
||||||
|
row,
|
||||||
|
width());
|
||||||
|
_rows.push_back(row);
|
||||||
row = Row();
|
row = Row();
|
||||||
row.items.reserve(kInlineItemsMaxPerRow);
|
row.items.reserve(kInlineItemsMaxPerRow);
|
||||||
sumWidth = 0;
|
sumWidth = 0;
|
||||||
|
@ -476,7 +489,7 @@ void GifsListWidget::refreshSavedGifs() {
|
||||||
}
|
}
|
||||||
deleteUnusedGifLayouts();
|
deleteUnusedGifLayouts();
|
||||||
|
|
||||||
updateSize();
|
resizeToWidth(width());
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,7 +574,7 @@ void GifsListWidget::deleteUnusedInlineLayouts() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GifsListWidget::Row &GifsListWidget::layoutInlineRow(Row &row, int32 sumWidth) {
|
void GifsListWidget::layoutInlineRow(Row &row, int fullWidth) {
|
||||||
auto count = int(row.items.size());
|
auto count = int(row.items.size());
|
||||||
Assert(count <= kInlineItemsMaxPerRow);
|
Assert(count <= kInlineItemsMaxPerRow);
|
||||||
|
|
||||||
|
@ -571,27 +584,30 @@ GifsListWidget::Row &GifsListWidget::layoutInlineRow(Row &row, int32 sumWidth) {
|
||||||
for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
indices[i] = i;
|
indices[i] = i;
|
||||||
}
|
}
|
||||||
std::sort(indices, indices + count, [&row](int a, int b) -> bool {
|
std::sort(indices, indices + count, [&](int a, int b) {
|
||||||
return row.items.at(a)->maxWidth() < row.items.at(b)->maxWidth();
|
return row.items[a]->maxWidth()
|
||||||
|
< row.items[b]->maxWidth();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto desiredWidth = row.maxWidth;
|
||||||
row.height = 0;
|
row.height = 0;
|
||||||
int availw = width() - (st::inlineResultsLeft - st::buttonRadius);
|
int availw = fullWidth - (st::inlineResultsLeft - st::buttonRadius);
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
int index = indices[i];
|
int index = indices[i];
|
||||||
int w = sumWidth ? (row.items.at(index)->maxWidth() * availw / sumWidth) : row.items.at(index)->maxWidth();
|
int w = desiredWidth
|
||||||
|
? (row.items[index]->maxWidth() * availw / desiredWidth)
|
||||||
|
: row.items[index]->maxWidth();
|
||||||
int actualw = qMax(w, int(st::inlineResultsMinWidth));
|
int actualw = qMax(w, int(st::inlineResultsMinWidth));
|
||||||
row.height = qMax(row.height, row.items[index]->resizeGetHeight(actualw));
|
row.height = qMax(row.height, row.items[index]->resizeGetHeight(actualw));
|
||||||
if (sumWidth) {
|
if (desiredWidth) {
|
||||||
availw -= actualw;
|
availw -= actualw;
|
||||||
sumWidth -= row.items.at(index)->maxWidth();
|
desiredWidth -= row.items[index]->maxWidth();
|
||||||
if (index > 0 && row.items.at(index - 1)->hasRightSkip()) {
|
if (index > 0 && row.items[index - 1]->hasRightSkip()) {
|
||||||
availw -= st::inlineResultsSkip;
|
availw -= st::inlineResultsSkip;
|
||||||
sumWidth -= st::inlineResultsSkip;
|
desiredWidth -= st::inlineResultsSkip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return row;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GifsListWidget::preloadImages() {
|
void GifsListWidget::preloadImages() {
|
||||||
|
@ -639,7 +655,7 @@ int GifsListWidget::refreshInlineRows(const InlineCacheEntry *entry, bool result
|
||||||
inlineRowFinalize(row, sumWidth, true);
|
inlineRowFinalize(row, sumWidth, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize();
|
resizeToWidth(width());
|
||||||
update();
|
update();
|
||||||
|
|
||||||
_lastMousePos = QCursor::pos();
|
_lastMousePos = QCursor::pos();
|
||||||
|
@ -680,7 +696,12 @@ int GifsListWidget::validateExistingInlineRows(const InlineResults &results) {
|
||||||
}
|
}
|
||||||
_rows.resize(untilrow + 1);
|
_rows.resize(untilrow + 1);
|
||||||
_rows[untilrow].items.resize(untilcol);
|
_rows[untilrow].items.resize(untilcol);
|
||||||
_rows[untilrow] = layoutInlineRow(_rows[untilrow]);
|
_rows[untilrow].maxWidth = std::accumulate(
|
||||||
|
_rows[untilrow].items.begin(),
|
||||||
|
_rows[untilrow].items.end(),
|
||||||
|
0,
|
||||||
|
[](int w, auto &row) { return w + row->maxWidth(); });
|
||||||
|
layoutInlineRow(_rows[untilrow], width());
|
||||||
return until;
|
return until;
|
||||||
}
|
}
|
||||||
if (untilrow && !untilcol) { // remove last row, maybe it is not full
|
if (untilrow && !untilcol) { // remove last row, maybe it is not full
|
||||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
||||||
TabbedSelector::InnerFooter *getFooter() const override;
|
TabbedSelector::InnerFooter *getFooter() const override;
|
||||||
void processHideFinished() override;
|
void processHideFinished() override;
|
||||||
void processPanelHideFinished() override;
|
void processPanelHideFinished() override;
|
||||||
int countDesiredHeight() override;
|
int countDesiredHeight(int newWidth) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onPreview();
|
void onPreview();
|
||||||
|
@ -136,6 +136,7 @@ private:
|
||||||
bool _inlineWithThumb = false;
|
bool _inlineWithThumb = false;
|
||||||
|
|
||||||
struct Row {
|
struct Row {
|
||||||
|
int maxWidth = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
QVector<LayoutItem*> items;
|
QVector<LayoutItem*> items;
|
||||||
};
|
};
|
||||||
|
@ -151,7 +152,7 @@ private:
|
||||||
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32 &sumWidth);
|
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, Row &row, int32 &sumWidth);
|
||||||
bool inlineRowFinalize(Row &row, int32 &sumWidth, bool force = false);
|
bool inlineRowFinalize(Row &row, int32 &sumWidth, bool force = false);
|
||||||
|
|
||||||
Row &layoutInlineRow(Row &row, int32 sumWidth = 0);
|
void layoutInlineRow(Row &row, int fullWidth);
|
||||||
void deleteUnusedGifLayouts();
|
void deleteUnusedGifLayouts();
|
||||||
|
|
||||||
void deleteUnusedInlineLayouts();
|
void deleteUnusedInlineLayouts();
|
||||||
|
|
|
@ -21,7 +21,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "chat_helpers/stickers_list_widget.h"
|
#include "chat_helpers/stickers_list_widget.h"
|
||||||
|
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
|
@ -37,11 +36,12 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "styles/style_chat_helpers.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kStickersPanelPerRow = Stickers::kPanelPerRow;
|
|
||||||
constexpr auto kInlineItemsMaxPerRow = 5;
|
constexpr auto kInlineItemsMaxPerRow = 5;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -101,6 +101,7 @@ private:
|
||||||
BasicAnimation _a_icons;
|
BasicAnimation _a_icons;
|
||||||
QPoint _iconsMousePos, _iconsMouseDown;
|
QPoint _iconsMousePos, _iconsMouseDown;
|
||||||
int _iconsLeft = 0;
|
int _iconsLeft = 0;
|
||||||
|
int _iconsRight = 0;
|
||||||
int _iconsTop = 0;
|
int _iconsTop = 0;
|
||||||
int _iconsStartX = 0;
|
int _iconsStartX = 0;
|
||||||
int _iconsMax = 0;
|
int _iconsMax = 0;
|
||||||
|
@ -117,7 +118,7 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent) : Inner
|
||||||
, _a_icons(animation(this, &Footer::step_icons)) {
|
, _a_icons(animation(this, &Footer::step_icons)) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
_iconsLeft = (st::emojiPanWidth - kVisibleIconsCount * st::emojiCategory.width) / 2;
|
_iconsLeft = _iconsRight = st::emojiCategorySkip;
|
||||||
|
|
||||||
subscribe(Auth().downloaderTaskFinished(), [this] {
|
subscribe(Auth().downloaderTaskFinished(), [this] {
|
||||||
update();
|
update();
|
||||||
|
@ -127,12 +128,13 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent) : Inner
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void StickersListWidget::Footer::enumerateVisibleIcons(Callback callback) {
|
void StickersListWidget::Footer::enumerateVisibleIcons(Callback callback) {
|
||||||
auto iconsX = qRound(_iconsX.current());
|
auto iconsX = qRound(_iconsX.current());
|
||||||
auto index = iconsX / st::emojiCategory.width;
|
auto index = iconsX / st::stickerIconWidth;
|
||||||
auto x = _iconsLeft - (iconsX % st::emojiCategory.width);
|
auto x = _iconsLeft - (iconsX % st::stickerIconWidth);
|
||||||
for (auto index = qMin(_icons.size(), iconsX / st::emojiCategory.width),
|
auto first = floorclamp(iconsX, st::stickerIconWidth, 0, _icons.size());
|
||||||
last = qMin(_icons.size(), index + kVisibleIconsCount); index != last; ++index) {
|
auto last = ceilclamp(iconsX + width(), st::stickerIconWidth, 0, _icons.size());
|
||||||
|
for (auto index = first; index != last; ++index) {
|
||||||
callback(_icons[index], x);
|
callback(_icons[index], x);
|
||||||
x += st::emojiCategory.width;
|
x += st::stickerIconWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +146,9 @@ void StickersListWidget::Footer::preloadImages() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::Footer::validateSelectedIcon(uint64 setId, ValidateIconAnimations animations) {
|
void StickersListWidget::Footer::validateSelectedIcon(
|
||||||
|
uint64 setId,
|
||||||
|
ValidateIconAnimations animations) {
|
||||||
auto newSel = 0;
|
auto newSel = 0;
|
||||||
for (auto i = 0, l = _icons.size(); i != l; ++i) {
|
for (auto i = 0, l = _icons.size(); i != l; ++i) {
|
||||||
if (_icons[i].setId == setId) {
|
if (_icons[i].setId == setId) {
|
||||||
|
@ -154,13 +158,19 @@ void StickersListWidget::Footer::validateSelectedIcon(uint64 setId, ValidateIcon
|
||||||
}
|
}
|
||||||
if (newSel != _iconSel) {
|
if (newSel != _iconSel) {
|
||||||
_iconSel = newSel;
|
_iconSel = newSel;
|
||||||
auto iconSelXFinal = _iconSel * st::emojiCategory.width;
|
auto iconSelXFinal = _iconSel * st::stickerIconWidth;
|
||||||
if (animations == ValidateIconAnimations::Full) {
|
if (animations == ValidateIconAnimations::Full) {
|
||||||
_iconSelX.start(iconSelXFinal);
|
_iconSelX.start(iconSelXFinal);
|
||||||
} else {
|
} else {
|
||||||
_iconSelX = anim::value(iconSelXFinal, iconSelXFinal);
|
_iconSelX = anim::value(iconSelXFinal, iconSelXFinal);
|
||||||
}
|
}
|
||||||
auto iconsXFinal = snap((2 * _iconSel + 1 - kVisibleIconsCount) * st::emojiCategory.width / 2, 0, _iconsMax);
|
auto iconsCountForCentering = (2 * _iconSel + 1);
|
||||||
|
auto iconsWidthForCentering = iconsCountForCentering
|
||||||
|
* st::stickerIconWidth;
|
||||||
|
auto iconsXFinal = snap(
|
||||||
|
(iconsWidthForCentering - width()) / 2,
|
||||||
|
0,
|
||||||
|
_iconsMax);
|
||||||
if (animations == ValidateIconAnimations::None) {
|
if (animations == ValidateIconAnimations::None) {
|
||||||
_iconsX = anim::value(iconsXFinal, iconsXFinal);
|
_iconsX = anim::value(iconsXFinal, iconsXFinal);
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
|
@ -202,7 +212,11 @@ void StickersListWidget::Footer::paintEvent(QPaintEvent *e) {
|
||||||
auto selxrel = _iconsLeft + qRound(_iconSelX.current());
|
auto selxrel = _iconsLeft + qRound(_iconSelX.current());
|
||||||
auto selx = selxrel - qRound(_iconsX.current());
|
auto selx = selxrel - qRound(_iconsX.current());
|
||||||
|
|
||||||
auto clip = QRect(_iconsLeft, _iconsTop, _iconsLeft + (kVisibleIconsCount - 1) * st::emojiCategory.width - _iconsLeft, st::emojiCategory.height);
|
auto clip = QRect(
|
||||||
|
_iconsLeft,
|
||||||
|
_iconsTop,
|
||||||
|
width() - _iconsLeft - _iconsRight - st::stickerIconWidth,
|
||||||
|
st::emojiFooterHeight);
|
||||||
if (rtl()) clip.moveLeft(width() - _iconsLeft - clip.width());
|
if (rtl()) clip.moveLeft(width() - _iconsLeft - clip.width());
|
||||||
p.setClipRect(clip);
|
p.setClipRect(clip);
|
||||||
|
|
||||||
|
@ -211,9 +225,9 @@ void StickersListWidget::Footer::paintEvent(QPaintEvent *e) {
|
||||||
icon.sticker->thumb->load();
|
icon.sticker->thumb->load();
|
||||||
auto pix = icon.sticker->thumb->pix(icon.pixw, icon.pixh);
|
auto pix = icon.sticker->thumb->pix(icon.pixw, icon.pixh);
|
||||||
|
|
||||||
p.drawPixmapLeft(x + (st::emojiCategory.width - icon.pixw) / 2, _iconsTop + (st::emojiCategory.height - icon.pixh) / 2, width(), pix);
|
p.drawPixmapLeft(x + (st::stickerIconWidth - icon.pixw) / 2, _iconsTop + (st::emojiFooterHeight - icon.pixh) / 2, width(), pix);
|
||||||
} else if (icon.megagroup) {
|
} else if (icon.megagroup) {
|
||||||
icon.megagroup->paintUserpicLeft(p, x + (st::emojiCategory.width - st::stickerGroupCategorySize) / 2, _iconsTop + (st::emojiCategory.height - st::stickerGroupCategorySize) / 2, width(), st::stickerGroupCategorySize);
|
icon.megagroup->paintUserpicLeft(p, x + (st::stickerIconWidth - st::stickerGroupCategorySize) / 2, _iconsTop + (st::emojiFooterHeight - st::stickerGroupCategorySize) / 2, width(), st::stickerGroupCategorySize);
|
||||||
} else {
|
} else {
|
||||||
auto getSpecialSetIcon = [](uint64 setId) {
|
auto getSpecialSetIcon = [](uint64 setId) {
|
||||||
if (setId == Stickers::FeaturedSetId) {
|
if (setId == Stickers::FeaturedSetId) {
|
||||||
|
@ -223,26 +237,27 @@ void StickersListWidget::Footer::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
return &st::emojiRecent;
|
return &st::emojiRecent;
|
||||||
};
|
};
|
||||||
getSpecialSetIcon(icon.setId)->paint(p, x + st::emojiCategory.iconPosition.x(), _iconsTop + st::emojiCategory.iconPosition.y(), width());
|
auto paintedIcon = getSpecialSetIcon(icon.setId);
|
||||||
|
paintedIcon->paint(p, x + (st::stickerIconWidth - paintedIcon->width()) / 2, _iconsTop + st::emojiCategory.iconPosition.y(), width());
|
||||||
if (icon.setId == Stickers::FeaturedSetId) {
|
if (icon.setId == Stickers::FeaturedSetId) {
|
||||||
paintFeaturedStickerSetsBadge(p, x);
|
paintFeaturedStickerSetsBadge(p, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (rtl()) selx = width() - selx - st::emojiCategory.width;
|
if (rtl()) selx = width() - selx - st::stickerIconWidth;
|
||||||
p.fillRect(selx, _iconsTop + st::emojiCategory.height - st::stickerIconPadding, st::emojiCategory.width, st::stickerIconSel, st::stickerIconSelColor);
|
p.fillRect(selx, _iconsTop + st::emojiFooterHeight - st::stickerIconPadding, st::stickerIconWidth, st::stickerIconSel, st::stickerIconSelColor);
|
||||||
|
|
||||||
auto o_left = snap(_iconsX.current() / st::stickerIconLeft.width(), 0., 1.);
|
auto o_left = snap(_iconsX.current() / st::stickerIconLeft.width(), 0., 1.);
|
||||||
if (o_left > 0) {
|
if (o_left > 0) {
|
||||||
p.setOpacity(o_left);
|
p.setOpacity(o_left);
|
||||||
st::stickerIconLeft.fill(p, rtlrect(_iconsLeft, _iconsTop, st::stickerIconLeft.width(), st::emojiCategory.height, width()));
|
st::stickerIconLeft.fill(p, rtlrect(_iconsLeft, _iconsTop, st::stickerIconLeft.width(), st::emojiFooterHeight, width()));
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
auto o_right = snap((_iconsMax - _iconsX.current()) / st::stickerIconRight.width(), 0., 1.);
|
auto o_right = snap((_iconsMax - _iconsX.current()) / st::stickerIconRight.width(), 0., 1.);
|
||||||
if (o_right > 0) {
|
if (o_right > 0) {
|
||||||
p.setOpacity(o_right);
|
p.setOpacity(o_right);
|
||||||
st::stickerIconRight.fill(p, rtlrect(_iconsLeft + (kVisibleIconsCount - 1) * st::emojiCategory.width - st::stickerIconRight.width(), _iconsTop, st::stickerIconRight.width(), st::emojiCategory.height, width()));
|
st::stickerIconRight.fill(p, rtlrect(width() - _iconsRight - st::stickerIconWidth - st::stickerIconRight.width(), _iconsTop, st::stickerIconRight.width(), st::emojiFooterHeight, width()));
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -306,7 +321,7 @@ void StickersListWidget::Footer::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (wasDown == _iconOver && _iconOver >= 0 && _iconOver < _icons.size()) {
|
if (wasDown == _iconOver && _iconOver >= 0 && _iconOver < _icons.size()) {
|
||||||
_iconSelX = anim::value(_iconOver * st::emojiCategory.width, _iconOver * st::emojiCategory.width);
|
_iconSelX = anim::value(_iconOver * st::stickerIconWidth, _iconOver * st::stickerIconWidth);
|
||||||
_pan->showStickerSet(_icons[_iconOver].setId);
|
_pan->showStickerSet(_icons[_iconOver].setId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,17 +360,26 @@ void StickersListWidget::Footer::updateSelected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = mapFromGlobal(_iconsMousePos);
|
auto p = mapFromGlobal(_iconsMousePos);
|
||||||
int32 x = p.x(), y = p.y(), newOver = -1;
|
auto x = p.x(), y = p.y(), newOver = -1;
|
||||||
if (rtl()) x = width() - x;
|
if (rtl()) x = width() - x;
|
||||||
|
auto settingsLeft = width() - _iconsRight - st::stickerIconWidth;
|
||||||
x -= _iconsLeft;
|
x -= _iconsLeft;
|
||||||
if (x >= st::emojiCategory.width * (kVisibleIconsCount - 1) && x < st::emojiCategory.width * kVisibleIconsCount && y >= _iconsTop && y < _iconsTop + st::emojiCategory.height) {
|
settingsLeft -= _iconsLeft;
|
||||||
|
if (x >= settingsLeft
|
||||||
|
&& x < settingsLeft + st::stickerIconWidth
|
||||||
|
&& y >= _iconsTop
|
||||||
|
&& y < _iconsTop + st::emojiFooterHeight) {
|
||||||
if (!_icons.isEmpty() && !hasOnlyFeaturedSets()) {
|
if (!_icons.isEmpty() && !hasOnlyFeaturedSets()) {
|
||||||
newOver = _icons.size();
|
newOver = _icons.size();
|
||||||
}
|
}
|
||||||
} else if (!_icons.isEmpty()) {
|
} else if (!_icons.isEmpty()) {
|
||||||
if (y >= _iconsTop && y < _iconsTop + st::emojiCategory.height && x >= 0 && x < (kVisibleIconsCount - 1) * st::emojiCategory.width && x < _icons.size() * st::emojiCategory.width) {
|
if (y >= _iconsTop
|
||||||
|
&& y < _iconsTop + st::emojiFooterHeight
|
||||||
|
&& x >= 0
|
||||||
|
&& x < settingsLeft
|
||||||
|
&& x < _icons.size() * st::stickerIconWidth) {
|
||||||
x += qRound(_iconsX.current());
|
x += qRound(_iconsX.current());
|
||||||
newOver = qFloor(x / st::emojiCategory.width);
|
newOver = qFloor(x / st::stickerIconWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (newOver != _iconOver) {
|
if (newOver != _iconOver) {
|
||||||
|
@ -368,18 +392,17 @@ void StickersListWidget::Footer::updateSelected() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::Footer::refreshIcons(ValidateIconAnimations animations) {
|
void StickersListWidget::Footer::refreshIcons(
|
||||||
|
ValidateIconAnimations animations) {
|
||||||
_iconOver = -1;
|
_iconOver = -1;
|
||||||
_pan->fillIcons(_icons);
|
_pan->fillIcons(_icons);
|
||||||
_iconsX.finish();
|
_iconsX.finish();
|
||||||
_iconSelX.finish();
|
_iconSelX.finish();
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
if (_icons.isEmpty()) {
|
_iconsMax = std::max(
|
||||||
_iconsMax = 0;
|
int((_icons.size() + 1) * st::stickerIconWidth) - width(),
|
||||||
} else {
|
0);
|
||||||
_iconsMax = qMax(int((_icons.size() + 1 - kVisibleIconsCount) * st::emojiCategory.width), 0);
|
|
||||||
}
|
|
||||||
if (_iconsX.current() > _iconsMax) {
|
if (_iconsX.current() > _iconsMax) {
|
||||||
_iconsX = anim::value(_iconsMax, _iconsMax);
|
_iconsX = anim::value(_iconsMax, _iconsMax);
|
||||||
}
|
}
|
||||||
|
@ -393,8 +416,8 @@ bool StickersListWidget::Footer::hasOnlyFeaturedSets() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::Footer::paintStickerSettingsIcon(Painter &p) const {
|
void StickersListWidget::Footer::paintStickerSettingsIcon(Painter &p) const {
|
||||||
int settingsLeft = _iconsLeft + (kVisibleIconsCount - 1) * st::emojiCategory.width;
|
int settingsLeft = width() - _iconsRight - st::stickerIconWidth;
|
||||||
st::stickersSettings.paint(p, settingsLeft + st::emojiCategory.iconPosition.x(), _iconsTop + st::emojiCategory.iconPosition.y(), width());
|
st::stickersSettings.paint(p, settingsLeft + (st::stickerIconWidth - st::stickersSettings.width()) / 2, _iconsTop + st::emojiCategory.iconPosition.y(), width());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::Footer::paintFeaturedStickerSetsBadge(Painter &p, int iconLeft) const {
|
void StickersListWidget::Footer::paintFeaturedStickerSetsBadge(Painter &p, int iconLeft) const {
|
||||||
|
@ -402,7 +425,7 @@ void StickersListWidget::Footer::paintFeaturedStickerSetsBadge(Painter &p, int i
|
||||||
Dialogs::Layout::UnreadBadgeStyle unreadSt;
|
Dialogs::Layout::UnreadBadgeStyle unreadSt;
|
||||||
unreadSt.sizeId = Dialogs::Layout::UnreadBadgeInStickersPanel;
|
unreadSt.sizeId = Dialogs::Layout::UnreadBadgeInStickersPanel;
|
||||||
unreadSt.size = st::stickersSettingsUnreadSize;
|
unreadSt.size = st::stickersSettingsUnreadSize;
|
||||||
int unreadRight = iconLeft + st::emojiCategory.width - st::stickersSettingsUnreadPosition.x();
|
int unreadRight = iconLeft + st::stickerIconWidth - st::stickersSettingsUnreadPosition.x();
|
||||||
if (rtl()) unreadRight = width() - unreadRight;
|
if (rtl()) unreadRight = width() - unreadRight;
|
||||||
int unreadTop = _iconsTop + st::stickersSettingsUnreadPosition.y();
|
int unreadTop = _iconsTop + st::stickersSettingsUnreadPosition.y();
|
||||||
Dialogs::Layout::paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, unreadSt);
|
Dialogs::Layout::paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, unreadSt);
|
||||||
|
@ -437,12 +460,10 @@ void StickersListWidget::Footer::step_icons(TimeMs ms, bool timer) {
|
||||||
|
|
||||||
StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
StickersListWidget::StickersListWidget(QWidget *parent, not_null<Window::Controller*> controller) : Inner(parent, controller)
|
||||||
, _section(Section::Stickers)
|
, _section(Section::Stickers)
|
||||||
, _megagroupSetAbout(st::emojiPanWidth - st::emojiScroll.width - st::emojiPanHeaderLeft)
|
, _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft)
|
||||||
, _addText(lang(lng_stickers_featured_add).toUpper())
|
, _addText(lang(lng_stickers_featured_add).toUpper())
|
||||||
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
||||||
, _settings(this, lang(lng_stickers_you_have)) {
|
, _settings(this, lang(lng_stickers_you_have)) {
|
||||||
updateSize();
|
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
|
@ -494,7 +515,7 @@ void StickersListWidget::readVisibleSets() {
|
||||||
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) {
|
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int count = qMin(set.pack.size(), static_cast<int>(kStickersPanelPerRow));
|
int count = qMin(set.pack.size(), _columnCount);
|
||||||
int loaded = 0;
|
int loaded = 0;
|
||||||
for (int j = 0; j < count; ++j) {
|
for (int j = 0; j < count; ++j) {
|
||||||
if (set.pack[j]->thumb->loaded() || set.pack[j]->loaded()) {
|
if (set.pack[j]->thumb->loaded() || set.pack[j]->loaded()) {
|
||||||
|
@ -508,7 +529,9 @@ void StickersListWidget::readVisibleSets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickersListWidget::featuredRowHeight() const {
|
int StickersListWidget::featuredRowHeight() const {
|
||||||
return st::stickersTrendingHeader + st::stickerPanSize.height() + st::stickersTrendingSkip;
|
return st::stickersTrendingHeader
|
||||||
|
+ _singleSize.height()
|
||||||
|
+ st::stickersTrendingSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
|
@ -524,8 +547,8 @@ bool StickersListWidget::enumerateSections(Callback callback) const {
|
||||||
info.rowsCount = 0;
|
info.rowsCount = 0;
|
||||||
info.rowsBottom = info.rowsTop + _megagroupSetButtonRect.y() + _megagroupSetButtonRect.height() + st::stickerGroupCategoryAddMargin.bottom();
|
info.rowsBottom = info.rowsTop + _megagroupSetButtonRect.y() + _megagroupSetButtonRect.height() + st::stickerGroupCategoryAddMargin.bottom();
|
||||||
} else {
|
} else {
|
||||||
info.rowsCount = (info.count / kStickersPanelPerRow) + ((info.count % kStickersPanelPerRow) ? 1 : 0);
|
info.rowsCount = (info.count / _columnCount) + ((info.count % _columnCount) ? 1 : 0);
|
||||||
info.rowsBottom = info.rowsTop + info.rowsCount * st::stickerPanSize.height();
|
info.rowsBottom = info.rowsTop + info.rowsCount * _singleSize.height();
|
||||||
}
|
}
|
||||||
if (!callback(info)) {
|
if (!callback(info)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -560,7 +583,21 @@ StickersListWidget::SectionInfo StickersListWidget::sectionInfoByOffset(int yOff
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickersListWidget::countDesiredHeight() {
|
int StickersListWidget::countDesiredHeight(int newWidth) {
|
||||||
|
if (newWidth <= st::stickerPanWidthMin) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto availableWidth = newWidth - (st::stickerPanPadding - st::buttonRadius);
|
||||||
|
_columnCount = availableWidth / st::stickerPanWidthMin;
|
||||||
|
auto singleWidth = availableWidth / _columnCount;
|
||||||
|
auto fullWidth = (st::buttonRadius + newWidth + st::emojiScroll.width);
|
||||||
|
auto rowsRight = (fullWidth - _columnCount * singleWidth) / 2;
|
||||||
|
accumulate_max(rowsRight, st::emojiScroll.width);
|
||||||
|
_rowsLeft = fullWidth
|
||||||
|
- _columnCount * singleWidth
|
||||||
|
- rowsRight
|
||||||
|
- st::buttonRadius;
|
||||||
|
_singleSize = QSize(singleWidth, singleWidth);
|
||||||
auto visibleHeight = minimalHeight();
|
auto visibleHeight = minimalHeight();
|
||||||
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
|
auto minimalLastHeight = (visibleHeight - st::stickerPanPadding);
|
||||||
auto countResult = [this, minimalLastHeight] {
|
auto countResult = [this, minimalLastHeight] {
|
||||||
|
@ -591,25 +628,25 @@ void StickersListWidget::clearInstalledLocally() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickersListWidget::stickersLeft() const {
|
int StickersListWidget::stickersLeft() const {
|
||||||
return (st::stickerPanPadding - st::buttonRadius);
|
return _rowsLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect StickersListWidget::stickerRect(int section, int sel) {
|
QRect StickersListWidget::stickerRect(int section, int sel) {
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
if (_section == Section::Featured) {
|
if (_section == Section::Featured) {
|
||||||
x = stickersLeft() + (sel * st::stickerPanSize.width());
|
x = stickersLeft() + (sel * _singleSize.width());
|
||||||
y = st::stickerPanPadding + (section * featuredRowHeight()) + st::stickersTrendingHeader;
|
y = st::stickerPanPadding + (section * featuredRowHeight()) + st::stickersTrendingHeader;
|
||||||
} else if (_section == Section::Stickers) {
|
} else if (_section == Section::Stickers) {
|
||||||
auto info = sectionInfo(section);
|
auto info = sectionInfo(section);
|
||||||
if (sel >= _mySets[section].pack.size()) {
|
if (sel >= _mySets[section].pack.size()) {
|
||||||
sel -= _mySets[section].pack.size();
|
sel -= _mySets[section].pack.size();
|
||||||
}
|
}
|
||||||
auto countTillItem = (sel - (sel % kStickersPanelPerRow));
|
auto countTillItem = (sel - (sel % _columnCount));
|
||||||
auto rowsToSkip = (countTillItem / kStickersPanelPerRow) + ((countTillItem % kStickersPanelPerRow) ? 1 : 0);
|
auto rowsToSkip = (countTillItem / _columnCount) + ((countTillItem % _columnCount) ? 1 : 0);
|
||||||
x = stickersLeft() + ((sel % kStickersPanelPerRow) * st::stickerPanSize.width());
|
x = stickersLeft() + ((sel % _columnCount) * _singleSize.width());
|
||||||
y = info.rowsTop + rowsToSkip * st::stickerPanSize.height();
|
y = info.rowsTop + rowsToSkip * _singleSize.height();
|
||||||
}
|
}
|
||||||
return QRect(x, y, st::stickerPanSize.width(), st::stickerPanSize.height());
|
return QRect(QPoint(x, y), _singleSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::paintEvent(QPaintEvent *e) {
|
void StickersListWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -625,12 +662,12 @@ void StickersListWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::paintFeaturedStickers(Painter &p, QRect clip) {
|
void StickersListWidget::paintFeaturedStickers(Painter &p, QRect clip) {
|
||||||
auto fromColumn = floorclamp(clip.x() - stickersLeft(), st::stickerPanSize.width(), 0, kStickersPanelPerRow);
|
auto fromColumn = floorclamp(clip.x() - stickersLeft(), _singleSize.width(), 0, _columnCount);
|
||||||
auto toColumn = ceilclamp(clip.x() + clip.width() - stickersLeft(), st::stickerPanSize.width(), 0, kStickersPanelPerRow);
|
auto toColumn = ceilclamp(clip.x() + clip.width() - stickersLeft(), _singleSize.width(), 0, _columnCount);
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
qSwap(fromColumn, toColumn);
|
qSwap(fromColumn, toColumn);
|
||||||
fromColumn = kStickersPanelPerRow - fromColumn;
|
fromColumn = _columnCount - fromColumn;
|
||||||
toColumn = kStickersPanelPerRow - toColumn;
|
toColumn = _columnCount - toColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
|
@ -716,12 +753,12 @@ void StickersListWidget::paintFeaturedStickers(Painter &p, QRect clip) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
auto fromColumn = floorclamp(clip.x() - stickersLeft(), st::stickerPanSize.width(), 0, kStickersPanelPerRow);
|
auto fromColumn = floorclamp(clip.x() - stickersLeft(), _singleSize.width(), 0, _columnCount);
|
||||||
auto toColumn = ceilclamp(clip.x() + clip.width() - stickersLeft(), st::stickerPanSize.width(), 0, kStickersPanelPerRow);
|
auto toColumn = ceilclamp(clip.x() + clip.width() - stickersLeft(), _singleSize.width(), 0, _columnCount);
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
qSwap(fromColumn, toColumn);
|
qSwap(fromColumn, toColumn);
|
||||||
fromColumn = kStickersPanelPerRow - fromColumn;
|
fromColumn = _columnCount - fromColumn;
|
||||||
toColumn = kStickersPanelPerRow - toColumn;
|
toColumn = _columnCount - toColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
|
@ -766,11 +803,11 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
paintMegagroupEmptySet(p, info.rowsTop, buttonSelected, ms);
|
paintMegagroupEmptySet(p, info.rowsTop, buttonSelected, ms);
|
||||||
} else {
|
} else {
|
||||||
auto special = (set.flags & MTPDstickerSet::Flag::f_official) != 0;
|
auto special = (set.flags & MTPDstickerSet::Flag::f_official) != 0;
|
||||||
auto fromRow = floorclamp(clip.y() - info.rowsTop, st::stickerPanSize.height(), 0, info.rowsCount);
|
auto fromRow = floorclamp(clip.y() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
||||||
auto toRow = ceilclamp(clip.y() + clip.height() - info.rowsTop, st::stickerPanSize.height(), 0, info.rowsCount);
|
auto toRow = ceilclamp(clip.y() + clip.height() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
||||||
for (int i = fromRow; i < toRow; ++i) {
|
for (int i = fromRow; i < toRow; ++i) {
|
||||||
for (int j = fromColumn; j < toColumn; ++j) {
|
for (int j = fromColumn; j < toColumn; ++j) {
|
||||||
int index = i * kStickersPanelPerRow + j;
|
int index = i * _columnCount + j;
|
||||||
if (index >= info.count) break;
|
if (index >= info.count) break;
|
||||||
|
|
||||||
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
||||||
|
@ -811,13 +848,13 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
|
||||||
auto sticker = set.pack[index];
|
auto sticker = set.pack[index];
|
||||||
if (!sticker->sticker()) return;
|
if (!sticker->sticker()) return;
|
||||||
|
|
||||||
int row = (index / kStickersPanelPerRow), col = (index % kStickersPanelPerRow);
|
int row = (index / _columnCount), col = (index % _columnCount);
|
||||||
|
|
||||||
auto pos = QPoint(stickersLeft() + col * st::stickerPanSize.width(), y + row * st::stickerPanSize.height());
|
auto pos = QPoint(stickersLeft() + col * _singleSize.width(), y + row * _singleSize.height());
|
||||||
if (selected) {
|
if (selected) {
|
||||||
auto tl = pos;
|
auto tl = pos;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - st::stickerPanSize.width());
|
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||||
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
|
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto goodThumb = !sticker->thumb->isNull() && ((sticker->thumb->width() >= 128) || (sticker->thumb->height() >= 128));
|
auto goodThumb = !sticker->thumb->isNull() && ((sticker->thumb->width() >= 128) || (sticker->thumb->height() >= 128));
|
||||||
|
@ -827,19 +864,19 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
|
||||||
sticker->checkSticker();
|
sticker->checkSticker();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
|
auto coef = qMin((_singleSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (_singleSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height()));
|
||||||
if (coef > 1) coef = 1;
|
if (coef > 1) coef = 1;
|
||||||
auto w = qMax(qRound(coef * sticker->dimensions.width()), 1);
|
auto w = qMax(qRound(coef * sticker->dimensions.width()), 1);
|
||||||
auto h = qMax(qRound(coef * sticker->dimensions.height()), 1);
|
auto h = qMax(qRound(coef * sticker->dimensions.height()), 1);
|
||||||
auto ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
|
auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2);
|
||||||
if (goodThumb) {
|
if (goodThumb) {
|
||||||
p.drawPixmapLeft(ppos, width(), sticker->thumb->pix(w, h));
|
p.drawPixmapLeft(ppos, width(), sticker->thumb->pixSingle(w, h, w, h, ImageRoundRadius::None));
|
||||||
} else if (!sticker->sticker()->img->isNull()) {
|
} else if (!sticker->sticker()->img->isNull()) {
|
||||||
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h));
|
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pixSingle(w, h, w, h, ImageRoundRadius::None));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected && stickerHasDeleteButton(set, index)) {
|
if (selected && stickerHasDeleteButton(set, index)) {
|
||||||
auto xPos = pos + QPoint(st::stickerPanSize.width() - st::stickerPanDeleteIconBg.width(), 0);
|
auto xPos = pos + QPoint(_singleSize.width() - st::stickerPanDeleteIconBg.width(), 0);
|
||||||
p.setOpacity(deleteSelected ? st::stickerPanDeleteOpacityBgOver : st::stickerPanDeleteOpacityBg);
|
p.setOpacity(deleteSelected ? st::stickerPanDeleteOpacityBgOver : st::stickerPanDeleteOpacityBg);
|
||||||
st::stickerPanDeleteIconBg.paint(p, xPos, width());
|
st::stickerPanDeleteIconBg.paint(p, xPos, width());
|
||||||
p.setOpacity(deleteSelected ? st::stickerPanDeleteOpacityFgOver : st::stickerPanDeleteOpacityFg);
|
p.setOpacity(deleteSelected ? st::stickerPanDeleteOpacityFgOver : st::stickerPanDeleteOpacityFg);
|
||||||
|
@ -849,7 +886,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
int StickersListWidget::stickersRight() const {
|
int StickersListWidget::stickersRight() const {
|
||||||
return stickersLeft() + (kStickersPanelPerRow * st::stickerPanSize.width());
|
return stickersLeft() + (_columnCount * _singleSize.width());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListWidget::featuredHasAddButton(int index) const {
|
bool StickersListWidget::featuredHasAddButton(int index) const {
|
||||||
|
@ -1089,7 +1126,9 @@ void StickersListWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::resizeEvent(QResizeEvent *e) {
|
void StickersListWidget::resizeEvent(QResizeEvent *e) {
|
||||||
_settings->moveToLeft((st::emojiPanWidth - _settings->width()) / 2, height() / 3);
|
_settings->moveToLeft(
|
||||||
|
(width() - _settings->width()) / 2,
|
||||||
|
height() / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::leaveEventHook(QEvent *e) {
|
void StickersListWidget::leaveEventHook(QEvent *e) {
|
||||||
|
@ -1152,9 +1191,9 @@ void StickersListWidget::refreshStickers() {
|
||||||
appendSet(_featuredSets, setId, AppendSkip::Installed);
|
appendSet(_featuredSets, setId, AppendSkip::Installed);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSize();
|
resizeToWidth(width());
|
||||||
|
|
||||||
if (_footer) {
|
if (_footer && _columnCount > 0) {
|
||||||
_footer->refreshIcons(ValidateIconAnimations::None);
|
_footer->refreshIcons(ValidateIconAnimations::None);
|
||||||
if (_footer->hasOnlyFeaturedSets() && _section != Section::Featured) {
|
if (_footer->hasOnlyFeaturedSets() && _section != Section::Featured) {
|
||||||
showStickerSet(Stickers::FeaturedSetId);
|
showStickerSet(Stickers::FeaturedSetId);
|
||||||
|
@ -1173,10 +1212,10 @@ void StickersListWidget::preloadImages() {
|
||||||
for (int i = 0, l = sets.size(), k = 0; i < l; ++i) {
|
for (int i = 0, l = sets.size(), k = 0; i < l; ++i) {
|
||||||
int count = sets[i].pack.size();
|
int count = sets[i].pack.size();
|
||||||
if (_section == Section::Featured) {
|
if (_section == Section::Featured) {
|
||||||
accumulate_min(count, kStickersPanelPerRow);
|
accumulate_min(count, _columnCount);
|
||||||
}
|
}
|
||||||
for (int j = 0; j != count; ++j) {
|
for (int j = 0; j != count; ++j) {
|
||||||
if (++k > kStickersPanelPerRow * (kStickersPanelPerRow + 1)) break;
|
if (++k > _columnCount * (_columnCount + 1)) break;
|
||||||
|
|
||||||
auto sticker = sets.at(i).pack.at(j);
|
auto sticker = sets.at(i).pack.at(j);
|
||||||
if (!sticker || !sticker->sticker()) continue;
|
if (!sticker || !sticker->sticker()) continue;
|
||||||
|
@ -1188,7 +1227,7 @@ void StickersListWidget::preloadImages() {
|
||||||
sticker->automaticLoad(0);
|
sticker->automaticLoad(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (k > kStickersPanelPerRow * (kStickersPanelPerRow + 1)) break;
|
if (k > _columnCount * (_columnCount + 1)) break;
|
||||||
}
|
}
|
||||||
if (_footer) {
|
if (_footer) {
|
||||||
_footer->preloadImages();
|
_footer->preloadImages();
|
||||||
|
@ -1278,7 +1317,7 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (performResize && (_section == Section::Stickers || _section == Section::Featured)) {
|
if (performResize && (_section == Section::Stickers || _section == Section::Featured)) {
|
||||||
updateSize();
|
resizeToWidth(width());
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1370,7 +1409,7 @@ void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto s = _mySets[i].pack[0];
|
auto s = _mySets[i].pack[0];
|
||||||
auto availw = st::emojiCategory.width - 2 * st::stickerIconPadding, availh = st::emojiCategory.height - 2 * st::stickerIconPadding;
|
auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding, availh = st::emojiFooterHeight - 2 * st::stickerIconPadding;
|
||||||
auto thumbw = s->thumb->width(), thumbh = s->thumb->height(), pixw = 1, pixh = 1;
|
auto thumbw = s->thumb->width(), thumbh = s->thumb->height(), pixw = 1, pixh = 1;
|
||||||
if (availw * thumbh > availh * thumbw) {
|
if (availw * thumbh > availh * thumbw) {
|
||||||
pixh = availh;
|
pixh = availh;
|
||||||
|
@ -1421,9 +1460,9 @@ void StickersListWidget::updateSelected() {
|
||||||
} else {
|
} else {
|
||||||
newSelected = OverSet { section };
|
newSelected = OverSet { section };
|
||||||
}
|
}
|
||||||
} else if (yOffset >= st::stickersTrendingHeader && yOffset < st::stickersTrendingHeader + st::stickerPanSize.height()) {
|
} else if (yOffset >= st::stickersTrendingHeader && yOffset < st::stickersTrendingHeader + _singleSize.height()) {
|
||||||
if (sx >= 0 && sx < kStickersPanelPerRow * st::stickerPanSize.width()) {
|
if (sx >= 0 && sx < _columnCount * _singleSize.width()) {
|
||||||
auto index = qFloor(sx / st::stickerPanSize.width());
|
auto index = qFloor(sx / _singleSize.width());
|
||||||
if (index >= 0 && index < set.pack.size()) {
|
if (index >= 0 && index < set.pack.size()) {
|
||||||
auto overDelete = false;
|
auto overDelete = false;
|
||||||
newSelected = OverSticker { section, index, overDelete };
|
newSelected = OverSticker { section, index, overDelete };
|
||||||
|
@ -1452,15 +1491,15 @@ void StickersListWidget::updateSelected() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto special = ((set.flags & MTPDstickerSet::Flag::f_official) != 0);
|
auto special = ((set.flags & MTPDstickerSet::Flag::f_official) != 0);
|
||||||
auto rowIndex = qFloor(yOffset / st::stickerPanSize.height());
|
auto rowIndex = qFloor(yOffset / _singleSize.height());
|
||||||
auto columnIndex = qFloor(sx / st::stickerPanSize.width());
|
auto columnIndex = qFloor(sx / _singleSize.width());
|
||||||
auto index = rowIndex * kStickersPanelPerRow + columnIndex;
|
auto index = rowIndex * _columnCount + columnIndex;
|
||||||
if (index >= 0 && index < set.pack.size()) {
|
if (index >= 0 && index < set.pack.size()) {
|
||||||
auto overDelete = false;
|
auto overDelete = false;
|
||||||
if (stickerHasDeleteButton(set, index)) {
|
if (stickerHasDeleteButton(set, index)) {
|
||||||
auto inx = sx - (columnIndex * st::stickerPanSize.width());
|
auto inx = sx - (columnIndex * _singleSize.width());
|
||||||
auto iny = yOffset - (rowIndex * st::stickerPanSize.height());
|
auto iny = yOffset - (rowIndex * _singleSize.height());
|
||||||
if (inx >= st::stickerPanSize.width() - st::stickerPanDeleteIconBg.width() && iny < st::stickerPanDeleteIconBg.height()) {
|
if (inx >= _singleSize.width() - st::stickerPanDeleteIconBg.width() && iny < st::stickerPanDeleteIconBg.height()) {
|
||||||
overDelete = true;
|
overDelete = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ protected:
|
||||||
TabbedSelector::InnerFooter *getFooter() const override;
|
TabbedSelector::InnerFooter *getFooter() const override;
|
||||||
void processHideFinished() override;
|
void processHideFinished() override;
|
||||||
void processPanelHideFinished() override;
|
void processPanelHideFinished() override;
|
||||||
int countDesiredHeight() override;
|
int countDesiredHeight(int newWidth) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onSettings();
|
void onSettings();
|
||||||
|
@ -231,6 +231,9 @@ private:
|
||||||
uint64 _removingSetId = 0;
|
uint64 _removingSetId = 0;
|
||||||
|
|
||||||
Footer *_footer = nullptr;
|
Footer *_footer = nullptr;
|
||||||
|
int _rowsLeft = 0;
|
||||||
|
int _columnCount = 0;
|
||||||
|
QSize _singleSize;
|
||||||
|
|
||||||
OverState _selected;
|
OverState _selected;
|
||||||
OverState _pressed;
|
OverState _pressed;
|
||||||
|
|
|
@ -37,11 +37,13 @@ object_ptr<Window::SectionWidget> TabbedMemento::createWidget(
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> controller,
|
||||||
Window::Column column,
|
Window::Column column,
|
||||||
const QRect &geometry) {
|
const QRect &geometry) {
|
||||||
return object_ptr<TabbedSection>(
|
auto result = object_ptr<TabbedSection>(
|
||||||
parent,
|
parent,
|
||||||
controller,
|
controller,
|
||||||
std::move(_selector),
|
std::move(_selector),
|
||||||
std::move(_returnMethod));
|
std::move(_returnMethod));
|
||||||
|
result->setGeometry(geometry);
|
||||||
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
TabbedMemento::~TabbedMemento() {
|
TabbedMemento::~TabbedMemento() {
|
||||||
|
@ -68,8 +70,6 @@ TabbedSection::TabbedSection(
|
||||||
: Window::SectionWidget(parent, controller)
|
: Window::SectionWidget(parent, controller)
|
||||||
, _selector(std::move(selector))
|
, _selector(std::move(selector))
|
||||||
, _returnMethod(std::move(returnMethod)) {
|
, _returnMethod(std::move(returnMethod)) {
|
||||||
resize(st::emojiPanWidth, st::emojiPanMaxHeight);
|
|
||||||
|
|
||||||
_selector->setParent(this);
|
_selector->setParent(this);
|
||||||
_selector->setRoundRadius(0);
|
_selector->setRoundRadius(0);
|
||||||
_selector->setGeometry(rect());
|
_selector->setGeometry(rect());
|
||||||
|
|
|
@ -107,7 +107,7 @@ void TabbedSelector::SlideAnimation::setFinalImages(Direction direction, QImage
|
||||||
_painterInnerBottom = _innerBottom / cIntRetinaFactor();
|
_painterInnerBottom = _innerBottom / cIntRetinaFactor();
|
||||||
_painterInnerWidth = _innerWidth / cIntRetinaFactor();
|
_painterInnerWidth = _innerWidth / cIntRetinaFactor();
|
||||||
_painterInnerHeight = _innerHeight / cIntRetinaFactor();
|
_painterInnerHeight = _innerHeight / cIntRetinaFactor();
|
||||||
_painterCategoriesTop = _painterInnerBottom - st::emojiCategory.height;
|
_painterCategoriesTop = _painterInnerBottom - st::emojiFooterHeight;
|
||||||
|
|
||||||
_wasSectionIcons = wasSectionIcons;
|
_wasSectionIcons = wasSectionIcons;
|
||||||
}
|
}
|
||||||
|
@ -299,8 +299,6 @@ TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> co
|
||||||
}
|
}
|
||||||
|
|
||||||
createTabsSlider();
|
createTabsSlider();
|
||||||
|
|
||||||
_scroll->setGeometryToLeft(st::buttonRadius, marginTop(), st::emojiPanWidth - st::buttonRadius, height() - marginTop() - marginBottom());
|
|
||||||
setWidgetToScrollArea();
|
setWidgetToScrollArea();
|
||||||
|
|
||||||
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
||||||
|
@ -355,26 +353,47 @@ TabbedSelector::TabbedSelector(QWidget *parent, not_null<Window::Controller*> co
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
void TabbedSelector::resizeEvent(QResizeEvent *e) {
|
||||||
auto contentHeight = height() - marginTop() - marginBottom();
|
_tabsSlider->resizeToWidth(width());
|
||||||
|
_tabsSlider->moveToLeft(0, 0);
|
||||||
|
_topShadow->setGeometry(
|
||||||
|
_tabsSlider->x(),
|
||||||
|
_tabsSlider->bottomNoMargins() - st::lineWidth,
|
||||||
|
_tabsSlider->width(),
|
||||||
|
st::lineWidth);
|
||||||
|
|
||||||
|
auto scrollWidth = width() - st::buttonRadius;
|
||||||
|
auto scrollHeight = height() - marginTop() - marginBottom();
|
||||||
|
auto inner = currentTab()->widget();
|
||||||
|
auto innerWidth = scrollWidth - st::emojiScroll.width;
|
||||||
|
auto updateScrollGeometry = [&] {
|
||||||
|
_scroll->setGeometryToLeft(
|
||||||
|
st::buttonRadius,
|
||||||
|
marginTop(),
|
||||||
|
scrollWidth,
|
||||||
|
scrollHeight);
|
||||||
|
};
|
||||||
|
auto updateInnerGeometry = [&] {
|
||||||
|
auto scrollTop = _scroll->scrollTop();
|
||||||
|
auto scrollBottom = scrollTop + scrollHeight;
|
||||||
|
inner->setMinimalHeight(innerWidth, scrollHeight);
|
||||||
|
inner->setVisibleTopBottom(scrollTop, scrollBottom);
|
||||||
|
};
|
||||||
if (e->oldSize().height() > height()) {
|
if (e->oldSize().height() > height()) {
|
||||||
_scroll->resize(_scroll->width(), contentHeight);
|
updateScrollGeometry();
|
||||||
auto scrollTop = _scroll->scrollTop();
|
updateInnerGeometry();
|
||||||
currentTab()->widget()->setMinimalHeight(contentHeight);
|
|
||||||
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
|
|
||||||
} else {
|
} else {
|
||||||
auto scrollTop = _scroll->scrollTop();
|
updateInnerGeometry();
|
||||||
currentTab()->widget()->setMinimalHeight(contentHeight);
|
updateScrollGeometry();
|
||||||
currentTab()->widget()->setVisibleTopBottom(scrollTop, scrollTop + contentHeight);
|
|
||||||
_scroll->resize(_scroll->width(), contentHeight);
|
|
||||||
}
|
}
|
||||||
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
_bottomShadow->setGeometry(_tabsSlider->x(), _scroll->y() + _scroll->height() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
||||||
if (_restrictedLabel) {
|
if (_restrictedLabel) {
|
||||||
_restrictedLabel->move((width() - _restrictedLabel->width()), (height() / 3 - _restrictedLabel->height() / 2));
|
_restrictedLabel->move((width() - _restrictedLabel->width()), (height() / 3 - _restrictedLabel->height() / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
_footerTop = height() - st::emojiCategory.height;
|
_footerTop = height() - st::emojiFooterHeight;
|
||||||
for (auto &tab : _tabs) {
|
for (auto &tab : _tabs) {
|
||||||
tab.footer()->move(_tabsSlider->x(), _footerTop);
|
tab.footer()->resizeToWidth(width());
|
||||||
|
tab.footer()->moveToLeft(0, _footerTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
@ -416,12 +435,12 @@ void TabbedSelector::paintContent(Painter &p) {
|
||||||
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
auto topPart = QRect(0, 0, width(), _tabsSlider->height() + _roundRadius);
|
||||||
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
App::roundRect(p, topPart, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::NoTopBottom);
|
||||||
|
|
||||||
auto bottomPart = QRect(0, _footerTop - _roundRadius, width(), st::emojiCategory.height + _roundRadius);
|
auto bottomPart = QRect(0, _footerTop - _roundRadius, width(), st::emojiFooterHeight + _roundRadius);
|
||||||
auto bottomParts = RectPart::NoTopBottom | RectPart::FullBottom;
|
auto bottomParts = RectPart::NoTopBottom | RectPart::FullBottom;
|
||||||
App::roundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
App::roundRect(p, bottomPart, bottomBg, ImageRoundRadius::Small, bottomParts);
|
||||||
} else {
|
} else {
|
||||||
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);
|
||||||
p.fillRect(0, _footerTop, width(), st::emojiCategory.height, bottomBg);
|
p.fillRect(0, _footerTop, width(), st::emojiFooterHeight, bottomBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sidesTop = marginTop();
|
auto sidesTop = marginTop();
|
||||||
|
@ -439,7 +458,7 @@ int TabbedSelector::marginTop() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int TabbedSelector::marginBottom() const {
|
int TabbedSelector::marginBottom() const {
|
||||||
return st::emojiCategory.height;
|
return st::emojiFooterHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::refreshStickers() {
|
void TabbedSelector::refreshStickers() {
|
||||||
|
@ -606,10 +625,6 @@ void TabbedSelector::createTabsSlider() {
|
||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this] { switchTab(); },
|
[this] { switchTab(); },
|
||||||
lifetime());
|
lifetime());
|
||||||
|
|
||||||
_tabsSlider->resizeToWidth(width());
|
|
||||||
_tabsSlider->moveToLeft(0, 0);
|
|
||||||
_topShadow->setGeometry(_tabsSlider->x(), _tabsSlider->bottomNoMargins() - st::lineWidth, _tabsSlider->width(), st::lineWidth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabbedSelector::hasSectionIcons() const {
|
bool TabbedSelector::hasSectionIcons() const {
|
||||||
|
@ -683,10 +698,12 @@ not_null<GifsListWidget*> TabbedSelector::gifs() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::setWidgetToScrollArea() {
|
void TabbedSelector::setWidgetToScrollArea() {
|
||||||
_scroll->setOwnedWidget(currentTab()->takeWidget());
|
auto inner = _scroll->setOwnedWidget(currentTab()->takeWidget());
|
||||||
|
inner->resizeToWidth(_scroll->width() - st::emojiScroll.width);
|
||||||
|
inner->moveToLeft(0, 0);
|
||||||
|
inner->show();
|
||||||
|
|
||||||
_scroll->disableScroll(false);
|
_scroll->disableScroll(false);
|
||||||
currentTab()->widget()->moveToLeft(0, 0);
|
|
||||||
currentTab()->widget()->show();
|
|
||||||
scrollToY(currentTab()->getScrollTop());
|
scrollToY(currentTab()->getScrollTop());
|
||||||
onScroll();
|
onScroll();
|
||||||
}
|
}
|
||||||
|
@ -710,30 +727,32 @@ void TabbedSelector::Inner::visibleTopBottomUpdated(int visibleTop, int visibleB
|
||||||
_visibleBottom = visibleBottom;
|
_visibleBottom = visibleBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::Inner::setMinimalHeight(int newMinimalHeight) {
|
void TabbedSelector::Inner::setMinimalHeight(
|
||||||
|
int newWidth,
|
||||||
|
int newMinimalHeight) {
|
||||||
if (_minimalHeight != newMinimalHeight) {
|
if (_minimalHeight != newMinimalHeight) {
|
||||||
_minimalHeight = newMinimalHeight;
|
_minimalHeight = newMinimalHeight;
|
||||||
updateSize();
|
resizeToWidth(newWidth);
|
||||||
|
} else if (newWidth != width()) {
|
||||||
|
resizeToWidth(newWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::Inner::updateSize() {
|
int TabbedSelector::Inner::resizeGetHeight(int newWidth) {
|
||||||
auto width = st::emojiPanWidth
|
auto result = std::max(
|
||||||
- st::emojiScroll.width
|
countDesiredHeight(newWidth),
|
||||||
- st::buttonRadius;
|
minimalHeight());
|
||||||
auto height = qMax(countDesiredHeight(), minimalHeight());
|
if (result != height()) {
|
||||||
auto newSize = QSize(width, height);
|
|
||||||
if (size() != newSize) {
|
|
||||||
resize(newSize);
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TabbedSelector::Inner::minimalHeight() const {
|
int TabbedSelector::Inner::minimalHeight() const {
|
||||||
auto result = _minimalHeight;
|
auto result = _minimalHeight;
|
||||||
return (_minimalHeight > 0)
|
return (_minimalHeight > 0)
|
||||||
? _minimalHeight
|
? _minimalHeight
|
||||||
: (st::emojiPanMaxHeight - st::emojiCategory.height);
|
: (st::emojiPanMaxHeight - st::emojiFooterHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabbedSelector::Inner::hideFinished() {
|
void TabbedSelector::Inner::hideFinished() {
|
||||||
|
@ -751,8 +770,9 @@ void TabbedSelector::Inner::panelHideFinished() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent) : TWidget(parent) {
|
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent)
|
||||||
resize(st::emojiPanWidth, st::emojiCategory.height);
|
: TWidget(parent) {
|
||||||
|
resize(st::emojiPanWidth, st::emojiFooterHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -218,7 +218,7 @@ public:
|
||||||
int getVisibleBottom() const {
|
int getVisibleBottom() const {
|
||||||
return _visibleBottom;
|
return _visibleBottom;
|
||||||
}
|
}
|
||||||
void setMinimalHeight(int newMinimalHeight);
|
void setMinimalHeight(int newWidth, int newMinimalHeight);
|
||||||
|
|
||||||
virtual void refreshRecent() = 0;
|
virtual void refreshRecent() = 0;
|
||||||
virtual void preloadImages() {
|
virtual void preloadImages() {
|
||||||
|
@ -242,14 +242,14 @@ protected:
|
||||||
void visibleTopBottomUpdated(
|
void visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) override;
|
int visibleBottom) override;
|
||||||
void updateSize();
|
|
||||||
int minimalHeight() const;
|
int minimalHeight() const;
|
||||||
|
int resizeGetHeight(int newWidth) override final;
|
||||||
|
|
||||||
not_null<Window::Controller*> controller() const {
|
not_null<Window::Controller*> controller() const {
|
||||||
return _controller;
|
return _controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int countDesiredHeight() = 0;
|
virtual int countDesiredHeight(int newWidth) = 0;
|
||||||
virtual InnerFooter *getFooter() const = 0;
|
virtual InnerFooter *getFooter() const = 0;
|
||||||
virtual void processHideFinished() {
|
virtual void processHideFinished() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -3789,16 +3789,13 @@ void HistoryWidget::topBarClick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::pushTabbedSelectorToThirdSection() {
|
void HistoryWidget::pushTabbedSelectorToThirdSection(
|
||||||
|
const Window::SectionShow ¶ms) {
|
||||||
if (!_history || !_tabbedPanel) {
|
if (!_history || !_tabbedPanel) {
|
||||||
return;
|
return;
|
||||||
} else if (!_canSendMessages) {
|
} else if (!_canSendMessages) {
|
||||||
Auth().data().setTabbedReplacedWithInfo(true);
|
Auth().data().setTabbedReplacedWithInfo(true);
|
||||||
controller()->showPeerInfo(_peer,
|
controller()->showPeerInfo(_peer, params);
|
||||||
Window::SectionShow(
|
|
||||||
Window::SectionShow::Way::ClearStack,
|
|
||||||
anim::type::instant,
|
|
||||||
anim::activation::background));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Auth().data().setTabbedReplacedWithInfo(false);
|
Auth().data().setTabbedReplacedWithInfo(false);
|
||||||
|
@ -3814,25 +3811,16 @@ void HistoryWidget::pushTabbedSelectorToThirdSection() {
|
||||||
returnTabbedSelector(std::move(selector));
|
returnTabbedSelector(std::move(selector));
|
||||||
}));
|
}));
|
||||||
controller()->resizeForThirdSection();
|
controller()->resizeForThirdSection();
|
||||||
controller()->showSection(
|
controller()->showSection(std::move(memento), params);
|
||||||
std::move(memento),
|
|
||||||
Window::SectionShow(
|
|
||||||
Window::SectionShow::Way::ClearStack,
|
|
||||||
anim::type::instant,
|
|
||||||
anim::activation::background));
|
|
||||||
destroyingPanel.destroy();
|
destroyingPanel.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::pushInfoToThirdSection() {
|
void HistoryWidget::pushInfoToThirdSection(
|
||||||
|
const Window::SectionShow ¶ms) {
|
||||||
if (!_peer) {
|
if (!_peer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
controller()->showPeerInfo(
|
controller()->showPeerInfo(_peer, params);
|
||||||
_peer,
|
|
||||||
Window::SectionShow(
|
|
||||||
Window::SectionShow::Way::ClearStack,
|
|
||||||
anim::type::instant,
|
|
||||||
anim::activation::background));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::toggleTabbedSelectorMode() {
|
void HistoryWidget::toggleTabbedSelectorMode() {
|
||||||
|
@ -3841,7 +3829,8 @@ void HistoryWidget::toggleTabbedSelectorMode() {
|
||||||
&& !Adaptive::OneColumn()) {
|
&& !Adaptive::OneColumn()) {
|
||||||
Auth().data().setTabbedSelectorSectionEnabled(true);
|
Auth().data().setTabbedSelectorSectionEnabled(true);
|
||||||
Auth().saveDataDelayed();
|
Auth().saveDataDelayed();
|
||||||
pushTabbedSelectorToThirdSection();
|
pushTabbedSelectorToThirdSection(
|
||||||
|
Window::SectionShow::Way::ClearStack);
|
||||||
} else {
|
} else {
|
||||||
_tabbedPanel->toggleAnimated();
|
_tabbedPanel->toggleAnimated();
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,10 @@ public:
|
||||||
void unreadCountChanged(History *history);
|
void unreadCountChanged(History *history);
|
||||||
|
|
||||||
QRect historyRect() const;
|
QRect historyRect() const;
|
||||||
void pushTabbedSelectorToThirdSection();
|
void pushTabbedSelectorToThirdSection(
|
||||||
void pushInfoToThirdSection();
|
const Window::SectionShow ¶ms);
|
||||||
|
void pushInfoToThirdSection(
|
||||||
|
const Window::SectionShow ¶ms);
|
||||||
|
|
||||||
void updateSendAction(History *history, SendAction::Type type, int32 progress = 0);
|
void updateSendAction(History *history, SendAction::Type type, int32 progress = 0);
|
||||||
void cancelSendAction(History *history, SendAction::Type type);
|
void cancelSendAction(History *history, SendAction::Type type);
|
||||||
|
|
|
@ -362,7 +362,7 @@ infoProfileButton: InfoProfileButton {
|
||||||
textBg: windowBg;
|
textBg: windowBg;
|
||||||
textBgOver: windowBgOver;
|
textBgOver: windowBgOver;
|
||||||
|
|
||||||
font: semiboldFont;
|
font: normalFont;
|
||||||
|
|
||||||
height: 20px;
|
height: 20px;
|
||||||
padding: margins(79px, 10px, 8px, 8px);
|
padding: margins(79px, 10px, 8px, 8px);
|
||||||
|
|
|
@ -3388,10 +3388,14 @@ void MainWidget::updateControlsGeometry() {
|
||||||
if (Adaptive::ThreeColumn()) {
|
if (Adaptive::ThreeColumn()) {
|
||||||
if (!_thirdSection
|
if (!_thirdSection
|
||||||
&& !_controller->takeThirdSectionFromLayer()) {
|
&& !_controller->takeThirdSectionFromLayer()) {
|
||||||
|
auto params = Window::SectionShow(
|
||||||
|
Window::SectionShow::Way::ClearStack,
|
||||||
|
anim::type::instant,
|
||||||
|
anim::activation::background);
|
||||||
if (Auth().data().tabbedSelectorSectionEnabled()) {
|
if (Auth().data().tabbedSelectorSectionEnabled()) {
|
||||||
_history->pushTabbedSelectorToThirdSection();
|
_history->pushTabbedSelectorToThirdSection(params);
|
||||||
} else if (Auth().data().thirdSectionInfoEnabled()) {
|
} else if (Auth().data().thirdSectionInfoEnabled()) {
|
||||||
_history->pushInfoToThirdSection();
|
_history->pushInfoToThirdSection(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -3507,18 +3511,17 @@ void MainWidget::updateThirdColumnToCurrentPeer(
|
||||||
_thirdSection->createMemento());
|
_thirdSection->createMemento());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
auto params = Window::SectionShow(
|
||||||
|
Window::SectionShow::Way::ClearStack,
|
||||||
|
anim::type::instant,
|
||||||
|
anim::activation::background);
|
||||||
auto switchInfoFast = [&] {
|
auto switchInfoFast = [&] {
|
||||||
saveOldThirdSection();
|
saveOldThirdSection();
|
||||||
_controller->showPeerInfo(
|
_controller->showPeerInfo(peer, params);
|
||||||
peer,
|
|
||||||
SectionShow(
|
|
||||||
SectionShow::Way::ClearStack,
|
|
||||||
anim::type::instant,
|
|
||||||
anim::activation::background));
|
|
||||||
};
|
};
|
||||||
auto switchTabbedFast = [&] {
|
auto switchTabbedFast = [&] {
|
||||||
saveOldThirdSection();
|
saveOldThirdSection();
|
||||||
_history->pushTabbedSelectorToThirdSection();
|
_history->pushTabbedSelectorToThirdSection(params);
|
||||||
};
|
};
|
||||||
if (Adaptive::ThreeColumn()
|
if (Adaptive::ThreeColumn()
|
||||||
&& Auth().data().tabbedSelectorSectionEnabled()
|
&& Auth().data().tabbedSelectorSectionEnabled()
|
||||||
|
|
|
@ -32,7 +32,7 @@ windowShadowShift: 1px;
|
||||||
|
|
||||||
columnMinimalWidthLeft: 260px;
|
columnMinimalWidthLeft: 260px;
|
||||||
columnMinimalWidthMain: 380px;
|
columnMinimalWidthMain: 380px;
|
||||||
columnMinimalWidthThird: 345px;
|
columnMinimalWidthThird: 292px;//345px;
|
||||||
|
|
||||||
adaptiveChatWideWidth: 880px;
|
adaptiveChatWideWidth: 880px;
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,8 @@ void Controller::resizeForThirdSection() {
|
||||||
st::columnMinimalWidthThird);
|
st::columnMinimalWidthThird);
|
||||||
auto newBodyWidth = layout.bodyWidth + extendBy;
|
auto newBodyWidth = layout.bodyWidth + extendBy;
|
||||||
auto currentRatio = Auth().data().dialogsWidthRatio();
|
auto currentRatio = Auth().data().dialogsWidthRatio();
|
||||||
Auth().data().setDialogsWidthRatio((currentRatio * layout.bodyWidth) / newBodyWidth);
|
Auth().data().setDialogsWidthRatio(
|
||||||
|
(currentRatio * layout.bodyWidth) / newBodyWidth);
|
||||||
window()->tryToExtendWidthBy(extendBy);
|
window()->tryToExtendWidthBy(extendBy);
|
||||||
|
|
||||||
Auth().data().setTabbedSelectorSectionEnabled(
|
Auth().data().setTabbedSelectorSectionEnabled(
|
||||||
|
|
Loading…
Reference in New Issue