Implement expanding of list / categories.
This commit is contained in:
parent
c5fa4aae62
commit
20d4d00634
|
@ -483,6 +483,21 @@ auto EmojiListWidget::premiumChosen() const
|
||||||
return _premiumChosen.events();
|
return _premiumChosen.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::paintExpanding(
|
||||||
|
QPainter &p,
|
||||||
|
QRect clip,
|
||||||
|
RectPart origin) {
|
||||||
|
const auto shift = clip.topLeft();
|
||||||
|
const auto adjusted = clip.translated(-shift);
|
||||||
|
p.translate(shift);
|
||||||
|
p.setClipRect(adjusted);
|
||||||
|
const auto context = ExpandingContext{
|
||||||
|
.expanding = true,
|
||||||
|
};
|
||||||
|
paint(p, context, adjusted);
|
||||||
|
p.translate(-shift);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiListWidget::visibleTopBottomUpdated(
|
void EmojiListWidget::visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) {
|
int visibleBottom) {
|
||||||
|
@ -755,14 +770,26 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
_repaintsScheduled.clear();
|
_repaintsScheduled.clear();
|
||||||
|
|
||||||
const auto r = e ? e->rect() : rect();
|
const auto clip = e ? e->rect() : rect();
|
||||||
if (r != rect()) {
|
p.fillRect(clip, st::emojiPanBg);
|
||||||
p.setClipRect(r);
|
|
||||||
}
|
|
||||||
p.fillRect(r, st::emojiPanBg);
|
|
||||||
|
|
||||||
auto fromColumn = floorclamp(r.x() - _rowsLeft, _singleSize.width(), 0, _columnCount);
|
paint(p, {}, clip);
|
||||||
auto toColumn = ceilclamp(r.x() + r.width() - _rowsLeft, _singleSize.width(), 0, _columnCount);
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::paint(
|
||||||
|
QPainter &p,
|
||||||
|
const ExpandingContext &context,
|
||||||
|
QRect clip) {
|
||||||
|
auto fromColumn = floorclamp(
|
||||||
|
clip.x() - _rowsLeft,
|
||||||
|
_singleSize.width(),
|
||||||
|
0,
|
||||||
|
_columnCount);
|
||||||
|
auto toColumn = ceilclamp(
|
||||||
|
clip.x() + clip.width() - _rowsLeft,
|
||||||
|
_singleSize.width(),
|
||||||
|
0,
|
||||||
|
_columnCount);
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
qSwap(fromColumn, toColumn);
|
qSwap(fromColumn, toColumn);
|
||||||
fromColumn = _columnCount - fromColumn;
|
fromColumn = _columnCount - fromColumn;
|
||||||
|
@ -775,9 +802,9 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
? &_pressed
|
? &_pressed
|
||||||
: &_selected);
|
: &_selected);
|
||||||
enumerateSections([&](const SectionInfo &info) {
|
enumerateSections([&](const SectionInfo &info) {
|
||||||
if (r.top() >= info.rowsBottom) {
|
if (clip.top() >= info.rowsBottom) {
|
||||||
return true;
|
return true;
|
||||||
} else if (r.top() + r.height() <= info.top) {
|
} else if (clip.top() + clip.height() <= info.top) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto buttonSelected = selectedButton
|
const auto buttonSelected = selectedButton
|
||||||
|
@ -785,8 +812,8 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
: false;
|
: false;
|
||||||
const auto widthForTitle = emojiRight()
|
const auto widthForTitle = emojiRight()
|
||||||
- (st().headerLeft - st().margin.left())
|
- (st().headerLeft - st().margin.left())
|
||||||
- paintButtonGetWidth(p, info, buttonSelected, r);
|
- paintButtonGetWidth(p, info, buttonSelected, clip);
|
||||||
if (info.section > 0 && r.top() < info.rowsTop) {
|
if (info.section > 0 && clip.top() < info.rowsTop) {
|
||||||
p.setFont(st::emojiPanHeaderFont);
|
p.setFont(st::emojiPanHeaderFont);
|
||||||
p.setPen(st::emojiPanHeaderFg);
|
p.setPen(st::emojiPanHeaderFg);
|
||||||
auto titleText = (info.section < _staticCount)
|
auto titleText = (info.section < _staticCount)
|
||||||
|
@ -808,14 +835,23 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
top,
|
top,
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
|
const auto textTop = top + st::emojiPanHeaderFont->ascent;
|
||||||
p.setFont(st::emojiPanHeaderFont);
|
p.setFont(st::emojiPanHeaderFont);
|
||||||
p.setPen(st::emojiPanHeaderFg);
|
p.setPen(st::emojiPanHeaderFg);
|
||||||
p.drawTextLeft(left, top, width(), titleText, titleWidth);
|
p.drawText(left, textTop, titleText);
|
||||||
}
|
}
|
||||||
if (r.top() + r.height() > info.rowsTop) {
|
if (clip.top() + clip.height() > info.rowsTop) {
|
||||||
ensureLoaded(info.section);
|
ensureLoaded(info.section);
|
||||||
auto fromRow = floorclamp(r.y() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
auto fromRow = floorclamp(
|
||||||
auto toRow = ceilclamp(r.y() + r.height() - info.rowsTop, _singleSize.height(), 0, info.rowsCount);
|
clip.y() - info.rowsTop,
|
||||||
|
_singleSize.height(),
|
||||||
|
0,
|
||||||
|
info.rowsCount);
|
||||||
|
auto toRow = ceilclamp(
|
||||||
|
clip.y() + clip.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) {
|
||||||
const auto index = i * _columnCount + j;
|
const auto index = i * _columnCount + j;
|
||||||
|
@ -1790,6 +1826,7 @@ QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
||||||
void EmojiListWidget::refreshEmoji() {
|
void EmojiListWidget::refreshEmoji() {
|
||||||
refreshRecent();
|
refreshRecent();
|
||||||
refreshCustom();
|
refreshCustom();
|
||||||
|
resizeToWidth(width());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::showSet(uint64 setId) {
|
void EmojiListWidget::showSet(uint64 setId) {
|
||||||
|
|
|
@ -112,6 +112,8 @@ public:
|
||||||
[[nodiscard]] auto premiumChosen() const
|
[[nodiscard]] auto premiumChosen() const
|
||||||
-> rpl::producer<not_null<DocumentData*>>;
|
-> rpl::producer<not_null<DocumentData*>>;
|
||||||
|
|
||||||
|
void paintExpanding(QPainter &p, QRect clip, RectPart origin);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void visibleTopBottomUpdated(
|
void visibleTopBottomUpdated(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
|
@ -205,6 +207,9 @@ private:
|
||||||
OverEmoji,
|
OverEmoji,
|
||||||
OverSet,
|
OverSet,
|
||||||
OverButton>;
|
OverButton>;
|
||||||
|
struct ExpandingContext {
|
||||||
|
bool expanding = false;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
bool enumerateSections(Callback callback) const;
|
bool enumerateSections(Callback callback) const;
|
||||||
|
@ -230,6 +235,7 @@ private:
|
||||||
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
|
[[nodiscard]] EmojiPtr lookupOverEmoji(const OverEmoji *over) const;
|
||||||
void selectEmoji(EmojiPtr emoji);
|
void selectEmoji(EmojiPtr emoji);
|
||||||
void selectCustom(not_null<DocumentData*> document);
|
void selectCustom(not_null<DocumentData*> document);
|
||||||
|
void paint(QPainter &p, const ExpandingContext &context, QRect clip);
|
||||||
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
|
void drawCollapsedBadge(QPainter &p, QPoint position, int count);
|
||||||
void drawRecent(
|
void drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/rect_part.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
@ -222,6 +223,27 @@ void StickersListFooter::clearHeavyData() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersListFooter::paintExpanding(
|
||||||
|
Painter &p,
|
||||||
|
QRect clip,
|
||||||
|
float64 radius,
|
||||||
|
RectPart origin) {
|
||||||
|
const auto delta = ((origin | RectPart::None) & RectPart::FullBottom)
|
||||||
|
? (height() - clip.height())
|
||||||
|
: 0;
|
||||||
|
const auto shift = QPoint(clip.x(), clip.y() - delta);
|
||||||
|
p.translate(shift);
|
||||||
|
const auto context = ExpandingContext{
|
||||||
|
.clip = clip.translated(-shift),
|
||||||
|
.progress = clip.height() / float64(height()),
|
||||||
|
.radius = int(std::ceil(radius)),
|
||||||
|
.expanding = true,
|
||||||
|
};
|
||||||
|
paint(p, context);
|
||||||
|
p.translate(-shift);
|
||||||
|
p.setClipping(false);
|
||||||
|
}
|
||||||
|
|
||||||
void StickersListFooter::initSearch() {
|
void StickersListFooter::initSearch() {
|
||||||
_searchField.create(
|
_searchField.create(
|
||||||
this,
|
this,
|
||||||
|
@ -536,9 +558,15 @@ void StickersListFooter::setLoading(bool loading) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintEvent(QPaintEvent *e) {
|
void StickersListFooter::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
auto p = Painter(this);
|
||||||
|
|
||||||
_repaintScheduled = false;
|
_repaintScheduled = false;
|
||||||
|
paint(p, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersListFooter::paint(
|
||||||
|
Painter &p,
|
||||||
|
const ExpandingContext &context) const {
|
||||||
if (_searchButtonVisible) {
|
if (_searchButtonVisible) {
|
||||||
paintSearchIcon(p);
|
paintSearchIcon(p);
|
||||||
}
|
}
|
||||||
|
@ -558,25 +586,37 @@ void StickersListFooter::paintEvent(QPaintEvent *e) {
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
clip.moveLeft(width() - _iconsLeft - clip.width());
|
clip.moveLeft(width() - _iconsLeft - clip.width());
|
||||||
}
|
}
|
||||||
p.setClipRect(clip);
|
if (context.expanding) {
|
||||||
|
const auto both = clip.intersected(
|
||||||
|
context.clip.marginsRemoved(
|
||||||
|
{ context.radius, 0, context.radius, 0 }));
|
||||||
|
if (both.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.setClipRect(both);
|
||||||
|
} else {
|
||||||
|
p.setClipRect(clip);
|
||||||
|
}
|
||||||
|
|
||||||
if (!_barSelection) {
|
if (!_barSelection) {
|
||||||
paintSelectionBg(p);
|
paintSelectionBg(p, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
const auto paused = _paused();
|
const auto paused = _paused();
|
||||||
enumerateVisibleIcons([&](const IconInfo &info) {
|
enumerateVisibleIcons([&](const IconInfo &info) {
|
||||||
paintSetIcon(p, info, now, paused);
|
paintSetIcon(p, context, info, now, paused);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_barSelection) {
|
if (_barSelection) {
|
||||||
paintSelectionBar(p);
|
paintSelectionBar(p);
|
||||||
}
|
}
|
||||||
paintLeftRightFading(p);
|
paintLeftRightFading(p, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintSelectionBg(Painter &p) const {
|
void StickersListFooter::paintSelectionBg(
|
||||||
|
QPainter &p,
|
||||||
|
const ExpandingContext &context) const {
|
||||||
auto selxrel = _iconsLeft + qRound(_iconState.selectionX.current());
|
auto selxrel = _iconsLeft + qRound(_iconState.selectionX.current());
|
||||||
auto selx = selxrel - qRound(_iconState.x.current());
|
auto selx = selxrel - qRound(_iconState.x.current());
|
||||||
const auto selw = qRound(_iconState.selectionWidth.current());
|
const auto selw = qRound(_iconState.selectionWidth.current());
|
||||||
|
@ -585,9 +625,18 @@ void StickersListFooter::paintSelectionBg(Painter &p) const {
|
||||||
}
|
}
|
||||||
const auto sely = _iconsTop;
|
const auto sely = _iconsTop;
|
||||||
const auto area = st().iconArea;
|
const auto area = st().iconArea;
|
||||||
const auto rect = QRect(
|
auto rect = QRect(
|
||||||
QPoint(selx, sely) + _areaPosition,
|
QPoint(selx, sely) + _areaPosition,
|
||||||
QSize(selw - 2 * _areaPosition.x(), area));
|
QSize(selw - 2 * _areaPosition.x(), area));
|
||||||
|
if (context.expanding) {
|
||||||
|
const auto recthalf = rect.height() / 2;
|
||||||
|
const auto myhalf = height() / 2;
|
||||||
|
const auto sub = anim::interpolate(recthalf, 0, context.progress);
|
||||||
|
const auto shift = anim::interpolate(myhalf, 0, context.progress);
|
||||||
|
rect = rect.marginsRemoved(
|
||||||
|
{ sub, sub, sub, sub }
|
||||||
|
).translated(0, shift);
|
||||||
|
}
|
||||||
if (rect.width() == rect.height() || _subiconsWidth <= _singleWidth) {
|
if (rect.width() == rect.height() || _subiconsWidth <= _singleWidth) {
|
||||||
_selectionBg.paint(p, rect);
|
_selectionBg.paint(p, rect);
|
||||||
} else if (selw == _subiconsWidth) {
|
} else if (selw == _subiconsWidth) {
|
||||||
|
@ -606,7 +655,7 @@ void StickersListFooter::paintSelectionBg(Painter &p) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintSelectionBar(Painter &p) const {
|
void StickersListFooter::paintSelectionBar(QPainter &p) const {
|
||||||
auto selxrel = _iconsLeft + qRound(_iconState.selectionX.current());
|
auto selxrel = _iconsLeft + qRound(_iconState.selectionX.current());
|
||||||
auto selx = selxrel - qRound(_iconState.x.current());
|
auto selx = selxrel - qRound(_iconState.x.current());
|
||||||
const auto selw = qRound(_iconState.selectionWidth.current());
|
const auto selw = qRound(_iconState.selectionWidth.current());
|
||||||
|
@ -621,26 +670,37 @@ void StickersListFooter::paintSelectionBar(Painter &p) const {
|
||||||
st::stickerIconSelColor);
|
st::stickerIconSelColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintLeftRightFading(Painter &p) const {
|
void StickersListFooter::paintLeftRightFading(
|
||||||
auto o_left = std::clamp(
|
QPainter &p,
|
||||||
|
const ExpandingContext &context) const {
|
||||||
|
const auto o_left_normal = std::clamp(
|
||||||
_iconState.x.current() / st().fadeLeft.width(),
|
_iconState.x.current() / st().fadeLeft.width(),
|
||||||
0.,
|
0.,
|
||||||
1.);
|
1.);
|
||||||
|
const auto o_left = context.expanding
|
||||||
|
? (1. - context.progress * (1. - o_left_normal))
|
||||||
|
: o_left_normal;
|
||||||
|
const auto radiusSkip = context.expanding
|
||||||
|
? std::max(context.radius - st::roundRadiusSmall, 0)
|
||||||
|
: 0;
|
||||||
if (o_left > 0) {
|
if (o_left > 0) {
|
||||||
p.setOpacity(o_left);
|
p.setOpacity(o_left);
|
||||||
st().fadeLeft.fill(p, style::rtlrect(_iconsLeft, _iconsTop, st().fadeLeft.width(), st().footer, width()));
|
st().fadeLeft.fill(p, style::rtlrect(std::max(_iconsLeft, radiusSkip), _iconsTop, st().fadeLeft.width(), st().footer, width()));
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
auto o_right = std::clamp(
|
const auto o_right_normal = std::clamp(
|
||||||
(_iconState.max - _iconState.x.current()) / st().fadeRight.width(),
|
(_iconState.max - _iconState.x.current()) / st().fadeRight.width(),
|
||||||
0.,
|
0.,
|
||||||
1.);
|
1.);
|
||||||
|
const auto o_right = context.expanding
|
||||||
|
? (1. - context.progress * (1. - o_right_normal))
|
||||||
|
: o_right_normal;
|
||||||
if (o_right > 0) {
|
if (o_right > 0) {
|
||||||
p.setOpacity(o_right);
|
p.setOpacity(o_right);
|
||||||
st().fadeRight.fill(
|
st().fadeRight.fill(
|
||||||
p,
|
p,
|
||||||
style::rtlrect(
|
style::rtlrect(
|
||||||
width() - _iconsRight - st().fadeRight.width(),
|
width() - std::max(_iconsRight, radiusSkip) - st().fadeRight.width(),
|
||||||
_iconsTop,
|
_iconsTop,
|
||||||
st().fadeRight.width(),
|
st().fadeRight.width(),
|
||||||
st().footer, width()));
|
st().footer, width()));
|
||||||
|
@ -1043,7 +1103,7 @@ bool StickersListFooter::hasOnlyFeaturedSets() const {
|
||||||
&& (_icons[0].setId == Data::Stickers::FeaturedSetId);
|
&& (_icons[0].setId == Data::Stickers::FeaturedSetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintStickerSettingsIcon(Painter &p) const {
|
void StickersListFooter::paintStickerSettingsIcon(QPainter &p) const {
|
||||||
const auto settingsLeft = width() - _iconsRight;
|
const auto settingsLeft = width() - _iconsRight;
|
||||||
st::stickersSettings.paint(
|
st::stickersSettings.paint(
|
||||||
p,
|
p,
|
||||||
|
@ -1053,7 +1113,7 @@ void StickersListFooter::paintStickerSettingsIcon(Painter &p) const {
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::paintSearchIcon(Painter &p) const {
|
void StickersListFooter::paintSearchIcon(QPainter &p) const {
|
||||||
const auto searchLeft = _iconsLeft - _singleWidth;
|
const auto searchLeft = _iconsLeft - _singleWidth;
|
||||||
st::stickersSearch.paint(
|
st::stickersSearch.paint(
|
||||||
p,
|
p,
|
||||||
|
@ -1152,10 +1212,21 @@ void StickersListFooter::updateSetIconAt(int left) {
|
||||||
|
|
||||||
void StickersListFooter::paintSetIcon(
|
void StickersListFooter::paintSetIcon(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
const ExpandingContext &context,
|
||||||
const IconInfo &info,
|
const IconInfo &info,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool paused) const {
|
bool paused) const {
|
||||||
const auto &icon = _icons[info.index];
|
const auto &icon = _icons[info.index];
|
||||||
|
if (context.expanding) {
|
||||||
|
p.save();
|
||||||
|
const auto center = QPoint(
|
||||||
|
info.adjustedLeft + _singleWidth / 2,
|
||||||
|
_iconsTop + st().footer / 2);
|
||||||
|
const auto shift = QPoint(0, anim::interpolate(height() / 2, 0, context.progress));
|
||||||
|
p.translate(shift + center);
|
||||||
|
p.scale(context.progress, context.progress);
|
||||||
|
p.translate(-center);
|
||||||
|
}
|
||||||
if (icon.sticker) {
|
if (icon.sticker) {
|
||||||
icon.ensureMediaCreated();
|
icon.ensureMediaCreated();
|
||||||
const_cast<StickersListFooter*>(this)->validateIconAnimation(icon);
|
const_cast<StickersListFooter*>(this)->validateIconAnimation(icon);
|
||||||
|
@ -1296,6 +1367,9 @@ void StickersListFooter::paintSetIcon(
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (context.expanding) {
|
||||||
|
p.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalStickersManager::LocalStickersManager(not_null<Main::Session*> session)
|
LocalStickersManager::LocalStickersManager(not_null<Main::Session*> session)
|
||||||
|
|
|
@ -134,6 +134,12 @@ public:
|
||||||
};
|
};
|
||||||
[[nodiscard]] rpl::producer<SearchRequest> searchRequests() const;
|
[[nodiscard]] rpl::producer<SearchRequest> searchRequests() const;
|
||||||
|
|
||||||
|
void paintExpanding(
|
||||||
|
Painter &p,
|
||||||
|
QRect clip,
|
||||||
|
float64 radius,
|
||||||
|
RectPart origin);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
@ -182,6 +188,12 @@ private:
|
||||||
crl::time animationStart = 0;
|
crl::time animationStart = 0;
|
||||||
Ui::Animations::Basic animation;
|
Ui::Animations::Basic animation;
|
||||||
};
|
};
|
||||||
|
struct ExpandingContext {
|
||||||
|
QRect clip;
|
||||||
|
float64 progress = 0.;
|
||||||
|
int radius = 0;
|
||||||
|
bool expanding = false;
|
||||||
|
};
|
||||||
|
|
||||||
void enumerateVisibleIcons(Fn<void(const IconInfo &)> callback) const;
|
void enumerateVisibleIcons(Fn<void(const IconInfo &)> callback) const;
|
||||||
void enumerateIcons(Fn<bool(const IconInfo &)> callback) const;
|
void enumerateIcons(Fn<bool(const IconInfo &)> callback) const;
|
||||||
|
@ -212,16 +224,23 @@ private:
|
||||||
void checkDragging(ScrollState &state);
|
void checkDragging(ScrollState &state);
|
||||||
bool finishDragging(ScrollState &state);
|
bool finishDragging(ScrollState &state);
|
||||||
bool finishDragging();
|
bool finishDragging();
|
||||||
void paintStickerSettingsIcon(Painter &p) const;
|
|
||||||
void paintSearchIcon(Painter &p) const;
|
void paint(Painter &p, const ExpandingContext &context) const;
|
||||||
|
void paintStickerSettingsIcon(QPainter &p) const;
|
||||||
|
void paintSearchIcon(QPainter &p) const;
|
||||||
void paintSetIcon(
|
void paintSetIcon(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
const ExpandingContext &context,
|
||||||
const IconInfo &info,
|
const IconInfo &info,
|
||||||
crl::time now,
|
crl::time now,
|
||||||
bool paused) const;
|
bool paused) const;
|
||||||
void paintSelectionBg(Painter &p) const;
|
void paintSelectionBg(
|
||||||
void paintSelectionBar(Painter &p) const;
|
QPainter &p,
|
||||||
void paintLeftRightFading(Painter &p) const;
|
const ExpandingContext &context) const;
|
||||||
|
void paintSelectionBar(QPainter &p) const;
|
||||||
|
void paintLeftRightFading(
|
||||||
|
QPainter &p,
|
||||||
|
const ExpandingContext &context) const;
|
||||||
|
|
||||||
void updateEmojiSectionWidth();
|
void updateEmojiSectionWidth();
|
||||||
void updateEmojiWidthCallback();
|
void updateEmojiWidthCallback();
|
||||||
|
|
|
@ -267,13 +267,25 @@ void Selector::paintCollapsed(QPainter &p) {
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::paintExpanding(QPainter &p, float64 progress) {
|
void Selector::paintExpanding(Painter &p, float64 progress) {
|
||||||
paintExpandingBg(p, progress);
|
const auto rects = paintExpandingBg(p, progress);
|
||||||
paintStripWithoutExpand(p);
|
//paintStripWithoutExpand(p);
|
||||||
paintFadingExpandIcon(p, progress);
|
paintFadingExpandIcon(p, progress);
|
||||||
|
if (_footer) {
|
||||||
|
_footer->paintExpanding(
|
||||||
|
p,
|
||||||
|
rects.categories,
|
||||||
|
rects.radius,
|
||||||
|
RectPart::BottomRight);
|
||||||
|
}
|
||||||
|
_list->paintExpanding(
|
||||||
|
p,
|
||||||
|
rects.list.marginsRemoved(st::reactPanelEmojiPan.margin),
|
||||||
|
RectPart::TopRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::paintExpandingBg(QPainter &p, float64 progress) {
|
auto Selector::paintExpandingBg(QPainter &p, float64 progress)
|
||||||
|
-> ExpandingRects {
|
||||||
constexpr auto kFramesCount = Ui::RoundAreaWithShadow::kFramesCount;
|
constexpr auto kFramesCount = Ui::RoundAreaWithShadow::kFramesCount;
|
||||||
const auto frame = int(base::SafeRound(progress * (kFramesCount - 1)));
|
const auto frame = int(base::SafeRound(progress * (kFramesCount - 1)));
|
||||||
const auto radiusStart = st::reactStripHeight / 2.;
|
const auto radiusStart = st::reactStripHeight / 2.;
|
||||||
|
@ -292,6 +304,21 @@ void Selector::paintExpandingBg(QPainter &p, float64 progress) {
|
||||||
if (!fill.isEmpty()) {
|
if (!fill.isEmpty()) {
|
||||||
p.fillRect(fill, st::defaultPopupMenu.menu.itemBg);
|
p.fillRect(fill, st::defaultPopupMenu.menu.itemBg);
|
||||||
}
|
}
|
||||||
|
const auto categories = anim::interpolate(
|
||||||
|
0,
|
||||||
|
extendTopForCategories(),
|
||||||
|
expanding);
|
||||||
|
const auto inner = outer.marginsRemoved(extents);
|
||||||
|
_shadowTop = inner.y() + categories;
|
||||||
|
_shadowSkip = (categories < radius)
|
||||||
|
? int(base::SafeRound(
|
||||||
|
radius - sqrt(categories * (2 * radius - categories))))
|
||||||
|
: 0;
|
||||||
|
return {
|
||||||
|
.categories = QRect(inner.x(), inner.y(), inner.width(), categories),
|
||||||
|
.list = inner.marginsRemoved({ 0, categories, 0, 0 }),
|
||||||
|
.radius = radius,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::paintStripWithoutExpand(QPainter &p) {
|
void Selector::paintStripWithoutExpand(QPainter &p) {
|
||||||
|
@ -317,6 +344,7 @@ void Selector::paintFadingExpandIcon(QPainter &p, float64 progress) {
|
||||||
QSize(_size, _size)
|
QSize(_size, _size)
|
||||||
).marginsRemoved({ sub, sub, sub, sub });
|
).marginsRemoved({ sub, sub, sub, sub });
|
||||||
p.drawImage(expandIconRect, _expandIconCache);
|
p.drawImage(expandIconRect, _expandIconCache);
|
||||||
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::paintExpanded(QPainter &p) {
|
void Selector::paintExpanded(QPainter &p) {
|
||||||
|
@ -360,7 +388,7 @@ void Selector::paintBubble(QPainter &p, int innerWidth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::paintEvent(QPaintEvent *e) {
|
void Selector::paintEvent(QPaintEvent *e) {
|
||||||
auto p = QPainter(this);
|
auto p = Painter(this);
|
||||||
if (_appearing) {
|
if (_appearing) {
|
||||||
paintAppearing(p);
|
paintAppearing(p);
|
||||||
} else if (!_expanded) {
|
} else if (!_expanded) {
|
||||||
|
@ -543,12 +571,17 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
|
||||||
inner.y(),
|
inner.y(),
|
||||||
inner.width(),
|
inner.width(),
|
||||||
_footer->height());
|
_footer->height());
|
||||||
|
_shadowTop = _outer.y();
|
||||||
|
_shadowSkip = (st::reactStripHeight / 2);
|
||||||
const auto shadow = Ui::CreateChild<Ui::PlainShadow>(this);
|
const auto shadow = Ui::CreateChild<Ui::PlainShadow>(this);
|
||||||
_footer->geometryValue() | rpl::start_with_next([=](QRect geometry) {
|
rpl::combine(
|
||||||
|
_shadowTop.value(),
|
||||||
|
_shadowSkip.value()
|
||||||
|
) | rpl::start_with_next([=](int top, int skip) {
|
||||||
shadow->setGeometry(
|
shadow->setGeometry(
|
||||||
geometry.x(),
|
inner.x() + skip,
|
||||||
geometry.y() + geometry.height(),
|
top,
|
||||||
geometry.width(),
|
inner.width() - 2 * skip,
|
||||||
st::lineWidth);
|
st::lineWidth);
|
||||||
}, shadow->lifetime());
|
}, shadow->lifetime());
|
||||||
shadow->show();
|
shadow->show();
|
||||||
|
@ -556,8 +589,8 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
|
||||||
const auto geometry = inner.marginsRemoved(
|
const auto geometry = inner.marginsRemoved(
|
||||||
st::reactPanelEmojiPan.margin);
|
st::reactPanelEmojiPan.margin);
|
||||||
_list->move(0, 0);
|
_list->move(0, 0);
|
||||||
_list->refreshEmoji();
|
|
||||||
_list->resizeToWidth(geometry.width());
|
_list->resizeToWidth(geometry.width());
|
||||||
|
_list->refreshEmoji();
|
||||||
_list->show();
|
_list->show();
|
||||||
|
|
||||||
const auto updateVisibleTopBottom = [=] {
|
const auto updateVisibleTopBottom = [=] {
|
||||||
|
|
|
@ -66,6 +66,12 @@ public:
|
||||||
private:
|
private:
|
||||||
static constexpr int kFramesCount = 32;
|
static constexpr int kFramesCount = 32;
|
||||||
|
|
||||||
|
struct ExpandingRects {
|
||||||
|
QRect categories;
|
||||||
|
QRect list;
|
||||||
|
float64 radius = 0.;
|
||||||
|
};
|
||||||
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void leaveEventHook(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
@ -74,8 +80,8 @@ private:
|
||||||
|
|
||||||
void paintAppearing(QPainter &p);
|
void paintAppearing(QPainter &p);
|
||||||
void paintCollapsed(QPainter &p);
|
void paintCollapsed(QPainter &p);
|
||||||
void paintExpanding(QPainter &p, float64 progress);
|
void paintExpanding(Painter &p, float64 progress);
|
||||||
void paintExpandingBg(QPainter &p, float64 progress);
|
ExpandingRects paintExpandingBg(QPainter &p, float64 progress);
|
||||||
void paintStripWithoutExpand(QPainter &p);
|
void paintStripWithoutExpand(QPainter &p);
|
||||||
void paintFadingExpandIcon(QPainter &p, float64 progress);
|
void paintFadingExpandIcon(QPainter &p, float64 progress);
|
||||||
void paintExpanded(QPainter &p);
|
void paintExpanded(QPainter &p);
|
||||||
|
@ -101,6 +107,8 @@ private:
|
||||||
Ui::ScrollArea *_scroll = nullptr;
|
Ui::ScrollArea *_scroll = nullptr;
|
||||||
ChatHelpers::EmojiListWidget *_list = nullptr;
|
ChatHelpers::EmojiListWidget *_list = nullptr;
|
||||||
ChatHelpers::StickersListFooter *_footer = nullptr;
|
ChatHelpers::StickersListFooter *_footer = nullptr;
|
||||||
|
rpl::variable<int> _shadowTop = 0;
|
||||||
|
rpl::variable<int> _shadowSkip = 0;
|
||||||
|
|
||||||
QImage _paintBuffer;
|
QImage _paintBuffer;
|
||||||
Ui::Animations::Simple _expanding;
|
Ui::Animations::Simple _expanding;
|
||||||
|
|
Loading…
Reference in New Issue