From a7b6b97bd73580a590569f322cec06e5ceb29a4d Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 19 May 2023 20:47:23 +0400 Subject: [PATCH] Improve and unify Ui::Show interface. --- ui/layers/box_content.cpp | 29 ++++++------- ui/layers/layer_manager.cpp | 78 ++++++++++++++++++++++------------- ui/layers/layer_manager.h | 10 +++++ ui/layers/show.cpp | 24 +++++++++-- ui/layers/show.h | 46 +++++++++++++++++---- ui/widgets/separate_panel.cpp | 72 +++++++++++++++++++++----------- ui/widgets/separate_panel.h | 10 +++-- 7 files changed, 189 insertions(+), 80 deletions(-) diff --git a/ui/layers/box_content.cpp b/ui/layers/box_content.cpp index afea011..00ec1b6 100644 --- a/ui/layers/box_content.cpp +++ b/ui/layers/box_content.cpp @@ -26,10 +26,13 @@ public: explicit BoxShow(not_null box); ~BoxShow(); - void showBox( - object_ptr content, - LayerOptions options = LayerOption::KeepOther) const override; - void hideLayer() const override; + void showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const override; [[nodiscard]] not_null toastParent() const override; [[nodiscard]] bool valid() const override; operator bool() const override; @@ -77,17 +80,15 @@ bool BoxShow::resolve() const { return false; } -void BoxShow::showBox( - object_ptr content, - LayerOptions options) const { +void BoxShow::showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const { if (resolve()) { - _wrapped->showBox(std::move(content), options); - } -} - -void BoxShow::hideLayer() const { - if (resolve()) { - _wrapped->hideLayer(); + _wrapped->showOrHideBoxOrLayer(std::move(layer), options, animated); } } diff --git a/ui/layers/layer_manager.cpp b/ui/layers/layer_manager.cpp index 81b2f83..7a22e09 100644 --- a/ui/layers/layer_manager.cpp +++ b/ui/layers/layer_manager.cpp @@ -9,16 +9,19 @@ #include "ui/layers/show.h" namespace Ui { -namespace { -class ManagerShow final : public Show { +class LayerManager::ManagerShow final : public Show { public: explicit ManagerShow(not_null manager); ~ManagerShow(); - void showBox( - object_ptr content, - Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override; - void hideLayer() const override; + + void showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const override; [[nodiscard]] not_null toastParent() const override; [[nodiscard]] bool valid() const override; operator bool() const override; @@ -28,46 +31,49 @@ private: }; -ManagerShow::ManagerShow(not_null manager) +LayerManager::ManagerShow::ManagerShow(not_null manager) : _manager(manager.get()) { } -ManagerShow::~ManagerShow() = default; +LayerManager::ManagerShow::~ManagerShow() = default; -void ManagerShow::showBox( - object_ptr content, - Ui::LayerOptions options) const { - if (const auto manager = _manager.get()) { - manager->showBox(std::move(content), options, anim::type::normal); +void LayerManager::ManagerShow::showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const { + using UniqueLayer = std::unique_ptr; + using ObjectBox = object_ptr; + if (auto layerWidget = std::get_if(&layer)) { + if (const auto manager = _manager.get()) { + manager->showLayer(std::move(*layerWidget), options, animated); + } + } else if (auto box = std::get_if(&layer)) { + if (const auto manager = _manager.get()) { + manager->showBox(std::move(*box), options, animated); + } + } else if (const auto manager = _manager.get()) { + manager->hideAll(animated); } } -void ManagerShow::hideLayer() const { - if (const auto manager = _manager.get()) { - manager->showBox( - object_ptr{ nullptr }, - Ui::LayerOption::CloseOther, - anim::type::normal); - } -} - -not_null ManagerShow::toastParent() const { +not_null LayerManager::ManagerShow::toastParent() const { const auto manager = _manager.get(); Ensures(manager != nullptr); return manager->toastParent(); } -bool ManagerShow::valid() const { +bool LayerManager::ManagerShow::valid() const { return (_manager.get() != nullptr); } -ManagerShow::operator bool() const { +LayerManager::ManagerShow::operator bool() const { return valid(); } -} // namespace - LayerManager::LayerManager(not_null widget) : _widget(widget) { } @@ -98,6 +104,15 @@ void LayerManager::showBox( setFocus(); } +void LayerManager::showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated) { + ensureLayerCreated(); + _layer->showLayer(std::move(layer), options, animated); + setFocus(); +} + void LayerManager::hideAll(anim::type animated) { if (animated == anim::type::instant) { destroyLayer(); @@ -120,6 +135,13 @@ bool LayerManager::setFocus() { return true; } +std::shared_ptr LayerManager::uiShow() { + if (!_cachedShow) { + _cachedShow = std::make_shared(this); + } + return _cachedShow; +} + const LayerWidget *LayerManager::topShownLayer() const { return _layer ? _layer->topShownLayer() : nullptr; } @@ -129,7 +151,7 @@ void LayerManager::ensureLayerCreated() { return; } _layer.emplace(_widget, crl::guard(this, [=] { - return std::make_shared(this); + return uiShow(); })); _layer->setHideByBackgroundClick(_hideByBackgroundClick); _layer->setStyleOverrides(_boxSt, _layerSt); diff --git a/ui/layers/layer_manager.h b/ui/layers/layer_manager.h index ad23a22..a051a11 100644 --- a/ui/layers/layer_manager.h +++ b/ui/layers/layer_manager.h @@ -19,6 +19,7 @@ namespace Ui { class BoxContent; class RpWidget; +class Show; class LayerManager final : public base::has_weak_ptr { public: @@ -33,6 +34,10 @@ public: object_ptr box, LayerOptions options = LayerOption::KeepOther, anim::type animated = anim::type::normal); + void showLayer( + std::unique_ptr layer, + LayerOptions options = LayerOption::KeepOther, + anim::type animated = anim::type::normal); void hideAll(anim::type animated = anim::type::normal); void raise(); bool setFocus(); @@ -42,12 +47,17 @@ public: } [[nodiscard]] const LayerWidget *topShownLayer() const; + [[nodiscard]] std::shared_ptr uiShow(); + private: + class ManagerShow; + void ensureLayerCreated(); void destroyLayer(); const not_null _widget; base::unique_qptr _layer; + std::shared_ptr _cachedShow; const style::Box *_boxSt = nullptr; const style::Box *_layerSt = nullptr; diff --git a/ui/layers/show.cpp b/ui/layers/show.cpp index 8b186aa..f28c64b 100644 --- a/ui/layers/show.cpp +++ b/ui/layers/show.cpp @@ -15,7 +15,25 @@ using namespace Toast; } // namespace -base::weak_ptr Show::showToast(Config &&config) { +void Show::showBox( + object_ptr content, + LayerOptions options, + anim::type animated) const { + return showOrHideBoxOrLayer(std::move(content), options, animated); +} + +void Show::showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated) const { + return showOrHideBoxOrLayer(std::move(layer), options, animated); +} + +void Show::hideLayer(anim::type animated) const { + return showOrHideBoxOrLayer(v::null, LayerOptions(), animated); +} + +base::weak_ptr Show::showToast(Config &&config) const { if (const auto strong = _lastToast.get()) { strong->hideAnimated(); } @@ -27,13 +45,13 @@ base::weak_ptr Show::showToast(Config &&config) { base::weak_ptr Show::showToast( TextWithEntities &&text, - crl::time duration) { + crl::time duration) const { return showToast({ .text = std::move(text), .duration = duration }); } base::weak_ptr Show::showToast( const QString &text, - crl::time duration) { + crl::time duration) const { return showToast({ .text = TextWithEntities{ text }, .duration = duration, diff --git a/ui/layers/show.h b/ui/layers/show.h index c0719b0..37413fd 100644 --- a/ui/layers/show.h +++ b/ui/layers/show.h @@ -11,6 +11,10 @@ struct TextWithEntities; +namespace anim { +enum class type : uchar; +} // namespace anim + namespace Ui::Toast { struct Config; class Instance; @@ -19,30 +23,56 @@ class Instance; namespace Ui { class BoxContent; +class LayerWidget; inline constexpr auto kZOrderBasic = 0; class Show { public: virtual ~Show() = 0; - virtual void showBox( - object_ptr content, - LayerOptions options = LayerOption::KeepOther) const = 0; - virtual void hideLayer() const = 0; + virtual void showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const = 0; [[nodiscard]] virtual not_null toastParent() const = 0; [[nodiscard]] virtual bool valid() const = 0; virtual operator bool() const = 0; - base::weak_ptr showToast(Toast::Config &&config); + void showBox( + object_ptr content, + LayerOptions options = LayerOption::KeepOther, + anim::type animated = anim::type()) const; + void showLayer( + std::unique_ptr layer, + LayerOptions options = LayerOption::KeepOther, + anim::type animated = anim::type()) const; + void hideLayer(anim::type animated = anim::type()) const; + + base::weak_ptr showToast(Toast::Config &&config) const; base::weak_ptr showToast( TextWithEntities &&text, - crl::time duration = 0); + crl::time duration = 0) const; base::weak_ptr showToast( const QString &text, - crl::time duration = 0); + crl::time duration = 0) const; + + template < + typename BoxType, + typename = std::enable_if_t>> + QPointer show( + object_ptr content, + LayerOptions options = LayerOption::KeepOther, + anim::type animated = anim::type()) const { + auto result = QPointer(content.data()); + showBox(std::move(content), options, animated); + return result; + } private: - base::weak_ptr _lastToast; + mutable base::weak_ptr _lastToast; }; diff --git a/ui/widgets/separate_panel.cpp b/ui/widgets/separate_panel.cpp index 621d994..83dc4bb 100644 --- a/ui/widgets/separate_panel.cpp +++ b/ui/widgets/separate_panel.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/padding_wrap.h" #include "ui/wrap/fade_wrap.h" #include "ui/platform/ui_platform_utility.h" +#include "ui/layers/box_content.h" #include "ui/layers/layer_widget.h" #include "ui/layers/show.h" #include "ui/painter.h" @@ -36,10 +37,14 @@ class PanelShow final : public Show { public: explicit PanelShow(not_null panel); ~PanelShow(); - void showBox( - object_ptr content, - Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override; - void hideLayer() const override; + + void showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const; [[nodiscard]] not_null toastParent() const override; [[nodiscard]] bool valid() const override; operator bool() const override; @@ -55,20 +60,25 @@ PanelShow::PanelShow(not_null panel) PanelShow::~PanelShow() = default; -void PanelShow::showBox( - object_ptr content, - Ui::LayerOptions options) const { - if (const auto panel = _panel.data()) { - panel->showBox(std::move(content), options, anim::type::normal); - } -} - -void PanelShow::hideLayer() const { - if (const auto panel = _panel.data()) { - panel->showBox( - object_ptr{ nullptr }, - Ui::LayerOption::CloseOther, - anim::type::normal); +void PanelShow::showOrHideBoxOrLayer( + std::variant< + v::null_t, + object_ptr, + std::unique_ptr> &&layer, + LayerOptions options, + anim::type animated) const { + using UniqueLayer = std::unique_ptr; + using ObjectBox = object_ptr; + if (auto layerWidget = std::get_if(&layer)) { + if (const auto panel = _panel.data()) { + panel->showLayer(std::move(*layerWidget), options, animated); + } + } else if (auto box = std::get_if(&layer)) { + if (const auto panel = _panel.data()) { + panel->showBox(std::move(*box), options, animated); + } + } else if (const auto panel = _panel.data()) { + panel->hideLayer(animated); } } @@ -398,13 +408,27 @@ int SeparatePanel::hideGetDuration() { } void SeparatePanel::showBox( - object_ptr box, - Ui::LayerOptions options, + object_ptr box, + LayerOptions options, anim::type animated) { - if (box) { - ensureLayerCreated(); - _layer->showBox(std::move(box), options, animated); - } else if (_layer) { + Expects(box != nullptr); + + ensureLayerCreated(); + _layer->showBox(std::move(box), options, animated); +} + +void SeparatePanel::showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated) { + Expects(layer != nullptr); + + ensureLayerCreated(); + _layer->showLayer(std::move(layer), options, animated); +} + +void SeparatePanel::hideLayer(anim::type animated) { + if (_layer) { _layer->hideAll(animated); } } diff --git a/ui/widgets/separate_panel.h b/ui/widgets/separate_panel.h index 13745ad..12070b1 100644 --- a/ui/widgets/separate_panel.h +++ b/ui/widgets/separate_panel.h @@ -31,6 +31,7 @@ class BoxContent; class IconButton; class PopupMenu; class LayerStackWidget; +class LayerWidget; class FlatLabel; template class FadeWrapScaled; @@ -59,9 +60,11 @@ public: object_ptr box, LayerOptions options, anim::type animated); - void destroyLayer(); - - [[nodiscard]] bool animationsPaused(int zorder) const; + void showLayer( + std::unique_ptr layer, + LayerOptions options, + anim::type animated); + void hideLayer(anim::type animated); [[nodiscard]] rpl::producer<> backRequests() const; [[nodiscard]] rpl::producer<> closeRequests() const; @@ -103,6 +106,7 @@ private: void createBorderImage(); void opacityCallback(); void ensureLayerCreated(); + void destroyLayer(); void updateTitleGeometry(int newWidth); void updateTitlePosition();