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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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