Improve and unify Ui::Show interface.

This commit is contained in:
John Preston 2023-05-19 20:47:23 +04:00
parent f86d876eff
commit a7b6b97bd7
7 changed files with 189 additions and 80 deletions

View file

@ -26,10 +26,13 @@ public:
explicit BoxShow(not_null<Ui::BoxContent*> box); explicit BoxShow(not_null<Ui::BoxContent*> box);
~BoxShow(); ~BoxShow();
void showBox( void showOrHideBoxOrLayer(
object_ptr<BoxContent> content, std::variant<
LayerOptions options = LayerOption::KeepOther) const override; v::null_t,
void hideLayer() const override; object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const override;
[[nodiscard]] not_null<QWidget*> toastParent() const override; [[nodiscard]] not_null<QWidget*> toastParent() const override;
[[nodiscard]] bool valid() const override; [[nodiscard]] bool valid() const override;
operator bool() const override; operator bool() const override;
@ -77,17 +80,15 @@ bool BoxShow::resolve() const {
return false; return false;
} }
void BoxShow::showBox( void BoxShow::showOrHideBoxOrLayer(
object_ptr<BoxContent> content, std::variant<
LayerOptions options) const { v::null_t,
object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const {
if (resolve()) { if (resolve()) {
_wrapped->showBox(std::move(content), options); _wrapped->showOrHideBoxOrLayer(std::move(layer), options, animated);
}
}
void BoxShow::hideLayer() const {
if (resolve()) {
_wrapped->hideLayer();
} }
} }

View file

@ -9,16 +9,19 @@
#include "ui/layers/show.h" #include "ui/layers/show.h"
namespace Ui { namespace Ui {
namespace {
class ManagerShow final : public Show { class LayerManager::ManagerShow final : public Show {
public: public:
explicit ManagerShow(not_null<LayerManager*> manager); explicit ManagerShow(not_null<LayerManager*> manager);
~ManagerShow(); ~ManagerShow();
void showBox(
object_ptr<Ui::BoxContent> content, void showOrHideBoxOrLayer(
Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override; std::variant<
void hideLayer() const override; v::null_t,
object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const override;
[[nodiscard]] not_null<QWidget*> toastParent() const override; [[nodiscard]] not_null<QWidget*> toastParent() const override;
[[nodiscard]] bool valid() const override; [[nodiscard]] bool valid() const override;
operator bool() const override; operator bool() const override;
@ -28,46 +31,49 @@ private:
}; };
ManagerShow::ManagerShow(not_null<LayerManager*> manager) LayerManager::ManagerShow::ManagerShow(not_null<LayerManager*> manager)
: _manager(manager.get()) { : _manager(manager.get()) {
} }
ManagerShow::~ManagerShow() = default; LayerManager::ManagerShow::~ManagerShow() = default;
void ManagerShow::showBox( void LayerManager::ManagerShow::showOrHideBoxOrLayer(
object_ptr<Ui::BoxContent> content, std::variant<
Ui::LayerOptions options) const { v::null_t,
if (const auto manager = _manager.get()) { object_ptr<BoxContent>,
manager->showBox(std::move(content), options, anim::type::normal); std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const {
using UniqueLayer = std::unique_ptr<Ui::LayerWidget>;
using ObjectBox = object_ptr<Ui::BoxContent>;
if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
if (const auto manager = _manager.get()) {
manager->showLayer(std::move(*layerWidget), options, animated);
}
} else if (auto box = std::get_if<ObjectBox>(&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 { not_null<QWidget*> LayerManager::ManagerShow::toastParent() const {
if (const auto manager = _manager.get()) {
manager->showBox(
object_ptr<Ui::BoxContent>{ nullptr },
Ui::LayerOption::CloseOther,
anim::type::normal);
}
}
not_null<QWidget*> ManagerShow::toastParent() const {
const auto manager = _manager.get(); const auto manager = _manager.get();
Ensures(manager != nullptr); Ensures(manager != nullptr);
return manager->toastParent(); return manager->toastParent();
} }
bool ManagerShow::valid() const { bool LayerManager::ManagerShow::valid() const {
return (_manager.get() != nullptr); return (_manager.get() != nullptr);
} }
ManagerShow::operator bool() const { LayerManager::ManagerShow::operator bool() const {
return valid(); return valid();
} }
} // namespace
LayerManager::LayerManager(not_null<RpWidget*> widget) LayerManager::LayerManager(not_null<RpWidget*> widget)
: _widget(widget) { : _widget(widget) {
} }
@ -98,6 +104,15 @@ void LayerManager::showBox(
setFocus(); setFocus();
} }
void LayerManager::showLayer(
std::unique_ptr<LayerWidget> layer,
LayerOptions options,
anim::type animated) {
ensureLayerCreated();
_layer->showLayer(std::move(layer), options, animated);
setFocus();
}
void LayerManager::hideAll(anim::type animated) { void LayerManager::hideAll(anim::type animated) {
if (animated == anim::type::instant) { if (animated == anim::type::instant) {
destroyLayer(); destroyLayer();
@ -120,6 +135,13 @@ bool LayerManager::setFocus() {
return true; return true;
} }
std::shared_ptr<Show> LayerManager::uiShow() {
if (!_cachedShow) {
_cachedShow = std::make_shared<ManagerShow>(this);
}
return _cachedShow;
}
const LayerWidget *LayerManager::topShownLayer() const { const LayerWidget *LayerManager::topShownLayer() const {
return _layer ? _layer->topShownLayer() : nullptr; return _layer ? _layer->topShownLayer() : nullptr;
} }
@ -129,7 +151,7 @@ void LayerManager::ensureLayerCreated() {
return; return;
} }
_layer.emplace(_widget, crl::guard(this, [=] { _layer.emplace(_widget, crl::guard(this, [=] {
return std::make_shared<ManagerShow>(this); return uiShow();
})); }));
_layer->setHideByBackgroundClick(_hideByBackgroundClick); _layer->setHideByBackgroundClick(_hideByBackgroundClick);
_layer->setStyleOverrides(_boxSt, _layerSt); _layer->setStyleOverrides(_boxSt, _layerSt);

View file

@ -19,6 +19,7 @@ namespace Ui {
class BoxContent; class BoxContent;
class RpWidget; class RpWidget;
class Show;
class LayerManager final : public base::has_weak_ptr { class LayerManager final : public base::has_weak_ptr {
public: public:
@ -33,6 +34,10 @@ public:
object_ptr<BoxContent> box, object_ptr<BoxContent> box,
LayerOptions options = LayerOption::KeepOther, LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type::normal); anim::type animated = anim::type::normal);
void showLayer(
std::unique_ptr<LayerWidget> layer,
LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type::normal);
void hideAll(anim::type animated = anim::type::normal); void hideAll(anim::type animated = anim::type::normal);
void raise(); void raise();
bool setFocus(); bool setFocus();
@ -42,12 +47,17 @@ public:
} }
[[nodiscard]] const LayerWidget *topShownLayer() const; [[nodiscard]] const LayerWidget *topShownLayer() const;
[[nodiscard]] std::shared_ptr<Show> uiShow();
private: private:
class ManagerShow;
void ensureLayerCreated(); void ensureLayerCreated();
void destroyLayer(); void destroyLayer();
const not_null<RpWidget*> _widget; const not_null<RpWidget*> _widget;
base::unique_qptr<LayerStackWidget> _layer; base::unique_qptr<LayerStackWidget> _layer;
std::shared_ptr<ManagerShow> _cachedShow;
const style::Box *_boxSt = nullptr; const style::Box *_boxSt = nullptr;
const style::Box *_layerSt = nullptr; const style::Box *_layerSt = nullptr;

View file

@ -15,7 +15,25 @@ using namespace Toast;
} // namespace } // namespace
base::weak_ptr<Instance> Show::showToast(Config &&config) { void Show::showBox(
object_ptr<BoxContent> content,
LayerOptions options,
anim::type animated) const {
return showOrHideBoxOrLayer(std::move(content), options, animated);
}
void Show::showLayer(
std::unique_ptr<LayerWidget> 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<Instance> Show::showToast(Config &&config) const {
if (const auto strong = _lastToast.get()) { if (const auto strong = _lastToast.get()) {
strong->hideAnimated(); strong->hideAnimated();
} }
@ -27,13 +45,13 @@ base::weak_ptr<Instance> Show::showToast(Config &&config) {
base::weak_ptr<Instance> Show::showToast( base::weak_ptr<Instance> Show::showToast(
TextWithEntities &&text, TextWithEntities &&text,
crl::time duration) { crl::time duration) const {
return showToast({ .text = std::move(text), .duration = duration }); return showToast({ .text = std::move(text), .duration = duration });
} }
base::weak_ptr<Instance> Show::showToast( base::weak_ptr<Instance> Show::showToast(
const QString &text, const QString &text,
crl::time duration) { crl::time duration) const {
return showToast({ return showToast({
.text = TextWithEntities{ text }, .text = TextWithEntities{ text },
.duration = duration, .duration = duration,

View file

@ -11,6 +11,10 @@
struct TextWithEntities; struct TextWithEntities;
namespace anim {
enum class type : uchar;
} // namespace anim
namespace Ui::Toast { namespace Ui::Toast {
struct Config; struct Config;
class Instance; class Instance;
@ -19,30 +23,56 @@ class Instance;
namespace Ui { namespace Ui {
class BoxContent; class BoxContent;
class LayerWidget;
inline constexpr auto kZOrderBasic = 0; inline constexpr auto kZOrderBasic = 0;
class Show { class Show {
public: public:
virtual ~Show() = 0; virtual ~Show() = 0;
virtual void showBox( virtual void showOrHideBoxOrLayer(
object_ptr<BoxContent> content, std::variant<
LayerOptions options = LayerOption::KeepOther) const = 0; v::null_t,
virtual void hideLayer() const = 0; object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const = 0;
[[nodiscard]] virtual not_null<QWidget*> toastParent() const = 0; [[nodiscard]] virtual not_null<QWidget*> toastParent() const = 0;
[[nodiscard]] virtual bool valid() const = 0; [[nodiscard]] virtual bool valid() const = 0;
virtual operator bool() const = 0; virtual operator bool() const = 0;
base::weak_ptr<Toast::Instance> showToast(Toast::Config &&config); void showBox(
object_ptr<BoxContent> content,
LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type()) const;
void showLayer(
std::unique_ptr<LayerWidget> layer,
LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type()) const;
void hideLayer(anim::type animated = anim::type()) const;
base::weak_ptr<Toast::Instance> showToast(Toast::Config &&config) const;
base::weak_ptr<Toast::Instance> showToast( base::weak_ptr<Toast::Instance> showToast(
TextWithEntities &&text, TextWithEntities &&text,
crl::time duration = 0); crl::time duration = 0) const;
base::weak_ptr<Toast::Instance> showToast( base::weak_ptr<Toast::Instance> showToast(
const QString &text, const QString &text,
crl::time duration = 0); crl::time duration = 0) const;
template <
typename BoxType,
typename = std::enable_if_t<std::is_base_of_v<BoxContent, BoxType>>>
QPointer<BoxType> show(
object_ptr<BoxType> content,
LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type()) const {
auto result = QPointer<BoxType>(content.data());
showBox(std::move(content), options, animated);
return result;
}
private: private:
base::weak_ptr<Toast::Instance> _lastToast; mutable base::weak_ptr<Toast::Instance> _lastToast;
}; };

View file

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/padding_wrap.h" #include "ui/wrap/padding_wrap.h"
#include "ui/wrap/fade_wrap.h" #include "ui/wrap/fade_wrap.h"
#include "ui/platform/ui_platform_utility.h" #include "ui/platform/ui_platform_utility.h"
#include "ui/layers/box_content.h"
#include "ui/layers/layer_widget.h" #include "ui/layers/layer_widget.h"
#include "ui/layers/show.h" #include "ui/layers/show.h"
#include "ui/painter.h" #include "ui/painter.h"
@ -36,10 +37,14 @@ class PanelShow final : public Show {
public: public:
explicit PanelShow(not_null<SeparatePanel*> panel); explicit PanelShow(not_null<SeparatePanel*> panel);
~PanelShow(); ~PanelShow();
void showBox(
object_ptr<Ui::BoxContent> content, void showOrHideBoxOrLayer(
Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override; std::variant<
void hideLayer() const override; v::null_t,
object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const;
[[nodiscard]] not_null<QWidget*> toastParent() const override; [[nodiscard]] not_null<QWidget*> toastParent() const override;
[[nodiscard]] bool valid() const override; [[nodiscard]] bool valid() const override;
operator bool() const override; operator bool() const override;
@ -55,20 +60,25 @@ PanelShow::PanelShow(not_null<SeparatePanel*> panel)
PanelShow::~PanelShow() = default; PanelShow::~PanelShow() = default;
void PanelShow::showBox( void PanelShow::showOrHideBoxOrLayer(
object_ptr<Ui::BoxContent> content, std::variant<
Ui::LayerOptions options) const { v::null_t,
if (const auto panel = _panel.data()) { object_ptr<BoxContent>,
panel->showBox(std::move(content), options, anim::type::normal); std::unique_ptr<LayerWidget>> &&layer,
} LayerOptions options,
} anim::type animated) const {
using UniqueLayer = std::unique_ptr<LayerWidget>;
void PanelShow::hideLayer() const { using ObjectBox = object_ptr<BoxContent>;
if (const auto panel = _panel.data()) { if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
panel->showBox( if (const auto panel = _panel.data()) {
object_ptr<Ui::BoxContent>{ nullptr }, panel->showLayer(std::move(*layerWidget), options, animated);
Ui::LayerOption::CloseOther, }
anim::type::normal); } else if (auto box = std::get_if<ObjectBox>(&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( void SeparatePanel::showBox(
object_ptr<Ui::BoxContent> box, object_ptr<BoxContent> box,
Ui::LayerOptions options, LayerOptions options,
anim::type animated) { anim::type animated) {
if (box) { Expects(box != nullptr);
ensureLayerCreated();
_layer->showBox(std::move(box), options, animated); ensureLayerCreated();
} else if (_layer) { _layer->showBox(std::move(box), options, animated);
}
void SeparatePanel::showLayer(
std::unique_ptr<LayerWidget> 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); _layer->hideAll(animated);
} }
} }

View file

@ -31,6 +31,7 @@ class BoxContent;
class IconButton; class IconButton;
class PopupMenu; class PopupMenu;
class LayerStackWidget; class LayerStackWidget;
class LayerWidget;
class FlatLabel; class FlatLabel;
template <typename Widget> template <typename Widget>
class FadeWrapScaled; class FadeWrapScaled;
@ -59,9 +60,11 @@ public:
object_ptr<BoxContent> box, object_ptr<BoxContent> box,
LayerOptions options, LayerOptions options,
anim::type animated); anim::type animated);
void destroyLayer(); void showLayer(
std::unique_ptr<LayerWidget> layer,
[[nodiscard]] bool animationsPaused(int zorder) const; LayerOptions options,
anim::type animated);
void hideLayer(anim::type animated);
[[nodiscard]] rpl::producer<> backRequests() const; [[nodiscard]] rpl::producer<> backRequests() const;
[[nodiscard]] rpl::producer<> closeRequests() const; [[nodiscard]] rpl::producer<> closeRequests() const;
@ -103,6 +106,7 @@ private:
void createBorderImage(); void createBorderImage();
void opacityCallback(); void opacityCallback();
void ensureLayerCreated(); void ensureLayerCreated();
void destroyLayer();
void updateTitleGeometry(int newWidth); void updateTitleGeometry(int newWidth);
void updateTitlePosition(); void updateTitlePosition();