mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 16:13:46 +08:00
Added slide animation for chats filter switching.
This commit is contained in:
@@ -212,6 +212,7 @@ dialogsSpeakingDenominator: 8.;
|
||||
dialogsImportantBarHeight: 37px;
|
||||
|
||||
dialogsWidthDuration: universalDuration;
|
||||
dialogsFilterSwipeSlideDuration: 140;
|
||||
dialogsTextWidthMin: 150px;
|
||||
|
||||
dialogsTextPalette: TextPalette(defaultTextPalette) {
|
||||
|
||||
@@ -579,11 +579,6 @@ InnerWidget::InnerWidget(
|
||||
update(next);
|
||||
}, lifetime());
|
||||
|
||||
_controller->activeChatsFilter(
|
||||
) | rpl::on_next([=](FilterId filterId) {
|
||||
switchToFilter(filterId);
|
||||
}, lifetime());
|
||||
|
||||
_controller->window().widget()->globalForceClicks(
|
||||
) | rpl::on_next([=](QPoint globalPosition) {
|
||||
processGlobalForceClick(globalPosition);
|
||||
@@ -5596,8 +5591,8 @@ void InnerWidget::switchToFilter(FilterId filterId) {
|
||||
const auto skip = found
|
||||
// Don't save a scroll state for very flexible chat filters.
|
||||
&& (filterIt->flags() & (Data::ChatFilter::Flag::NoRead));
|
||||
if (!skip) {
|
||||
restoreChatsFilterScrollState(filterId);
|
||||
if (skip || !restoreChatsFilterScrollState(filterId)) {
|
||||
jumpToTop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5610,11 +5605,13 @@ void InnerWidget::saveChatsFilterScrollState(FilterId filterId) {
|
||||
_chatsFilterScrollStates[filterId] = -y();
|
||||
}
|
||||
|
||||
void InnerWidget::restoreChatsFilterScrollState(FilterId filterId) {
|
||||
bool InnerWidget::restoreChatsFilterScrollState(FilterId filterId) {
|
||||
const auto it = _chatsFilterScrollStates.find(filterId);
|
||||
if (it != end(_chatsFilterScrollStates)) {
|
||||
_mustScrollTo.fire({ std::max(it->second, 0), -1 });
|
||||
if (it == end(_chatsFilterScrollStates)) {
|
||||
return false;
|
||||
}
|
||||
_mustScrollTo.fire({ std::max(it->second, 0), -1 });
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage *InnerWidget::cacheChatsFilterTag(
|
||||
|
||||
@@ -147,6 +147,7 @@ public:
|
||||
void peerSearchReceived(Api::PeerSearchResult result);
|
||||
|
||||
[[nodiscard]] FilterId filterId() const;
|
||||
void switchToFilter(FilterId filterId);
|
||||
|
||||
void clearSelection();
|
||||
|
||||
@@ -340,7 +341,6 @@ private:
|
||||
void refreshWithCollapsedRows(bool toTop = false);
|
||||
bool needCollapsedRowsRefresh() const;
|
||||
bool chooseCollapsedRow(Qt::KeyboardModifiers modifiers);
|
||||
void switchToFilter(FilterId filterId);
|
||||
bool chooseHashtag();
|
||||
ChosenRow computeChosenRow() const;
|
||||
bool isRowActive(not_null<Row*> row, const RowDescriptor &entry) const;
|
||||
@@ -609,7 +609,7 @@ private:
|
||||
[[nodiscard]] bool hasChatTypeFilter() const;
|
||||
|
||||
void saveChatsFilterScrollState(FilterId filterId);
|
||||
void restoreChatsFilterScrollState(FilterId filterId);
|
||||
bool restoreChatsFilterScrollState(FilterId filterId);
|
||||
|
||||
[[nodiscard]] not_null<Ui::QuickActionContext*> ensureQuickAction(
|
||||
int64 key);
|
||||
|
||||
@@ -41,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/effects/radial_animation.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/slide_animation.h"
|
||||
#include "ui/chat/requests_bar.h"
|
||||
#include "ui/chat/group_call_bar.h"
|
||||
#include "ui/chat/more_chats_bar.h"
|
||||
@@ -447,6 +448,10 @@ Widget::Widget(
|
||||
_childListPeerId.value(),
|
||||
_childListShown.value(),
|
||||
makeChildListShown)));
|
||||
controller->activeChatsFilter(
|
||||
) | rpl::on_next([=](FilterId id) {
|
||||
switchToChatsFilter(id);
|
||||
}, lifetime());
|
||||
rpl::combine(
|
||||
_scroll->heightValue(),
|
||||
_topBarSuggestionHeightChanged.events_starting_with(0)
|
||||
@@ -953,7 +958,9 @@ void Widget::setupSwipeBack() {
|
||||
if (CheckAndJumpToNearChatsFilter(controller(), next, false)) {
|
||||
return Ui::Controls::DefaultSwipeBackHandlerFinishData([=] {
|
||||
_swipeBackData = {};
|
||||
_chatsFilterSwipeSwitch = true;
|
||||
CheckAndJumpToNearChatsFilter(controller(), next, true);
|
||||
_chatsFilterSwipeSwitch = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2052,9 +2059,10 @@ void Widget::toggleFiltersMenu(bool enabled) {
|
||||
_chatFilters.get(),
|
||||
&session(),
|
||||
[this](FilterId id) {
|
||||
_scroll->scrollToY(0);
|
||||
if (controller()->activeChatsFilterCurrent() != id) {
|
||||
controller()->setActiveChatsFilter(id);
|
||||
} else {
|
||||
_scroll->scrollToY(0);
|
||||
}
|
||||
},
|
||||
Window::GifPauseReason::Any,
|
||||
@@ -2246,6 +2254,7 @@ void Widget::changeOpenedSubsection(
|
||||
if (isHidden()) {
|
||||
animated = anim::type::instant;
|
||||
}
|
||||
_chatsFilterSlideCanvas = nullptr;
|
||||
auto oldContentCache = QPixmap();
|
||||
const auto showDirection = fromRight
|
||||
? Window::SlideDirection::FromRight
|
||||
@@ -2519,6 +2528,84 @@ void Widget::showSearchInTopBar(anim::type animated) {
|
||||
updateForceDisplayWide();
|
||||
}
|
||||
|
||||
void Widget::switchToChatsFilter(FilterId id) {
|
||||
const auto was = _inner->filterId();
|
||||
const auto animated = (was != id)
|
||||
&& !isHidden()
|
||||
&& !_showAnimation
|
||||
&& (_chatsFilterSwipeSwitch
|
||||
|| (_chatFilters && !_chatFilters->isHidden()));
|
||||
if (!animated) {
|
||||
_inner->switchToFilter(id);
|
||||
return;
|
||||
}
|
||||
const auto &list = session().data().chatsFilters().list();
|
||||
const auto indexOf = [&](FilterId filterId) {
|
||||
return int(ranges::find(list, filterId, &Data::ChatFilter::id)
|
||||
- begin(list));
|
||||
};
|
||||
const auto slideLeft = (indexOf(id) < indexOf(was));
|
||||
const auto duration = _chatsFilterSwipeSwitch
|
||||
? st::dialogsFilterSwipeSlideDuration
|
||||
: st::slideDuration;
|
||||
_chatsFilterSlideCanvas = nullptr;
|
||||
auto wasCache = grabForChatsFilterSlide();
|
||||
_inner->switchToFilter(id);
|
||||
if (_inner->filterId() == was) {
|
||||
return;
|
||||
}
|
||||
startChatsFilterSlide(
|
||||
std::move(wasCache),
|
||||
grabForChatsFilterSlide(),
|
||||
slideLeft,
|
||||
duration);
|
||||
}
|
||||
|
||||
QPixmap Widget::grabForChatsFilterSlide() {
|
||||
const auto hidden = _scrollToTop->isHidden();
|
||||
if (!hidden) {
|
||||
_scrollToTop->hide();
|
||||
}
|
||||
auto result = Ui::GrabOpaque(
|
||||
_scroll.data(),
|
||||
_scroll->rect(),
|
||||
st::dialogsBg->c);
|
||||
if (!hidden) {
|
||||
_scrollToTop->show();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Widget::startChatsFilterSlide(
|
||||
QPixmap wasCache,
|
||||
QPixmap nowCache,
|
||||
bool slideLeft,
|
||||
crl::time duration) {
|
||||
_chatsFilterSlideCanvas = std::make_unique<Ui::RpWidget>(this);
|
||||
const auto canvas = _chatsFilterSlideCanvas.get();
|
||||
canvas->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
canvas->setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
canvas->setGeometry(_scroll->geometry());
|
||||
const auto animation
|
||||
= canvas->lifetime().make_state<Ui::SlideAnimation>();
|
||||
animation->setSnapshots(std::move(wasCache), std::move(nowCache));
|
||||
canvas->paintOn([=](QPainter &p) {
|
||||
p.fillRect(canvas->rect(), st::dialogsBg);
|
||||
animation->paintFrame(p, 0, 0, canvas->width());
|
||||
});
|
||||
canvas->show();
|
||||
if (_connecting) {
|
||||
_connecting->raise();
|
||||
}
|
||||
animation->start(slideLeft, [=] {
|
||||
if (animation->animating()) {
|
||||
canvas->update();
|
||||
} else {
|
||||
_chatsFilterSlideCanvas = nullptr;
|
||||
}
|
||||
}, duration);
|
||||
}
|
||||
|
||||
QPixmap Widget::grabForFolderSlideAnimation() {
|
||||
const auto hidden = _scrollToTop->isHidden();
|
||||
if (!hidden) {
|
||||
@@ -2832,6 +2919,7 @@ void Widget::showAnimated(
|
||||
Window::SlideDirection direction,
|
||||
const Window::SectionSlideParams ¶ms) {
|
||||
_showAnimation = nullptr;
|
||||
_chatsFilterSlideCanvas = nullptr;
|
||||
|
||||
auto oldContentCache = params.oldContentCache;
|
||||
showFast();
|
||||
@@ -4607,6 +4695,9 @@ void Widget::updateControlsGeometry() {
|
||||
const auto scrollHeight = height() - scrollTop - bottomSkip;
|
||||
const auto wasScrollHeight = _scroll->height();
|
||||
_scroll->setGeometry(0, scrollTop, scrollWidth, scrollHeight);
|
||||
if (_chatsFilterSlideCanvas) {
|
||||
_chatsFilterSlideCanvas->setGeometry(_scroll->geometry());
|
||||
}
|
||||
if (scrollHeight != wasScrollHeight) {
|
||||
controller()->floatPlayerAreaUpdated();
|
||||
}
|
||||
|
||||
@@ -212,6 +212,13 @@ private:
|
||||
void setupConnectingWidget();
|
||||
void setupMainMenuToggle();
|
||||
void setupMoreChatsBar();
|
||||
void switchToChatsFilter(FilterId id);
|
||||
[[nodiscard]] QPixmap grabForChatsFilterSlide();
|
||||
void startChatsFilterSlide(
|
||||
QPixmap wasCache,
|
||||
QPixmap nowCache,
|
||||
bool slideLeft,
|
||||
crl::time duration);
|
||||
void setupDownloadBar();
|
||||
void setupShortcuts();
|
||||
void setupStories();
|
||||
@@ -428,6 +435,7 @@ private:
|
||||
bool _searchQueryFromArchive = true;
|
||||
|
||||
Ui::Controls::SwipeBackResult _swipeBackData;
|
||||
bool _chatsFilterSwipeSwitch = false;
|
||||
bool _swipeBackMirrored = false;
|
||||
bool _swipeBackIconMirrored = false;
|
||||
|
||||
@@ -448,6 +456,7 @@ private:
|
||||
rpl::variable<float64> _childListShown;
|
||||
rpl::variable<PeerId> _childListPeerId;
|
||||
std::unique_ptr<Ui::RpWidget> _hideChildListCanvas;
|
||||
std::unique_ptr<Ui::RpWidget> _chatsFilterSlideCanvas;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user