mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-21 00:23:56 +08:00
Added slide animation for chats filter switching.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user