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