Use Window::SlideAnimation in all widgets.

This commit is contained in:
John Preston 2022-12-01 14:14:35 +04:00
parent eed706f917
commit b561705528
14 changed files with 217 additions and 302 deletions

View file

@ -744,15 +744,15 @@ void Widget::changeOpenedSubsection(
if (isHidden()) { if (isHidden()) {
animated = anim::type::instant; animated = anim::type::instant;
} }
auto cacheUnder = QPixmap(); auto oldContentCache = QPixmap();
const auto showDirection = fromRight const auto showDirection = fromRight
? Window::SlideDirection::FromRight ? Window::SlideDirection::FromRight
: Window::SlideDirection::FromLeft; : Window::SlideDirection::FromLeft;
if (animated == anim::type::normal) { if (animated == anim::type::normal) {
_connecting->setForceHidden(true); _connecting->setForceHidden(true);
cacheUnder = grabForFolderSlideAnimation(); oldContentCache = grabForFolderSlideAnimation();
} }
_a_show.stop(); _showAnimation = nullptr;
change(); change();
refreshTopBars(); refreshTopBars();
updateControlsVisibility(true); updateControlsVisibility(true);
@ -760,9 +760,12 @@ void Widget::changeOpenedSubsection(
_api.request(base::take(_topicSearchRequest)).cancel(); _api.request(base::take(_topicSearchRequest)).cancel();
if (animated == anim::type::normal) { if (animated == anim::type::normal) {
_connecting->setForceHidden(true); _connecting->setForceHidden(true);
auto cacheOver = grabForFolderSlideAnimation(); auto newContentCache = grabForFolderSlideAnimation();
_connecting->setForceHidden(false); _connecting->setForceHidden(false);
startSlideAnimation(); startSlideAnimation(
std::move(oldContentCache),
std::move(newContentCache),
showDirection);
} }
} }
@ -872,7 +875,7 @@ void Widget::refreshTopBars() {
} }
}, _forumGroupCallBar->lifetime()); }, _forumGroupCallBar->lifetime());
if (_a_show.animating()) { if (_showAnimation) {
_forumTopShadow->hide(); _forumTopShadow->hide();
_forumGroupCallBar->hide(); _forumGroupCallBar->hide();
_forumRequestsBar->hide(); _forumRequestsBar->hide();
@ -1048,7 +1051,7 @@ void Widget::startWidthAnimation() {
void Widget::stopWidthAnimation() { void Widget::stopWidthAnimation() {
_widthAnimationCache = QPixmap(); _widthAnimationCache = QPixmap();
if (!_a_show.animating()) { if (!_showAnimation) {
_scroll->show(); _scroll->show();
} }
update(); update();
@ -1062,21 +1065,27 @@ void Widget::showFast() {
} }
void Widget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params) { void Widget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params) {
_showDirection = direction; _showAnimation = nullptr;
_a_show.stop();
_cacheUnder = params.oldContentCache; auto oldContentCache = params.oldContentCache;
showFast(); showFast();
_cacheOver = controller()->content()->grabForShowAnimation(params); const auto content = controller()->content();
auto newContentCache = content->grabForShowAnimation(params);
if (_updateTelegram) { if (_updateTelegram) {
_updateTelegram->hide(); _updateTelegram->hide();
} }
_connecting->setForceHidden(true); _connecting->setForceHidden(true);
startSlideAnimation(); startSlideAnimation(
std::move(oldContentCache),
std::move(newContentCache),
direction);
} }
void Widget::startSlideAnimation() { void Widget::startSlideAnimation(
QPixmap oldContentCache,
QPixmap newContentCache,
Window::SlideDirection direction) {
_scroll->hide(); _scroll->hide();
_searchControls->hide(); _searchControls->hide();
if (_subsectionTopBar) { if (_subsectionTopBar) {
@ -1095,10 +1104,12 @@ void Widget::startSlideAnimation() {
_forumReportBar->bar().hide(); _forumReportBar->bar().hide();
} }
if (_showDirection == Window::SlideDirection::FromLeft) { _showAnimation = std::make_unique<Window::SlideAnimation>();
std::swap(_cacheUnder, _cacheOver); _showAnimation->setDirection(direction);
} _showAnimation->setRepaintCallback([=] { update(); });
_a_show.start([=] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition()); _showAnimation->setFinishedCallback([=] { slideFinished(); });
_showAnimation->setPixmaps(oldContentCache, newContentCache);
_showAnimation->start();
} }
bool Widget::floatPlayerHandleWheelEvent(QEvent *e) { bool Widget::floatPlayerHandleWheelEvent(QEvent *e) {
@ -1109,17 +1120,12 @@ QRect Widget::floatPlayerAvailableRect() {
return mapToGlobal(_scroll->geometry()); return mapToGlobal(_scroll->geometry());
} }
void Widget::animationCallback() { void Widget::slideFinished() {
update(); _showAnimation = nullptr;
if (!_a_show.animating()) { updateControlsVisibility(true);
_cacheUnder = _cacheOver = QPixmap(); if ((!_subsectionTopBar || !_subsectionTopBar->searchHasFocus())
&& !_filter->hasFocus()) {
updateControlsVisibility(true); controller()->widget()->setInnerFocus();
if ((!_subsectionTopBar || !_subsectionTopBar->searchHasFocus())
&& !_filter->hasFocus()) {
controller()->widget()->setInnerFocus();
}
} }
} }
@ -1854,7 +1860,7 @@ void Widget::listScrollUpdated() {
} }
void Widget::applyFilterUpdate(bool force) { void Widget::applyFilterUpdate(bool force) {
if (_a_show.animating() && !force) { if (_showAnimation && !force) {
return; return;
} }
@ -2099,7 +2105,7 @@ void Widget::resizeEvent(QResizeEvent *e) {
} }
void Widget::updateLockUnlockVisibility() { void Widget::updateLockUnlockVisibility() {
if (_a_show.animating()) { if (_showAnimation) {
return; return;
} }
const auto hidden = !session().domain().local().hasLocalPasscode(); const auto hidden = !session().domain().local().hasLocalPasscode();
@ -2110,7 +2116,7 @@ void Widget::updateLockUnlockVisibility() {
} }
void Widget::updateLoadMoreChatsVisibility() { void Widget::updateLoadMoreChatsVisibility() {
if (_a_show.animating() || !_loadMoreChats) { if (_showAnimation || !_loadMoreChats) {
return; return;
} }
const auto hidden = (_openedFolder != nullptr) const auto hidden = (_openedFolder != nullptr)
@ -2123,7 +2129,9 @@ void Widget::updateLoadMoreChatsVisibility() {
} }
void Widget::updateJumpToDateVisibility(bool fast) { void Widget::updateJumpToDateVisibility(bool fast) {
if (_a_show.animating()) return; if (_showAnimation) {
return;
}
_jumpToDate->toggle( _jumpToDate->toggle(
(_searchInChat && _filter->getLastText().isEmpty()), (_searchInChat && _filter->getLastText().isEmpty()),
@ -2306,24 +2314,8 @@ void Widget::paintEvent(QPaintEvent *e) {
if (r != rect()) { if (r != rect()) {
p.setClipRect(r); p.setClipRect(r);
} }
if (_a_show.animating()) { if (_showAnimation) {
const auto progress = _a_show.value(1.); _showAnimation->paintContents(p);
const auto top = 0;
const auto shift = std::min(st::slideShift, width() / 2);
const auto retina = cIntRetinaFactor();
const auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
const auto coordUnder = fromLeft ? anim::interpolate(-shift, 0, progress) : anim::interpolate(0, -shift, progress);
const auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
const auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, top, coordOver, _cacheUnder.height() / retina), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, _cacheUnder.height()));
p.setOpacity(shadow);
p.fillRect(0, top, coordOver, _cacheUnder.height() / retina, st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(QRect(coordOver, top, _cacheOver.width() / retina, _cacheOver.height() / retina), _cacheOver, QRect(0, 0, _cacheOver.width(), _cacheOver.height()));
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), top, st::slideShadow.width(), _cacheOver.height() / retina));
return; return;
} }
auto above = QRect(0, 0, width(), _scroll->y()); auto above = QRect(0, 0, width(), _scroll->y());

View file

@ -139,7 +139,7 @@ private:
bool searchMessages(bool searchCache = false); bool searchMessages(bool searchCache = false);
void needSearchMessages(); void needSearchMessages();
void animationCallback(); void slideFinished();
void searchReceived( void searchReceived(
SearchRequestType type, SearchRequestType type,
const MTPmessages_Messages &result, const MTPmessages_Messages &result,
@ -182,7 +182,10 @@ private:
void changeOpenedForum(Data::Forum *forum, anim::type animated); void changeOpenedForum(Data::Forum *forum, anim::type animated);
void hideChildList(); void hideChildList();
[[nodiscard]] QPixmap grabForFolderSlideAnimation(); [[nodiscard]] QPixmap grabForFolderSlideAnimation();
void startSlideAnimation(); void startSlideAnimation(
QPixmap oldContentCache,
QPixmap newContentCache,
Window::SlideDirection direction);
void fullSearchRefreshOn(rpl::producer<> events); void fullSearchRefreshOn(rpl::producer<> events);
void applyFilterUpdate(bool force = false); void applyFilterUpdate(bool force = false);
@ -233,9 +236,7 @@ private:
std::unique_ptr<Window::ConnectionState> _connecting; std::unique_ptr<Window::ConnectionState> _connecting;
Ui::Animations::Simple _scrollToAnimation; Ui::Animations::Simple _scrollToAnimation;
Ui::Animations::Simple _a_show; std::unique_ptr<Window::SlideAnimation> _showAnimation;
Window::SlideDirection _showDirection = Window::SlideDirection();
QPixmap _cacheUnder, _cacheOver;
Ui::Animations::Simple _scrollToTopShown; Ui::Animations::Simple _scrollToTopShown;
object_ptr<Ui::HistoryDownButton> _scrollToTop; object_ptr<Ui::HistoryDownButton> _scrollToTop;

View file

@ -803,7 +803,7 @@ HistoryWidget::HistoryWidget(
session().data().itemVisibilityQueries( session().data().itemVisibilityQueries(
) | rpl::filter([=]( ) | rpl::filter([=](
const Data::Session::ItemVisibilityQuery &query) { const Data::Session::ItemVisibilityQuery &query) {
return !_a_show.animating() return !_showAnimation
&& (_history == query.item->history()) && (_history == query.item->history())
&& (query.item->mainView() != nullptr) && (query.item->mainView() != nullptr)
&& isVisible(); && isVisible();
@ -2620,13 +2620,13 @@ std::optional<QString> HistoryWidget::writeRestriction() const {
} }
void HistoryWidget::updateControlsVisibility() { void HistoryWidget::updateControlsVisibility() {
if (!_a_show.animating()) { if (!_showAnimation) {
_topShadow->setVisible(_peer != nullptr); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr); _topBar->setVisible(_peer != nullptr);
} }
_cornerButtons.updateJumpDownVisibility(); _cornerButtons.updateJumpDownVisibility();
_cornerButtons.updateUnreadThingsVisibility(); _cornerButtons.updateUnreadThingsVisibility();
if (!_history || _a_show.animating()) { if (!_history || _showAnimation) {
hideChildWidgets(); hideChildWidgets();
return; return;
} }
@ -3161,7 +3161,7 @@ bool HistoryWidget::markingContentsRead() const {
&& _historyInited && _historyInited
&& !_firstLoadRequest && !_firstLoadRequest
&& !_delayedShowAtRequest && !_delayedShowAtRequest
&& !_a_show.animating() && !_showAnimation
&& controller()->widget()->markingAsRead(); && controller()->widget()->markingAsRead();
} }
@ -3940,11 +3940,7 @@ MsgId HistoryWidget::msgId() const {
void HistoryWidget::showAnimated( void HistoryWidget::showAnimated(
Window::SlideDirection direction, Window::SlideDirection direction,
const Window::SectionSlideParams &params) { const Window::SectionSlideParams &params) {
_showDirection = direction; _showAnimation = nullptr;
_a_show.stop();
_cacheUnder = params.oldContentCache;
// If we show pinned bar here, we don't want it to change the // If we show pinned bar here, we don't want it to change the
// calculated and prepared scrollTop of the messages history. // calculated and prepared scrollTop of the messages history.
@ -3965,40 +3961,40 @@ void HistoryWidget::showAnimated(
_preserveScrollTop = false; _preserveScrollTop = false;
_stickerToast = nullptr; _stickerToast = nullptr;
_cacheOver = controller()->content()->grabForShowAnimation(params); auto newContentCache = Ui::GrabWidget(this);
hideChildWidgets(); hideChildWidgets();
if (params.withTopBarShadow) _topShadow->show(); if (params.withTopBarShadow) _topShadow->show();
if (_showDirection == Window::SlideDirection::FromLeft) {
std::swap(_cacheUnder, _cacheOver);
}
_a_show.start([=] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
if (_history) { if (_history) {
_topBar->show(); _topBar->show();
_topBar->setAnimatingMode(true); _topBar->setAnimatingMode(true);
} }
_showAnimation = std::make_unique<Window::SlideAnimation>();
_showAnimation->setDirection(direction);
_showAnimation->setRepaintCallback([=] { update(); });
_showAnimation->setFinishedCallback([=] { showFinished(); });
_showAnimation->setPixmaps(params.oldContentCache, newContentCache);
_showAnimation->start();
activate(); activate();
} }
void HistoryWidget::animationCallback() { void HistoryWidget::showFinished() {
update(); _cornerButtons.finishAnimations();
if (!_a_show.animating()) { if (_pinnedBar) {
_cornerButtons.finishAnimations(); _pinnedBar->finishAnimating();
if (_pinnedBar) {
_pinnedBar->finishAnimating();
}
if (_groupCallBar) {
_groupCallBar->finishAnimating();
}
if (_requestsBar) {
_requestsBar->finishAnimating();
}
_cacheUnder = _cacheOver = QPixmap();
doneShow();
synteticScrollToY(_scroll->scrollTop());
} }
if (_groupCallBar) {
_groupCallBar->finishAnimating();
}
if (_requestsBar) {
_requestsBar->finishAnimating();
}
_showAnimation = nullptr;
doneShow();
synteticScrollToY(_scroll->scrollTop());
} }
void HistoryWidget::doneShow() { void HistoryWidget::doneShow() {
@ -4083,10 +4079,10 @@ void HistoryWidget::checkSuggestToGigagroup() {
} }
void HistoryWidget::finishAnimating() { void HistoryWidget::finishAnimating() {
if (!_a_show.animating()) { if (!_showAnimation) {
return; return;
} }
_a_show.stop(); _showAnimation = nullptr;
_topShadow->setVisible(_peer != nullptr); _topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr); _topBar->setVisible(_peer != nullptr);
_cornerButtons.finishAnimations(); _cornerButtons.finishAnimations();
@ -4549,7 +4545,7 @@ bool HistoryWidget::kbWasHidden() const {
} }
void HistoryWidget::toggleKeyboard(bool manual) { void HistoryWidget::toggleKeyboard(bool manual) {
auto fieldEnabled = canWriteMessage() && !_a_show.animating(); auto fieldEnabled = canWriteMessage() && !_showAnimation;
if (_kbShown || _kbReplyTo) { if (_kbShown || _kbReplyTo) {
_botKeyboardHide->hide(); _botKeyboardHide->hide();
if (_kbShown) { if (_kbShown) {
@ -4621,7 +4617,7 @@ void HistoryWidget::toggleKeyboard(bool manual) {
} }
updateControlsGeometry(); updateControlsGeometry();
updateFieldPlaceholder(); updateFieldPlaceholder();
if (_botKeyboardHide->isHidden() && canWriteMessage() && !_a_show.animating()) { if (_botKeyboardHide->isHidden() && canWriteMessage() && !_showAnimation) {
_tabbedSelectorToggle->show(); _tabbedSelectorToggle->show();
} else { } else {
_tabbedSelectorToggle->hide(); _tabbedSelectorToggle->hide();
@ -4882,7 +4878,7 @@ void HistoryWidget::fieldFocused() {
} }
void HistoryWidget::checkFieldAutocomplete() { void HistoryWidget::checkFieldAutocomplete() {
if (!_history || _a_show.animating()) { if (!_history || _showAnimation) {
return; return;
} }
@ -5441,7 +5437,7 @@ void HistoryWidget::updateHistoryGeometry(
if (!_history || (initial && _historyInited) || (!initial && !_historyInited)) { if (!_history || (initial && _historyInited) || (!initial && !_historyInited)) {
return; return;
} }
if (_firstLoadRequest || _a_show.animating()) { if (_firstLoadRequest || _showAnimation) {
_updateHistoryGeometryRequired = true; _updateHistoryGeometryRequired = true;
return; // scrollTopMax etc are not working after recountHistoryGeometry() return; // scrollTopMax etc are not working after recountHistoryGeometry()
} }
@ -5742,7 +5738,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
_history->lastKeyboardHiddenId = _history->lastKeyboardId; _history->lastKeyboardHiddenId = _history->lastKeyboardId;
} }
if (!isSearching() && !isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || (_replyToId && _replyEditMsg) || (!HasSendText(_field) && !kbWasHidden()))) { if (!isSearching() && !isBotStart() && !isBlocked() && _canSendMessages && (wasVisible || (_replyToId && _replyEditMsg) || (!HasSendText(_field) && !kbWasHidden()))) {
if (!_a_show.animating()) { if (!_showAnimation) {
if (hasMarkup) { if (hasMarkup) {
_kbScroll->show(); _kbScroll->show();
_tabbedSelectorToggle->hide(); _tabbedSelectorToggle->hide();
@ -5767,7 +5763,7 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
updateReplyEditText(_kbReplyTo); updateReplyEditText(_kbReplyTo);
} }
} else { } else {
if (!_a_show.animating()) { if (!_showAnimation) {
_kbScroll->hide(); _kbScroll->hide();
_tabbedSelectorToggle->show(); _tabbedSelectorToggle->show();
_botKeyboardHide->hide(); _botKeyboardHide->hide();
@ -5847,7 +5843,7 @@ int HistoryWidget::computeMaxFieldHeight() const {
} }
bool HistoryWidget::cornerButtonsIgnoreVisibility() { bool HistoryWidget::cornerButtonsIgnoreVisibility() {
return _a_show.animating(); return _showAnimation != nullptr;
} }
std::optional<bool> HistoryWidget::cornerButtonsDownShown() { std::optional<bool> HistoryWidget::cornerButtonsDownShown() {
@ -6302,7 +6298,7 @@ void HistoryWidget::checkPinnedBarState() {
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_pinnedBar->hide(); _pinnedBar->hide();
} }
} }
@ -6478,7 +6474,7 @@ void HistoryWidget::setupGroupCallBar() {
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_groupCallBar->hide(); _groupCallBar->hide();
} }
} }
@ -6525,7 +6521,7 @@ void HistoryWidget::setupRequestsBar() {
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_requestsBar->hide(); _requestsBar->hide();
} }
} }
@ -7193,7 +7189,7 @@ void HistoryWidget::handlePeerUpdate() {
session().api().chatParticipants().requestAdmins(channel); session().api().chatParticipants().requestAdmins(channel);
} }
} }
if (!_a_show.animating()) { if (!_showAnimation) {
if (_unblock->isHidden() == isBlocked() if (_unblock->isHidden() == isBlocked()
|| (!isBlocked() && _joinChannel->isHidden() == isJoinChannel())) { || (!isBlocked() && _joinChannel->isHidden() == isJoinChannel())) {
resize = true; resize = true;
@ -7637,28 +7633,12 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
} }
bool HistoryWidget::paintShowAnimationFrame() { bool HistoryWidget::paintShowAnimationFrame() {
auto progress = _a_show.value(1.); if (_showAnimation) {
if (!_a_show.animating()) { QPainter p(this);
return false; _showAnimation->paintContents(p);
return true;
} }
return false;
Painter p(this);
auto animationWidth = width();
auto retina = cIntRetinaFactor();
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = fromLeft ? anim::interpolate(0, animationWidth, progress) : anim::interpolate(animationWidth, 0, progress);
auto shadow = fromLeft ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, height() * retina));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, 0, _cacheOver.width(), height() * retina));
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
return true;
} }
void HistoryWidget::paintEvent(QPaintEvent *e) { void HistoryWidget::paintEvent(QPaintEvent *e) {

View file

@ -162,7 +162,9 @@ public:
bool hasTopBarShadow() const { bool hasTopBarShadow() const {
return peer() != nullptr; return peer() != nullptr;
} }
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams &params); void showAnimated(
Window::SlideDirection direction,
const Window::SectionSlideParams &params);
void finishAnimating(); void finishAnimating();
void doneShow(); void doneShow();
@ -403,7 +405,7 @@ private:
auto computeSendButtonType() const; auto computeSendButtonType() const;
void animationCallback(); void showFinished();
void updateOverStates(QPoint pos); void updateOverStates(QPoint pos);
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos = {}); void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos = {});
void sendButtonClicked(); void sendButtonClicked();
@ -754,9 +756,7 @@ private:
QString _confirmSource; QString _confirmSource;
Ui::Animations::Simple _a_show; std::unique_ptr<Window::SlideAnimation> _showAnimation;
Window::SlideDirection _showDirection;
QPixmap _cacheUnder, _cacheOver;
HistoryView::ElementHighlighter _highlighter; HistoryView::ElementHighlighter _highlighter;

View file

@ -297,7 +297,7 @@ void Widget::checkUpdateStatus() {
this, this,
tr::lng_menu_update(), tr::lng_menu_update(),
st::defaultBoxButton)); st::defaultBoxButton));
if (!_a_show.animating()) { if (!_showAnimation) {
_update->setVisible(true); _update->setVisible(true);
} }
const auto stepHasCover = getStep()->hasCover(); const auto stepHasCover = getStep()->hasCover();
@ -699,62 +699,47 @@ void Widget::hideControls() {
_back->hide(anim::type::instant); _back->hide(anim::type::instant);
} }
void Widget::showAnimated(const QPixmap &bgAnimCache, bool back) { void Widget::showAnimated(QPixmap oldContentCache, bool back) {
_showBack = back; _showAnimation = nullptr;
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
showControls(); showControls();
floatPlayerHideAll(); floatPlayerHideAll();
(_showBack ? _cacheUnder : _cacheOver) = Ui::GrabWidget(this); auto newContentCache = Ui::GrabWidget(this);
hideControls(); hideControls();
floatPlayerShowVisible(); floatPlayerShowVisible();
_a_show.start( _showAnimation = std::make_unique<Window::SlideAnimation>();
[=] { animationCallback(); }, _showAnimation->setDirection(back
0., ? Window::SlideDirection::FromLeft
1., : Window::SlideDirection::FromRight);
st::slideDuration, _showAnimation->setRepaintCallback([=] { update(); });
Window::SlideAnimation::transition()); _showAnimation->setFinishedCallback([=] { showFinished(); });
_showAnimation->setPixmaps(oldContentCache, newContentCache);
_showAnimation->start();
show(); show();
} }
void Widget::animationCallback() { void Widget::showFinished() {
update(); _showAnimation = nullptr;
if (!_a_show.animating()) {
_cacheUnder = _cacheOver = QPixmap();
showControls(); showControls();
getStep()->activate(); getStep()->activate();
}
} }
void Widget::paintEvent(QPaintEvent *e) { void Widget::paintEvent(QPaintEvent *e) {
bool trivial = (rect() == e->rect()); const auto trivial = (rect() == e->rect());
setMouseTracking(true); setMouseTracking(true);
QPainter p(this); QPainter p(this);
if (!trivial) { if (!trivial) {
p.setClipRect(e->rect()); p.setClipRect(e->rect());
} }
p.fillRect(e->rect(), st::windowBg); if (_showAnimation) {
auto progress = _a_show.value(1.); _showAnimation->paintContents(p);
if (_a_show.animating()) { return;
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = _showBack ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(coordOver, 0, _cacheOver);
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
} }
p.fillRect(e->rect(), st::windowBg);
} }
void Widget::resizeEvent(QResizeEvent *e) { void Widget::resizeEvent(QResizeEvent *e) {
@ -803,7 +788,7 @@ void Widget::updateControlsGeometry() {
} }
void Widget::keyPressEvent(QKeyEvent *e) { void Widget::keyPressEvent(QKeyEvent *e) {
if (_a_show.animating() || getStep()->animating()) return; if (_showAnimation || getStep()->animating()) return;
if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Back) { if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Back) {
if (getStep()->hasBack()) { if (getStep()->hasBack()) {

View file

@ -30,6 +30,7 @@ class FadeWrap;
namespace Window { namespace Window {
class ConnectionState; class ConnectionState;
class Controller; class Controller;
class SlideAnimation;
} // namespace Window } // namespace Window
namespace Intro { namespace Intro {
@ -96,15 +97,14 @@ public:
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
not_null<Main::Account*> account, not_null<Main::Account*> account,
EnterPoint point); EnterPoint point);
~Widget();
void showAnimated(const QPixmap &bgAnimCache, bool back = false); void showAnimated(QPixmap oldContentCache, bool back = false);
void setInnerFocus(); void setInnerFocus();
[[nodiscard]] rpl::producer<> showSettingsRequested() const; [[nodiscard]] rpl::producer<> showSettingsRequested() const;
~Widget();
protected: protected:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
@ -112,7 +112,7 @@ protected:
private: private:
void refreshLang(); void refreshLang();
void animationCallback(); void showFinished();
void createLanguageLink(); void createLanguageLink();
void checkUpdateStatus(); void checkUpdateStatus();
void setupNextButton(); void setupNextButton();
@ -175,9 +175,7 @@ private:
std::optional<MTP::Sender> _api; std::optional<MTP::Sender> _api;
mtpRequestId _nearestDcRequestId = 0; mtpRequestId _nearestDcRequestId = 0;
Ui::Animations::Simple _a_show; std::unique_ptr<Window::SlideAnimation> _showAnimation;
bool _showBack = false;
QPixmap _cacheUnder, _cacheOver;
std::vector<details::Step*> _stepHistory; std::vector<details::Step*> _stepHistory;
rpl::lifetime _stepLifetime; rpl::lifetime _stepLifetime;

View file

@ -816,7 +816,7 @@ void MainWidget::createPlayer() {
}, _player->lifetime()); }, _player->lifetime());
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_player->show(anim::type::instant); _player->show(anim::type::instant);
_player->setVisible(false); _player->setVisible(false);
Shortcuts::ToggleMediaShortcuts(true); Shortcuts::ToggleMediaShortcuts(true);
@ -825,7 +825,7 @@ void MainWidget::createPlayer() {
} }
} }
if (_player && !_player->toggled()) { if (_player && !_player->toggled()) {
if (!_a_show.animating()) { if (!_showAnimation) {
_player->show(anim::type::normal); _player->show(anim::type::normal);
_playerHeight = _contentScrollAddToY = _player->contentHeight(); _playerHeight = _contentScrollAddToY = _player->contentHeight();
updateControlsGeometry(); updateControlsGeometry();
@ -916,7 +916,7 @@ void MainWidget::createCallTopBar() {
callTopBarHeightUpdated(value); callTopBarHeightUpdated(value);
}, lifetime()); }, lifetime());
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_callTopBar->show(anim::type::instant); _callTopBar->show(anim::type::instant);
_callTopBar->setVisible(false); _callTopBar->setVisible(false);
} else { } else {
@ -980,7 +980,7 @@ void MainWidget::createExportTopBar(Export::View::Content &&data) {
} }
}, _exportTopBar->lifetime()); }, _exportTopBar->lifetime());
orderWidgets(); orderWidgets();
if (_a_show.animating()) { if (_showAnimation) {
_exportTopBar->show(anim::type::instant); _exportTopBar->show(anim::type::instant);
_exportTopBar->setVisible(false); _exportTopBar->setVisible(false);
} else { } else {
@ -1318,7 +1318,7 @@ void MainWidget::showPeerHistory(
} }
auto animatedShow = [&] { auto animatedShow = [&] {
if (_a_show.animating() if (_showAnimation
|| Core::App().passcodeLocked() || Core::App().passcodeLocked()
|| (params.animated == anim::type::instant)) { || (params.animated == anim::type::instant)) {
return false; return false;
@ -1369,7 +1369,7 @@ void MainWidget::showPeerHistory(
if (onlyDialogs) { if (onlyDialogs) {
Assert(_dialogs != nullptr); Assert(_dialogs != nullptr);
_history->hide(); _history->hide();
if (!_a_show.animating()) { if (!_showAnimation) {
if (animationParams) { if (animationParams) {
auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight; auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight;
_dialogs->showAnimated(direction, animationParams); _dialogs->showAnimated(direction, animationParams);
@ -1385,7 +1385,7 @@ void MainWidget::showPeerHistory(
if (isOneColumn() && _dialogs && !_dialogs->isHidden()) { if (isOneColumn() && _dialogs && !_dialogs->isHidden()) {
_dialogs->hide(); _dialogs->hide();
} }
if (!_a_show.animating()) { if (!_showAnimation) {
if (!animationParams.oldContentCache.isNull()) { if (!animationParams.oldContentCache.isNull()) {
_history->showAnimated( _history->showAnimated(
back back
@ -1661,7 +1661,7 @@ void MainWidget::showNewSection(
Assert(newMainSection || newThirdSection); Assert(newMainSection || newThirdSection);
auto animatedShow = [&] { auto animatedShow = [&] {
if (_a_show.animating() if (_showAnimation
|| Core::App().passcodeLocked() || Core::App().passcodeLocked()
|| (params.animated == anim::type::instant) || (params.animated == anim::type::instant)
|| memento->instant()) { || memento->instant()) {
@ -1965,58 +1965,41 @@ void MainWidget::checkActivation() {
} }
} }
void MainWidget::showAnimated(const QPixmap &bgAnimCache, bool back) { void MainWidget::showAnimated(QPixmap oldContentCache, bool back) {
_showBack = back; _showAnimation = nullptr;
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
showAll(); showAll();
floatPlayerHideAll(); floatPlayerHideAll();
(_showBack ? _cacheUnder : _cacheOver) = Ui::GrabWidget(this); auto newContentCache = Ui::GrabWidget(this);
hideAll(); hideAll();
floatPlayerShowVisible(); floatPlayerShowVisible();
_a_show.start( _showAnimation = std::make_unique<Window::SlideAnimation>();
[this] { animationCallback(); }, _showAnimation->setDirection(back
0., ? Window::SlideDirection::FromLeft
1., : Window::SlideDirection::FromRight);
st::slideDuration, _showAnimation->setRepaintCallback([=] { update(); });
Window::SlideAnimation::transition()); _showAnimation->setFinishedCallback([=] { showFinished(); });
_showAnimation->setPixmaps(oldContentCache, newContentCache);
_showAnimation->start();
show(); show();
} }
void MainWidget::animationCallback() { void MainWidget::showFinished() {
update(); _showAnimation = nullptr;
if (!_a_show.animating()) {
_cacheUnder = _cacheOver = QPixmap();
showAll(); showAll();
activate(); activate();
}
} }
void MainWidget::paintEvent(QPaintEvent *e) { void MainWidget::paintEvent(QPaintEvent *e) {
if (_background) { if (_background) {
checkChatBackground(); checkChatBackground();
} }
if (_showAnimation) {
auto p = QPainter(this); auto p = QPainter(this);
auto progress = _a_show.value(1.); _showAnimation->paintContents(p);
if (_a_show.animating()) {
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = _showBack ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(coordOver, 0, _cacheOver);
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
} }
} }
@ -2653,7 +2636,7 @@ bool MainWidget::contentOverlapped(const QRect &globalRect) {
} }
void MainWidget::activate() { void MainWidget::activate() {
if (_a_show.animating()) { if (_showAnimation) {
return; return;
} else if (const auto paths = cSendPaths(); !paths.isEmpty()) { } else if (const auto paths = cSendPaths(); !paths.isEmpty()) {
const auto interpret = u"interpret://"_q; const auto interpret = u"interpret://"_q;
@ -2688,7 +2671,7 @@ void MainWidget::activate() {
} }
bool MainWidget::animatingShow() const { bool MainWidget::animatingShow() const {
return _a_show.animating(); return _showAnimation != nullptr;
} }
bool MainWidget::isOneColumn() const { bool MainWidget::isOneColumn() const {

View file

@ -89,6 +89,7 @@ class TopBarWrapWidget;
class SectionMemento; class SectionMemento;
class SectionWidget; class SectionWidget;
class AbstractSectionWidget; class AbstractSectionWidget;
class SlideAnimation;
class ConnectionState; class ConnectionState;
struct SectionSlideParams; struct SectionSlideParams;
struct SectionShow; struct SectionShow;
@ -137,7 +138,7 @@ public:
void returnTabbedSelector(); void returnTabbedSelector();
void showAnimated(const QPixmap &bgAnimCache, bool back = false); void showAnimated(QPixmap oldContentCache, bool back = false);
void activate(); void activate();
@ -248,7 +249,7 @@ protected:
bool eventFilter(QObject *o, QEvent *e) override; bool eventFilter(QObject *o, QEvent *e) override;
private: private:
void animationCallback(); void showFinished();
void handleAdaptiveLayoutUpdate(); void handleAdaptiveLayoutUpdate();
void updateWindowAdaptiveLayout(); void updateWindowAdaptiveLayout();
void handleAudioUpdate(const Media::Player::TrackState &state); void handleAudioUpdate(const Media::Player::TrackState &state);
@ -342,9 +343,7 @@ private:
const not_null<Window::SessionController*> _controller; const not_null<Window::SessionController*> _controller;
Ui::Animations::Simple _a_show; std::unique_ptr<Window::SlideAnimation> _showAnimation;
bool _showBack = false;
QPixmap _cacheUnder, _cacheOver;
int _dialogsWidth = 0; int _dialogsWidth = 0;
int _thirdColumnWidth = 0; int _thirdColumnWidth = 0;

View file

@ -172,15 +172,8 @@ void MainWindow::clearWidgetsHook() {
} }
} }
QPixmap MainWindow::grabInner() { QPixmap MainWindow::grabForSlideAnimation() {
if (_passcodeLock) { return Ui::GrabWidget(bodyWidget());
return Ui::GrabWidget(_passcodeLock);
} else if (_intro) {
return Ui::GrabWidget(_intro);
} else if (_main) {
return Ui::GrabWidget(_main);
}
return {};
} }
void MainWindow::preventOrInvoke(Fn<void()> callback) { void MainWindow::preventOrInvoke(Fn<void()> callback) {
@ -192,7 +185,7 @@ void MainWindow::preventOrInvoke(Fn<void()> callback) {
void MainWindow::setupPasscodeLock() { void MainWindow::setupPasscodeLock() {
auto animated = (_main || _intro); auto animated = (_main || _intro);
auto bg = animated ? grabInner() : QPixmap(); auto oldContentCache = animated ? grabForSlideAnimation() : QPixmap();
_passcodeLock.create(bodyWidget(), &controller()); _passcodeLock.create(bodyWidget(), &controller());
updateControlsGeometry(); updateControlsGeometry();
@ -205,7 +198,7 @@ void MainWindow::setupPasscodeLock() {
_intro->hide(); _intro->hide();
} }
if (animated) { if (animated) {
_passcodeLock->showAnimated(bg); _passcodeLock->showAnimated(std::move(oldContentCache));
} else { } else {
_passcodeLock->showFinished(); _passcodeLock->showFinished();
setInnerFocus(); setInnerFocus();
@ -213,29 +206,30 @@ void MainWindow::setupPasscodeLock() {
} }
void MainWindow::clearPasscodeLock() { void MainWindow::clearPasscodeLock() {
Expects(_intro || _main);
if (!_passcodeLock) { if (!_passcodeLock) {
return; return;
} }
auto oldContentCache = grabForSlideAnimation();
_passcodeLock.destroy();
if (_intro) { if (_intro) {
auto bg = grabInner();
_passcodeLock.destroy();
_intro->show(); _intro->show();
updateControlsGeometry(); updateControlsGeometry();
_intro->showAnimated(bg, true); _intro->showAnimated(std::move(oldContentCache), true);
} else if (_main) { } else if (_main) {
auto bg = grabInner();
_passcodeLock.destroy();
_main->show(); _main->show();
updateControlsGeometry(); updateControlsGeometry();
_main->showAnimated(bg, true); _main->showAnimated(std::move(oldContentCache), true);
Core::App().checkStartUrl(); Core::App().checkStartUrl();
} }
} }
void MainWindow::setupIntro(Intro::EnterPoint point) { void MainWindow::setupIntro(
Intro::EnterPoint point,
QPixmap oldContentCache) {
auto animated = (_main || _passcodeLock); auto animated = (_main || _passcodeLock);
auto bg = animated ? grabInner() : QPixmap();
destroyLayer(); destroyLayer();
auto created = object_ptr<Intro::Widget>( auto created = object_ptr<Intro::Widget>(
@ -256,7 +250,7 @@ void MainWindow::setupIntro(Intro::EnterPoint point) {
_intro->show(); _intro->show();
updateControlsGeometry(); updateControlsGeometry();
if (animated) { if (animated) {
_intro->showAnimated(bg); _intro->showAnimated(std::move(oldContentCache));
} else { } else {
setInnerFocus(); setInnerFocus();
} }
@ -264,12 +258,13 @@ void MainWindow::setupIntro(Intro::EnterPoint point) {
fixOrder(); fixOrder();
} }
void MainWindow::setupMain(MsgId singlePeerShowAtMsgId) { void MainWindow::setupMain(
MsgId singlePeerShowAtMsgId,
QPixmap oldContentCache) {
Expects(account().sessionExists()); Expects(account().sessionExists());
const auto animated = _intro const auto animated = _intro
|| (_passcodeLock && !Core::App().passcodeLocked()); || (_passcodeLock && !Core::App().passcodeLocked());
const auto bg = animated ? grabInner() : QPixmap();
const auto weakAnimatedLayer = (_main && _layer && !_passcodeLock) const auto weakAnimatedLayer = (_main && _layer && !_passcodeLock)
? Ui::MakeWeak(_layer.get()) ? Ui::MakeWeak(_layer.get())
: nullptr; : nullptr;
@ -295,7 +290,7 @@ void MainWindow::setupMain(MsgId singlePeerShowAtMsgId) {
_main->show(); _main->show();
updateControlsGeometry(); updateControlsGeometry();
if (animated) { if (animated) {
_main->showAnimated(bg); _main->showAnimated(std::move(oldContentCache));
} else { } else {
_main->activate(); _main->activate();
} }

View file

@ -53,8 +53,8 @@ public:
void setupPasscodeLock(); void setupPasscodeLock();
void clearPasscodeLock(); void clearPasscodeLock();
void setupIntro(Intro::EnterPoint point); void setupIntro(Intro::EnterPoint point, QPixmap oldContentCache);
void setupMain(MsgId singlePeerShowAtMsgId); void setupMain(MsgId singlePeerShowAtMsgId, QPixmap oldContentCache);
void showSettings(); void showSettings();
@ -83,6 +83,8 @@ public:
void showMainMenu(); void showMainMenu();
void fixOrder() override; void fixOrder() override;
[[nodiscard]] QPixmap grabForSlideAnimation();
void showLayer( void showLayer(
std::unique_ptr<Ui::LayerWidget> &&layer, std::unique_ptr<Ui::LayerWidget> &&layer,
Ui::LayerOptions options, Ui::LayerOptions options,
@ -132,8 +134,6 @@ private:
void themeUpdated(const Window::Theme::BackgroundUpdate &data); void themeUpdated(const Window::Theme::BackgroundUpdate &data);
QPixmap grabInner();
std::unique_ptr<Media::SystemMediaControlsManager> _mediaControlsManager; std::unique_ptr<Media::SystemMediaControlsManager> _mediaControlsManager;
QPoint _lastMousePosition; QPoint _lastMousePosition;

View file

@ -103,10 +103,11 @@ void Controller::showAccount(
_sessionController = session _sessionController = session
? std::make_unique<SessionController>(session, this) ? std::make_unique<SessionController>(session, this)
: nullptr; : nullptr;
setupSideBar(); auto oldContentCache = _widget.grabForSlideAnimation();
_widget.updateWindowIcon(); _widget.updateWindowIcon();
if (session) { if (session) {
setupMain(singlePeerShowAtMsgId); setupSideBar();
setupMain(singlePeerShowAtMsgId, std::move(oldContentCache));
session->updates().isIdleValue( session->updates().isIdleValue(
) | rpl::filter([=](bool idle) { ) | rpl::filter([=](bool idle) {
@ -125,7 +126,8 @@ void Controller::showAccount(
session->updates().updateOnline(crl::now()); session->updates().updateOnline(crl::now());
} else { } else {
setupIntro(); sideBarChanged();
setupIntro(std::move(oldContentCache));
_widget.updateGlobalMenu(); _widget.updateGlobalMenu();
} }
@ -138,13 +140,11 @@ PeerData *Controller::singlePeer() const {
} }
void Controller::setupSideBar() { void Controller::setupSideBar() {
Expects(_sessionController != nullptr);
if (!isPrimary()) { if (!isPrimary()) {
return; return;
} }
if (!_sessionController) {
sideBarChanged();
return;
}
_sessionController->filtersMenuChanged( _sessionController->filtersMenuChanged(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
sideBarChanged(); sideBarChanged();
@ -283,16 +283,19 @@ void Controller::clearPasscodeLock() {
} }
} }
void Controller::setupIntro() { void Controller::setupIntro(QPixmap oldContentCache) {
_widget.setupIntro(Core::App().domain().maybeLastOrSomeAuthedAccount() const auto point = Core::App().domain().maybeLastOrSomeAuthedAccount()
? Intro::EnterPoint::Qr ? Intro::EnterPoint::Qr
: Intro::EnterPoint::Start); : Intro::EnterPoint::Start;
_widget.setupIntro(point, std::move(oldContentCache));
} }
void Controller::setupMain(MsgId singlePeerShowAtMsgId) { void Controller::setupMain(
MsgId singlePeerShowAtMsgId,
QPixmap oldContentCache) {
Expects(_sessionController != nullptr); Expects(_sessionController != nullptr);
_widget.setupMain(singlePeerShowAtMsgId); _widget.setupMain(singlePeerShowAtMsgId, std::move(oldContentCache));
if (const auto id = Ui::Emoji::NeedToSwitchBackToId()) { if (const auto id = Ui::Emoji::NeedToSwitchBackToId()) {
Ui::Emoji::LoadAndSwitchTo(&_sessionController->session(), id); Ui::Emoji::LoadAndSwitchTo(&_sessionController->session(), id);

View file

@ -62,8 +62,6 @@ public:
void setupPasscodeLock(); void setupPasscodeLock();
void clearPasscodeLock(); void clearPasscodeLock();
void setupIntro();
void setupMain(MsgId singlePeerShowAtMsgId);
void showLogoutConfirmation(); void showLogoutConfirmation();
@ -121,6 +119,9 @@ private:
}; };
explicit Controller(CreateArgs &&args); explicit Controller(CreateArgs &&args);
void setupIntro(QPixmap oldContentCache);
void setupMain(MsgId singlePeerShowAtMsgId, QPixmap oldContentCache);
void showAccount( void showAccount(
not_null<Main::Account*> account, not_null<Main::Account*> account,
MsgId singlePeerShowAtMsgId); MsgId singlePeerShowAtMsgId);

View file

@ -34,6 +34,8 @@ LockWidget::LockWidget(QWidget *parent, not_null<Controller*> window)
show(); show();
} }
LockWidget::~LockWidget() = default;
not_null<Controller*> LockWidget::window() const { not_null<Controller*> LockWidget::window() const {
return _window; return _window;
} }
@ -45,62 +47,40 @@ void LockWidget::setInnerFocus() {
setFocus(); setFocus();
} }
void LockWidget::showAnimated(const QPixmap &bgAnimCache, bool back) { void LockWidget::showAnimated(QPixmap oldContentCache) {
_showBack = back; _showAnimation = nullptr;
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
showChildren(); showChildren();
setInnerFocus(); setInnerFocus();
(_showBack ? _cacheUnder : _cacheOver) = Ui::GrabWidget(this); auto newContentCache = Ui::GrabWidget(this);
hideChildren(); hideChildren();
_a_show.start( _showAnimation = std::make_unique<Window::SlideAnimation>();
[this] { animationCallback(); }, _showAnimation->setRepaintCallback([=] { update(); });
0., _showAnimation->setFinishedCallback([=] { showFinished(); });
1., _showAnimation->setPixmaps(oldContentCache, newContentCache);
st::slideDuration, _showAnimation->start();
Window::SlideAnimation::transition());
show();
}
void LockWidget::animationCallback() { show();
update();
if (!_a_show.animating()) {
showFinished();
}
} }
void LockWidget::showFinished() { void LockWidget::showFinished() {
showChildren(); showChildren();
_window->widget()->setInnerFocus(); _window->widget()->setInnerFocus();
_showAnimation = nullptr;
if (const auto controller = _window->sessionController()) { if (const auto controller = _window->sessionController()) {
controller->clearSectionStack(); controller->clearSectionStack();
} }
_cacheUnder = _cacheOver = QPixmap();
} }
void LockWidget::paintEvent(QPaintEvent *e) { void LockWidget::paintEvent(QPaintEvent *e) {
auto p = QPainter(this); auto p = QPainter(this);
auto progress = _a_show.value(1.); if (_showAnimation) {
if (_a_show.animating()) { _showAnimation->paintContents(p);
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress); return;
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
auto shadow = _showBack ? (1. - progress) : progress;
if (coordOver > 0) {
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
p.setOpacity(shadow);
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(coordOver, 0, _cacheOver);
p.setOpacity(shadow);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
} else {
paintContent(p);
} }
paintContent(p);
} }
void LockWidget::paintContent(QPainter &p) { void LockWidget::paintContent(QPainter &p) {

View file

@ -26,16 +26,18 @@ class Session;
namespace Window { namespace Window {
class Controller; class Controller;
class SlideAnimation;
class LockWidget : public Ui::RpWidget { class LockWidget : public Ui::RpWidget {
public: public:
LockWidget(QWidget *parent, not_null<Controller*> window); LockWidget(QWidget *parent, not_null<Controller*> window);
~LockWidget();
not_null<Controller*> window() const; [[nodiscard]] not_null<Controller*> window() const;
virtual void setInnerFocus(); virtual void setInnerFocus();
void showAnimated(const QPixmap &bgAnimCache, bool back = false); void showAnimated(QPixmap oldContentCache);
void showFinished(); void showFinished();
protected: protected:
@ -43,12 +45,8 @@ protected:
virtual void paintContent(QPainter &p); virtual void paintContent(QPainter &p);
private: private:
void animationCallback();
const not_null<Controller*> _window; const not_null<Controller*> _window;
Ui::Animations::Simple _a_show; std::unique_ptr<SlideAnimation> _showAnimation;
bool _showBack = false;
QPixmap _cacheUnder, _cacheOver;
}; };