diff --git a/ui/layers/layer_widget.cpp b/ui/layers/layer_widget.cpp index 66a47db..74a32e1 100644 --- a/ui/layers/layer_widget.cpp +++ b/ui/layers/layer_widget.cpp @@ -34,6 +34,8 @@ public: QPixmap &&specialLayerCache, QPixmap &&layerCache); void removeBodyCache(); + [[nodiscard]] bool hasBodyCache() const; + void refreshBodyCache(QPixmap &&bodyCache); void startAnimation(Action action); void skipAnimation(Action action); void finishAnimating(); @@ -102,12 +104,22 @@ void LayerStackWidget::BackgroundWidget::setCacheImages( } void LayerStackWidget::BackgroundWidget::removeBodyCache() { - if (!_bodyCache.isNull()) { + if (hasBodyCache()) { _bodyCache = {}; setAttribute(Qt::WA_OpaquePaintEvent, false); } } +bool LayerStackWidget::BackgroundWidget::hasBodyCache() const { + return !_bodyCache.isNull(); +} + +void LayerStackWidget::BackgroundWidget::refreshBodyCache( + QPixmap &&bodyCache) { + _bodyCache = std::move(bodyCache); + setAttribute(Qt::WA_OpaquePaintEvent, !_bodyCache.isNull()); +} + void LayerStackWidget::BackgroundWidget::startAnimation(Action action) { if (action == Action::ShowMainMenu) { setMainMenuShown(true); @@ -410,6 +422,25 @@ void LayerStackWidget::hideAll(anim::type animated) { }, Action::HideAll, animated); } +void LayerStackWidget::hideAllAnimatedPrepare() { + prepareAnimation([] {}, [&] { + clearLayers(); + clearSpecialLayer(); + _mainMenu.destroy(); + }, Action::HideAll, anim::type::normal); +} + +void LayerStackWidget::hideAllAnimatedRun() { + if (_background->hasBodyCache()) { + removeBodyCache(); + hideChildren(); + auto bodyCache = Ui::GrabWidget(parentWidget()); + showChildren(); + _background->refreshBodyCache(std::move(bodyCache)); + } + _background->startAnimation(Action::HideAll); +} + void LayerStackWidget::hideTopLayer(anim::type animated) { if (_specialLayer || _mainMenu) { hideLayers(animated); @@ -548,9 +579,9 @@ bool LayerStackWidget::contentOverlapped(const QRect &globalRect) { } template -void LayerStackWidget::startAnimation( - SetupNew setupNewWidgets, - ClearOld clearOldWidgets, +bool LayerStackWidget::prepareAnimation( + SetupNew &&setupNewWidgets, + ClearOld &&clearOldWidgets, Action action, anim::type animated) { if (animated == anim::type::instant) { @@ -565,9 +596,26 @@ void LayerStackWidget::startAnimation( clearOldWidgets(); if (weak) { prepareForAnimation(); - _background->startAnimation(action); + return true; } } + return false; +} + +template +void LayerStackWidget::startAnimation( + SetupNew &&setupNewWidgets, + ClearOld &&clearOldWidgets, + Action action, + anim::type animated) { + const auto alive = prepareAnimation( + std::forward(setupNewWidgets), + std::forward(clearOldWidgets), + action, + animated); + if (alive) { + _background->startAnimation(action); + } } void LayerStackWidget::resizeEvent(QResizeEvent *e) { diff --git a/ui/layers/layer_widget.h b/ui/layers/layer_widget.h index 02f6b1c..94344a0 100644 --- a/ui/layers/layer_widget.h +++ b/ui/layers/layer_widget.h @@ -117,6 +117,10 @@ public: void setHideByBackgroundClick(bool hide); void removeBodyCache(); + // If you need to divide animated hideAll(). + void hideAllAnimatedPrepare(); + void hideAllAnimatedRun(); + bool showSectionInternal( not_null<::Window::SectionMemento*> memento, const ::Window::SectionShow ¶ms); @@ -158,9 +162,15 @@ private: HideAll, }; template + bool prepareAnimation( + SetupNew &&setupNewWidgets, + ClearOld &&clearOldWidgets, + Action action, + anim::type animated); + template void startAnimation( - SetupNew setupNewWidgets, - ClearOld clearOldWidgets, + SetupNew &&setupNewWidgets, + ClearOld &&clearOldWidgets, Action action, anim::type animated);