From b22e2ffe1d59ec83ad2448ee8d6ee26f97d424aa Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Jul 2021 18:29:13 +0300 Subject: [PATCH] Animate inline path thumbnails with sliding gradient. --- .../boxes/background_preview_box.cpp | 2 +- .../SourceFiles/boxes/sticker_set_box.cpp | 26 ++++++++++++++-- .../chat_helpers/field_autocomplete.cpp | 25 +++++++++++++++- .../chat_helpers/stickers_list_widget.cpp | 19 +++++++++++- .../chat_helpers/stickers_list_widget.h | 3 ++ .../chat_helpers/stickers_lottie.cpp | 30 +++++++++++++++++-- .../chat_helpers/stickers_lottie.h | 12 +++++++- .../admin_log/history_admin_log_inner.cpp | 11 +++++++ .../admin_log/history_admin_log_inner.h | 3 ++ .../history/history_inner_widget.cpp | 18 ++++++++++- .../history/history_inner_widget.h | 3 ++ .../history/view/history_view_element.cpp | 24 +++++++++++++-- .../history/view/history_view_element.h | 19 ++++++++++-- .../history/view/history_view_list_widget.cpp | 11 +++++++ .../history/view/history_view_list_widget.h | 3 ++ .../view/media/history_view_sticker.cpp | 12 +++++++- .../inline_bot_layout_internal.cpp | 20 +++++++++++-- .../inline_bots/inline_bot_layout_item.h | 11 +++++-- .../inline_bots/inline_results_inner.cpp | 7 +++++ .../inline_bots/inline_results_inner.h | 2 ++ .../settings/settings_privacy_controllers.cpp | 2 +- .../settings/settings_privacy_security.cpp | 3 +- .../support/support_autocomplete.cpp | 2 +- Telegram/SourceFiles/ui/image/image.cpp | 7 +++-- Telegram/lib_ui | 2 +- docs/building-msvc-x64.md | 10 +++---- docs/building-msvc.md | 10 +++---- 27 files changed, 258 insertions(+), 39 deletions(-) diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index cf1af6627..d5ddf7332 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -399,7 +399,7 @@ BackgroundPreviewBox::BackgroundPreviewBox( QWidget*, not_null controller, const Data::WallPaper &paper) -: SimpleElementDelegate(controller) +: SimpleElementDelegate(controller, [=] { update(); }) , _controller(controller) , _text1(GenerateTextItem( delegate(), diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 8cdddb330..9b7820f96 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/image/image.h" #include "ui/image/image_location_factory.h" #include "ui/text/text_utilities.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/emoji_config.h" #include "ui/toast/toast.h" #include "ui/widgets/popup_menu.h" @@ -128,6 +129,8 @@ private: TimeId _setInstallDate = TimeId(0); ImageWithLocation _setThumbnail; + const std::unique_ptr _pathGradient; + MTPInputStickerSet _input; mtpRequestId _installRequest = 0; @@ -328,6 +331,10 @@ StickerSetBox::Inner::Inner( : RpWidget(parent) , _controller(controller) , _api(&_controller->session().mtp()) +, _pathGradient(std::make_unique( + st::windowBgRipple, + st::windowBgOver, + [=] { update(); })) , _input(set) , _previewTimer([=] { showPreview(); }) { set.match([&](const MTPDinputStickerSetID &data) { @@ -652,6 +659,8 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) { + ((_elements.size() % kStickersPanelPerRow) ? 1 : 0); int32 from = qFloor(e->rect().top() / st::stickersSize.height()), to = qFloor(e->rect().bottom() / st::stickersSize.height()) + 1; + _pathGradient->startFrame(0, width(), width() / 2); + for (int32 i = from; i < to; ++i) { for (int32 j = 0; j < kStickersPanelPerRow; ++j) { int32 index = i * kStickersPanelPerRow + j; @@ -747,7 +756,8 @@ void StickerSetBox::Inner::paintSticker( const auto &media = element.documentMedia; media->checkStickerSmall(); - if (document->sticker()->animated + const auto isAnimated = document->sticker()->animated; + if (isAnimated && !element.animated && media->loaded()) { const_cast(this)->setupLottie(index); @@ -755,7 +765,7 @@ void StickerSetBox::Inner::paintSticker( auto w = 1; auto h = 1; - if (element.animated && !document->dimensions.isEmpty()) { + if (isAnimated && !document->dimensions.isEmpty()) { const auto request = Lottie::FrameRequest{ boundingBoxSize() * cIntRetinaFactor() }; const auto size = request.size(document->dimensions, true) / cIntRetinaFactor(); w = std::max(size.width(), 1); @@ -767,6 +777,16 @@ void StickerSetBox::Inner::paintSticker( h = std::max(qRound(coef * document->dimensions.height()), 1); } QPoint ppos = position + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2); + + + ChatHelpers::PaintStickerThumbnailPath( + p, + media.get(), + QRect(ppos, QSize(w, h)), + _pathGradient.get()); + return; AssertIsDebug(); + + if (element.animated && element.animated->ready()) { const auto frame = element.animated->frame(); p.drawImage( @@ -784,7 +804,7 @@ void StickerSetBox::Inner::paintSticker( p, media.get(), QRect(ppos, QSize(w, h)), - st::windowBgRipple->c); + _pathGradient.get()); } } diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index 791192c98..6b40e3bab 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/scroll_area.h" #include "ui/widgets/input_fields.h" #include "ui/image/image.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/ui_utility.h" #include "ui/cached_round_corners.h" #include "base/unixtime.h" @@ -125,6 +126,8 @@ private: bool _isOneColumn = false; + const std::unique_ptr _pathGradient; + Fn _sendMenuType; rpl::event_stream _mentionChosen; @@ -738,6 +741,10 @@ FieldAutocomplete::Inner::Inner( , _hrows(hrows) , _brows(brows) , _srows(srows) +, _pathGradient(std::make_unique( + st::windowBgRipple, + st::windowBgOver, + [=] { update(); })) , _previewTimer([=] { showPreview(); }) { controller->session().downloaderTaskFinished( ) | rpl::start_with_next([=] { @@ -770,6 +777,11 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) { - st::defaultScrollArea.width; if (!_srows->empty()) { + _pathGradient->startFrame( + 0, + width(), + std::min(st::msgMaxWidth / 2, width() / 2)); + int32 rows = rowscount(_srows->size(), _stickersPerRow); int32 fromrow = floorclamp(r.y() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows); int32 torow = ceilclamp(r.y() + r.height() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows); @@ -815,6 +827,17 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) { w = std::max(qRound(coef * document->dimensions.width()), 1); h = std::max(qRound(coef * document->dimensions.height()), 1); } + + + QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2); + ChatHelpers::PaintStickerThumbnailPath( + p, + media.get(), + QRect(ppos, QSize(w, h)), + _pathGradient.get()); + continue; AssertIsDebug(); + + if (sticker.animated && sticker.animated->ready()) { const auto frame = sticker.animated->frame(); const auto size = frame.size() / cIntRetinaFactor(); @@ -838,7 +861,7 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) { p, media.get(), QRect(ppos, QSize(w, h)), - st::windowBgRipple->c); + _pathGradient.get()); } } } diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 19f51500d..2ba62c80c 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/popup_menu.h" #include "ui/effects/animations.h" #include "ui/effects/ripple_animation.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/image/image.h" #include "ui/cached_round_corners.h" #include "lottie/lottie_multi_player.h" @@ -899,6 +900,10 @@ StickersListWidget::StickersListWidget( : Inner(parent, controller) , _api(&controller->session().mtp()) , _section(Section::Stickers) +, _pathGradient(std::make_unique( + st::windowBgRipple, + st::windowBgOver, + [=] { update(); })) , _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft) , _addText(tr::lng_stickers_featured_add(tr::now).toUpper()) , _addWidth(st::stickersTrendingAdd.font->width(_addText)) @@ -1531,6 +1536,8 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) { toColumn = _columnCount - toColumn; } + _pathGradient->startFrame(0, width(), width() / 2); + auto &sets = shownSets(); auto selectedSticker = std::get_if(&_selected); auto selectedButton = std::get_if(!v::is_null(_pressed) @@ -1889,6 +1896,16 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section, h = std::max(qRound(coef * document->dimensions.height()), 1); } auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2); + + + PaintStickerThumbnailPath( + p, + media.get(), + QRect(ppos, QSize{ w, h }), + _pathGradient.get()); + return; AssertIsDebug(); + + if (sticker.animated && sticker.animated->ready()) { auto request = Lottie::FrameRequest(); request.box = boundingBoxSize() * cIntRetinaFactor(); @@ -1923,7 +1940,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section, p, media.get(), QRect(ppos, QSize{ w, h }), - st::windowBgRipple->c); + _pathGradient.get()); } } diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h index b996f0214..f4684e361 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h @@ -25,6 +25,7 @@ class LinkButton; class PopupMenu; class RippleAnimation; class BoxContent; +class PathShiftGradient; } // namespace Ui namespace Lottie { @@ -361,6 +362,8 @@ private: OverState _pressed; QPoint _lastMousePosition; + const std::unique_ptr _pathGradient; + Ui::Text::String _megagroupSetAbout; QString _megagroupSetButtonText; int _megagroupSetButtonTextWidth = 0; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp b/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp index 98363781a..c10c5e95c 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_file_origin.h" #include "storage/cache/storage_cache_database.h" +#include "ui/effects/path_shift_gradient.h" #include "main/main_session.h" namespace ChatHelpers { @@ -192,17 +193,25 @@ bool PaintStickerThumbnailPath( QPainter &p, not_null media, QRect target, - QColor fg) { + QLinearGradient *gradient) { const auto &path = media->thumbnailPath(); const auto dimensions = media->owner()->dimensions; - if (path.isEmpty() || dimensions.isEmpty()) { + if (path.isEmpty() || dimensions.isEmpty() || target.isEmpty()) { return false; } p.save(); auto hq = PainterHighQualityEnabler(p); - p.setBrush(fg); p.setPen(Qt::NoPen); p.translate(target.topLeft()); + if (gradient) { + const auto scale = dimensions.width() / float64(target.width()); + const auto shift = p.worldTransform().dx(); + gradient->setStart((gradient->start().x() - shift) * scale, 0); + gradient->setFinalStop( + (gradient->finalStop().x() - shift) * scale, + 0); + p.setBrush(*gradient); + } p.scale( target.width() / float64(dimensions.width()), target.height() / float64(dimensions.height())); @@ -211,4 +220,19 @@ bool PaintStickerThumbnailPath( return true; } +bool PaintStickerThumbnailPath( + QPainter &p, + not_null media, + QRect target, + not_null gradient) { + return gradient->paint([&](const Ui::PathShiftGradient::Background &bg) { + if (const auto color = std::get_if(&bg)) { + p.setBrush(*color); + return PaintStickerThumbnailPath(p, media, target); + } + const auto gradient = v::get(bg); + return PaintStickerThumbnailPath(p, media, target, gradient); + }); +} + } // namespace ChatHelpers diff --git a/Telegram/SourceFiles/chat_helpers/stickers_lottie.h b/Telegram/SourceFiles/chat_helpers/stickers_lottie.h index 700a9f8f4..546d4e4a1 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_lottie.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_lottie.h @@ -26,6 +26,10 @@ namespace Main { class Session; } // namespace Main +namespace Ui { +class PathShiftGradient; +} // namespace Ui + namespace Data { class DocumentMedia; class StickersSetThumbnailView; @@ -75,6 +79,12 @@ bool PaintStickerThumbnailPath( QPainter &p, not_null media, QRect target, - QColor fg); + QLinearGradient *gradient = nullptr); + +bool PaintStickerThumbnailPath( + QPainter &p, + not_null media, + QRect target, + not_null gradient); } // namespace ChatHelpers diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index abe2aff0a..635f17c26 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/image/image.h" #include "ui/text/text_utilities.h" #include "ui/inactive_press.h" +#include "ui/effects/path_shift_gradient.h" #include "core/file_utilities.h" #include "lang/lang_keys.h" #include "boxes/peers/edit_participant_box.h" @@ -234,6 +235,7 @@ InnerWidget::InnerWidget( , _channel(channel) , _history(channel->owner().history(channel)) , _api(&_channel->session().mtp()) +, _pathGradient(HistoryView::MakePathShiftGradient([=] { update(); })) , _scrollDateCheck([=] { scrollDateCheck(); }) , _emptyText( st::historyAdminLogEmptyWidth @@ -651,6 +653,10 @@ bool InnerWidget::elementIsChatWide() { return _controller->adaptive().isChatWide(); } +not_null InnerWidget::elementPathShiftGradient() { + return _pathGradient.get(); +} + void InnerWidget::saveState(not_null memento) { memento->setFilter(std::move(_filter)); memento->setAdmins(std::move(_admins)); @@ -892,6 +898,11 @@ void InnerWidget::paintEvent(QPaintEvent *e) { if (_items.empty() && _upLoaded && _downLoaded) { paintEmpty(p); } else { + _pathGradient->startFrame( + 0, + width(), + std::min(st::msgMaxWidth / 2, width() / 2)); + auto begin = std::rbegin(_items), end = std::rend(_items); auto from = std::lower_bound(begin, end, clip.top(), [this](auto &elem, int top) { return this->itemTop(elem) + elem->height() <= top; diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h index 85b24efff..c10296a00 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h @@ -129,6 +129,7 @@ public: const FullMsgId &context) override; void elementHandleViaClick(not_null bot) override; bool elementIsChatWide() override; + not_null elementPathShiftGradient() override; ~InnerWidget(); @@ -248,6 +249,8 @@ private: const not_null _history; MTP::Sender _api; + const std::unique_ptr _pathGradient; + std::vector _items; std::set _eventIds; std::map, not_null> _itemsByData; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 06f498443..113161c7e 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/popup_menu.h" #include "ui/image/image.h" #include "ui/toast/toast.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/text/text_options.h" #include "ui/boxes/report_box.h" #include "ui/layers/generic_box.h" @@ -156,6 +157,7 @@ HistoryInner::HistoryInner( , _peer(history->peer) , _history(history) , _migrated(history->migrateFrom()) +, _pathGradient(HistoryView::MakePathShiftGradient([=] { update(); })) , _scrollDateCheck([this] { scrollDateCheck(); }) , _scrollDateHideTimer([this] { scrollDateHideByTimer(); }) { Instance = this; @@ -551,6 +553,11 @@ void HistoryInner::paintEvent(QPaintEvent *e) { _userpicsCache.clear(); }); + _pathGradient->startFrame( + 0, + width(), + std::min(st::msgMaxWidth / 2, width() / 2)); + Painter p(this); auto clip = e->rect(); auto ms = crl::now(); @@ -2623,6 +2630,10 @@ bool HistoryInner::elementIsChatWide() { return _isChatWide; } +not_null HistoryInner::elementPathShiftGradient() { + return _pathGradient.get(); +} + auto HistoryInner::getSelectionState() const -> HistoryView::TopBarWidget::SelectedState { auto result = HistoryView::TopBarWidget::SelectedState {}; @@ -3412,7 +3423,7 @@ void HistoryInner::onParentGeometryChanged() { } not_null HistoryInner::ElementDelegate() { - class Result : public HistoryView::ElementDelegate { + class Result final : public HistoryView::ElementDelegate { public: HistoryView::Context elementContext() override { return HistoryView::Context::History; @@ -3521,6 +3532,11 @@ not_null HistoryInner::ElementDelegate() { ? Instance->elementIsChatWide() : false; } + not_null elementPathShiftGradient() override { + Expects(Instance != nullptr); + + return Instance->elementPathShiftGradient(); + } }; static Result result; diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 39952148d..67eb4206b 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -36,6 +36,7 @@ class SessionController; namespace Ui { class PopupMenu; enum class ReportReason; +class PathShiftGradient; } // namespace Ui class HistoryWidget; @@ -105,6 +106,7 @@ public: const FullMsgId &context); void elementHandleViaClick(not_null bot); bool elementIsChatWide(); + not_null elementPathShiftGradient(); void updateBotInfo(bool recount = true); @@ -365,6 +367,7 @@ private: SelectedItems _selected; std::optional _chooseForReportReason; + const std::unique_ptr _pathGradient; bool _isChatWide = false; base::flat_set> _animatedStickersPlayed; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 2e94df4e6..8e6d804b3 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "chat_helpers/stickers_emoji_pack.h" #include "window/window_session_controller.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/toast/toast.h" #include "ui/toasts/common_toasts.h" #include "data/data_session.h" @@ -60,11 +61,23 @@ bool IsAttachedToPreviousInSavedMessages( } // namespace -SimpleElementDelegate::SimpleElementDelegate( - not_null controller) -: _controller(controller) { +std::unique_ptr MakePathShiftGradient( + Fn update) { + return std::make_unique( + st::msgServiceBg, + st::msgServiceBgSelected, + std::move(update)); } +SimpleElementDelegate::SimpleElementDelegate( + not_null controller, + Fn update) +: _controller(controller) +, _pathGradient(MakePathShiftGradient(std::move(update))) { +} + +SimpleElementDelegate::~SimpleElementDelegate() = default; + std::unique_ptr SimpleElementDelegate::elementCreate( not_null message, Element *replacing) { @@ -151,6 +164,11 @@ bool SimpleElementDelegate::elementIsChatWide() { return false; } +auto SimpleElementDelegate::elementPathShiftGradient() +-> not_null { + return _pathGradient.get(); +} + TextSelection UnshiftItemSelection( TextSelection selection, uint16 byLength) { diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index d7a2f6a45..dc6045d80 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -22,6 +22,10 @@ namespace Window { class SessionController; } // namespace Window +namespace Ui { +class PathShiftGradient; +} // namespace Ui + namespace HistoryView { enum class PointState : char; @@ -79,13 +83,22 @@ public: const FullMsgId &context) = 0; virtual void elementHandleViaClick(not_null bot) = 0; virtual bool elementIsChatWide() = 0; + virtual not_null elementPathShiftGradient() = 0; + + virtual ~ElementDelegate() { + } }; +[[nodiscard]] std::unique_ptr MakePathShiftGradient( + Fn update); + class SimpleElementDelegate : public ElementDelegate { public: - explicit SimpleElementDelegate( - not_null controller); + SimpleElementDelegate( + not_null controller, + Fn update); + ~SimpleElementDelegate(); std::unique_ptr elementCreate( not_null message, @@ -124,9 +137,11 @@ public: const FullMsgId &context) override; void elementHandleViaClick(not_null bot) override; bool elementIsChatWide() override; + not_null elementPathShiftGradient() override; private: const not_null _controller; + const std::unique_ptr _pathGradient; }; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 8b2747fd2..8ca77a1da 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/popup_menu.h" #include "ui/toast/toast.h" #include "ui/inactive_press.h" +#include "ui/effects/path_shift_gradient.h" #include "lang/lang_keys.h" #include "boxes/peers/edit_participant_box.h" #include "data/data_session.h" @@ -251,6 +252,7 @@ ListWidget::ListWidget( , _controller(controller) , _context(_delegate->listContext()) , _itemAverageHeight(itemMinimalHeight()) +, _pathGradient(MakePathShiftGradient([=] { update(); })) , _scrollDateCheck([this] { scrollDateCheck(); }) , _applyUpdatedScrollState([this] { applyUpdatedScrollState(); }) , _selectEnabled(_delegate->listAllowsMultiSelect()) @@ -1351,6 +1353,10 @@ bool ListWidget::elementIsChatWide() { return _isChatWide; } +not_null ListWidget::elementPathShiftGradient() { + return _pathGradient.get(); +} + void ListWidget::saveState(not_null memento) { memento->setAroundPosition(_aroundPosition); auto state = countScrollState(); @@ -1499,6 +1505,11 @@ void ListWidget::paintEvent(QPaintEvent *e) { Painter p(this); + _pathGradient->startFrame( + 0, + width(), + std::min(st::msgMaxWidth / 2, width() / 2)); + auto ms = crl::now(); auto clip = e->rect(); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index a9a04bf43..0c26dd368 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -253,6 +253,7 @@ public: const FullMsgId &context) override; void elementHandleViaClick(not_null bot) override; bool elementIsChatWide() override; + not_null elementPathShiftGradient() override; ~ListWidget(); @@ -509,6 +510,8 @@ private: not_null, std::shared_ptr> _userpics, _userpicsCache; + const std::unique_ptr _pathGradient; + int _minHeight = 0; int _visibleTop = 0; int _visibleBottom = 0; diff --git a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp index 71704f14e..7bbe58a7a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_sticker.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_cursor_state.h" #include "history/view/media/history_view_media_common.h" #include "ui/image/image.h" +#include "ui/effects/path_shift_gradient.h" #include "ui/emoji_config.h" #include "core/application.h" #include "core/core_settings.h" @@ -232,11 +233,20 @@ bool Sticker::paintPixmap(Painter &p, const QRect &r, bool selected) { } void Sticker::paintPath(Painter &p, const QRect &r, bool selected) { + const auto pathGradient = _parent->delegate()->elementPathShiftGradient(); + if (selected) { + pathGradient->overrideColors( + st::msgServiceBgSelected, + st::msgServiceBg); + } else { + pathGradient->clearOverridenColors(); + } + p.setBrush(selected ? st::msgServiceBgSelected : st::msgServiceBg); ChatHelpers::PaintStickerThumbnailPath( p, _dataMedia.get(), r, - (selected ? st::msgServiceBgSelected : st::msgServiceBg)->c); + pathGradient); } QPixmap Sticker::paintedPixmap(bool selected) const { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index 02c6f2932..6dc13d9f3 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -468,6 +468,22 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context) p.setOpacity(1); } + if (context->pathGradient) { + const auto thumbSize = getThumbSize(); + const auto w = thumbSize.width(); + const auto h = thumbSize.height(); + ChatHelpers::PaintStickerThumbnailPath( + p, + _dataMedia.get(), + QRect( + (st::stickerPanSize.width() - w) / 2, + (st::stickerPanSize.height() - h) / 2, + w, + h), + context->pathGradient); + } + return; AssertIsDebug(); + prepareThumbnail(); if (_lottie && _lottie->ready()) { const auto frame = _lottie->frame(); @@ -483,7 +499,7 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context) int w = _thumb.width() / cIntRetinaFactor(), h = _thumb.height() / cIntRetinaFactor(); QPoint pos = QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2); p.drawPixmap(pos, _thumb); - } else { + } else if (context->pathGradient) { const auto thumbSize = getThumbSize(); const auto w = thumbSize.width(); const auto h = thumbSize.height(); @@ -495,7 +511,7 @@ void Sticker::paint(Painter &p, const QRect &clip, const PaintContext *context) (st::stickerPanSize.height() - h) / 2, w, h), - st::windowBgRipple->c); + context->pathGradient); } } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h index a2ada30ff..641ceea2f 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h @@ -12,6 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class Image; +namespace Ui { +class PathShiftGradient; +} // namespace Ui + namespace Data { class CloudImageView; } // namespace Data @@ -27,11 +31,12 @@ class ItemBase; class PaintContext : public PaintContextBase { public: PaintContext(crl::time ms, bool selecting, bool paused, bool lastRow) - : PaintContextBase(ms, selecting) - , paused(paused) - , lastRow(lastRow) { + : PaintContextBase(ms, selecting) + , paused(paused) + , lastRow(lastRow) { } bool paused, lastRow; + Ui::PathShiftGradient *pathGradient = nullptr; }; diff --git a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp index 9055f493a..899775afc 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/popup_menu.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" +#include "ui/effects/path_shift_gradient.h" #include "history/view/history_view_cursor_state.h" #include "styles/style_chat_helpers.h" @@ -36,6 +37,10 @@ Inner::Inner( not_null controller) : RpWidget(parent) , _controller(controller) +, _pathGradient(std::make_unique( + st::windowBgRipple, + st::windowBgOver, + [=] { update(); })) , _updateInlineItems([=] { updateInlineItems(); }) , _previewTimer([=] { showPreview(); }) { resize(st::emojiPanWidth - st::emojiScroll.width - st::roundRadiusSmall, st::inlineResultsMinHeight); @@ -172,6 +177,8 @@ void Inner::paintInlineItems(Painter &p, const QRect &r) { } auto gifPaused = _controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults); InlineBots::Layout::PaintContext context(crl::now(), false, gifPaused, false); + context.pathGradient = _pathGradient.get(); + context.pathGradient->startFrame(0, width(), width() / 2); auto top = st::stickerPanPadding; if (_switchPmButton) { diff --git a/Telegram/SourceFiles/inline_bots/inline_results_inner.h b/Telegram/SourceFiles/inline_bots/inline_results_inner.h index cf54bf8a7..e794935fe 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_inner.h +++ b/Telegram/SourceFiles/inline_bots/inline_results_inner.h @@ -29,6 +29,7 @@ class RoundButton; class FlatLabel; class RippleAnimation; class PopupMenu; +class PathShiftGradient; } // namespace Ui namespace Window { @@ -154,6 +155,7 @@ private: bool open); not_null _controller; + const std::unique_ptr _pathGradient; int _visibleTop = 0; int _visibleBottom = 0; diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index 1b7a25efa..0822464bf 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -691,7 +691,7 @@ rpl::producer CallsPeer2PeerPrivacyController::exceptionsDescription() ForwardsPrivacyController::ForwardsPrivacyController( not_null controller) -: SimpleElementDelegate(controller) +: SimpleElementDelegate(controller, [] {}) , _controller(controller) { } diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 9339a7958..d588e48ef 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -173,7 +173,8 @@ void SetupPrivacy( add( tr::lng_settings_forwards_privacy(), Key::Forwards, - [=] { return std::make_unique(controller); }); + [=] { return std::make_unique( + controller); }); add( tr::lng_settings_profile_photo_privacy(), Key::ProfilePhoto, diff --git a/Telegram/SourceFiles/support/support_autocomplete.cpp b/Telegram/SourceFiles/support/support_autocomplete.cpp index fdf7c105d..2ed5bf4f4 100644 --- a/Telegram/SourceFiles/support/support_autocomplete.cpp +++ b/Telegram/SourceFiles/support/support_autocomplete.cpp @@ -508,7 +508,7 @@ ConfirmContactBox::ConfirmContactBox( not_null history, const Contact &data, Fn submit) -: SimpleElementDelegate(controller) +: SimpleElementDelegate(controller, [=] { update(); }) , _comment(GenerateCommentItem(this, history, data)) , _contact(GenerateContactItem(this, history, data)) , _submit(submit) { diff --git a/Telegram/SourceFiles/ui/image/image.cpp b/Telegram/SourceFiles/ui/image/image.cpp index 6a8fab40f..467425e8b 100644 --- a/Telegram/SourceFiles/ui/image/image.cpp +++ b/Telegram/SourceFiles/ui/image/image.cpp @@ -108,9 +108,10 @@ QByteArray ExpandPathInlineBytes(const QByteArray &bytes) { } else if (c >= 64) { result.append('-'); } - char buffer[3] = { 0 }; - std::to_chars(buffer, buffer + 3, (c & 63)); - result.append(buffer); + //char buffer[3] = { 0 }; // Unavailable on macOS < 10.15. + //std::to_chars(buffer, buffer + 3, (c & 63)); + //result.append(buffer); + result.append(QByteArray::number(c & 63)); } } result.append('z'); diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 3b3413e61..baf4d8086 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 3b3413e618864a9b1bec40911ca713f68726b177 +Subproject commit baf4d80867e719a6fc0ae0cefd192ce061c3b879 diff --git a/docs/building-msvc-x64.md b/docs/building-msvc-x64.md index 74a90db5a..e3420bb5b 100644 --- a/docs/building-msvc-x64.md +++ b/docs/building-msvc-x64.md @@ -34,7 +34,7 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** cd ThirdParty git clone https://github.com/desktop-app/patches.git cd patches - git checkout 7f8a282 + git checkout d051cbc cd ../ git clone https://chromium.googlesource.com/external/gyp cd gyp @@ -65,7 +65,7 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** git clone https://github.com/desktop-app/patches.git cd patches - git checkout 7f8a282 + git checkout d051cbc cd .. git clone https://github.com/desktop-app/lzma.git @@ -178,11 +178,11 @@ Open **x64 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** python scripts/bootstrap.py gclient sync - git apply ../patches/angle.patch + for /r %i in (..\patches\angle\*) do git apply %i - gn gen out/Debug --args="is_component_build = false is_debug = true target_cpu = \"x64\" is_clang = false enable_iterator_debugging = true angle_enable_swiftshader=false angle_enable_vulkan=false" + gn gen out/Debug --args="is_component_build=false is_debug=true target_cpu=\"x64\" is_clang=false enable_iterator_debugging=true angle_enable_swiftshader=false angle_enable_vulkan=false angle_default_d3d9=true" - gn gen out/Release --args="is_component_build = false is_debug = false target_cpu = \"x64\" is_clang = false enable_iterator_debugging = false angle_enable_swiftshader=false angle_enable_vulkan=false" + gn gen out/Release --args="is_component_build=false is_debug=false target_cpu=\"x64\" is_clang=false enable_iterator_debugging=false angle_enable_swiftshader=false angle_enable_vulkan=false angle_default_d3d9=true" ninja -C out/Debug libANGLE_static libGLESv2_static libEGL_static ninja -C out/Release libANGLE_static libGLESv2_static libEGL_static diff --git a/docs/building-msvc.md b/docs/building-msvc.md index a9c2f40bf..35ed47b09 100644 --- a/docs/building-msvc.md +++ b/docs/building-msvc.md @@ -34,7 +34,7 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** cd ThirdParty git clone https://github.com/desktop-app/patches.git cd patches - git checkout 7f8a282 + git checkout d051cbc cd ../ git clone https://chromium.googlesource.com/external/gyp cd gyp @@ -65,7 +65,7 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** git clone https://github.com/desktop-app/patches.git cd patches - git checkout 7f8a282 + git checkout d051cbc cd .. git clone https://github.com/desktop-app/lzma.git @@ -178,11 +178,11 @@ Open **x86 Native Tools Command Prompt for VS 2019.bat**, go to ***BuildPath*** python scripts/bootstrap.py gclient sync - git apply ../patches/angle.patch + for /r %i in (..\patches\angle\*) do git apply %i - gn gen out/Debug --args="is_component_build = false is_debug = true target_cpu = \"x86\" is_clang = false enable_iterator_debugging = true angle_enable_swiftshader=false angle_enable_vulkan=false" + gn gen out/Debug --args="is_component_build=false is_debug=true target_cpu=\"x86\" is_clang=false enable_iterator_debugging=true angle_enable_swiftshader=false angle_enable_vulkan=false angle_default_d3d9=true" - gn gen out/Release --args="is_component_build = false is_debug = false target_cpu = \"x86\" is_clang = false enable_iterator_debugging = false angle_enable_swiftshader=false angle_enable_vulkan=false" + gn gen out/Release --args="is_component_build=false is_debug=false target_cpu=\"x86\" is_clang=false enable_iterator_debugging=false angle_enable_swiftshader=false angle_enable_vulkan=false angle_default_d3d9=true" ninja -C out/Debug libANGLE_static libGLESv2_static libEGL_static ninja -C out/Release libANGLE_static libGLESv2_static libEGL_static