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);
~BoxShow();
void showBox(
object_ptr<BoxContent> content,
LayerOptions options = LayerOption::KeepOther) const override;
void hideLayer() const override;
void showOrHideBoxOrLayer(
std::variant<
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]] bool valid() const override;
operator bool() const override;
@ -77,17 +80,15 @@ bool BoxShow::resolve() const {
return false;
}
void BoxShow::showBox(
object_ptr<BoxContent> content,
LayerOptions options) const {
void BoxShow::showOrHideBoxOrLayer(
std::variant<
v::null_t,
object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&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);
}
}

View file

@ -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<LayerManager*> manager);
~ManagerShow();
void showBox(
object_ptr<Ui::BoxContent> content,
Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override;
void hideLayer() const override;
void showOrHideBoxOrLayer(
std::variant<
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]] bool valid() 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()) {
}
ManagerShow::~ManagerShow() = default;
LayerManager::ManagerShow::~ManagerShow() = default;
void ManagerShow::showBox(
object_ptr<Ui::BoxContent> 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<BoxContent>,
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 {
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 {
not_null<QWidget*> 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<RpWidget*> widget)
: _widget(widget) {
}
@ -98,6 +104,15 @@ void LayerManager::showBox(
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) {
if (animated == anim::type::instant) {
destroyLayer();
@ -120,6 +135,13 @@ bool LayerManager::setFocus() {
return true;
}
std::shared_ptr<Show> LayerManager::uiShow() {
if (!_cachedShow) {
_cachedShow = std::make_shared<ManagerShow>(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<ManagerShow>(this);
return uiShow();
}));
_layer->setHideByBackgroundClick(_hideByBackgroundClick);
_layer->setStyleOverrides(_boxSt, _layerSt);

View file

@ -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<BoxContent> box,
LayerOptions options = LayerOption::KeepOther,
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 raise();
bool setFocus();
@ -42,12 +47,17 @@ public:
}
[[nodiscard]] const LayerWidget *topShownLayer() const;
[[nodiscard]] std::shared_ptr<Show> uiShow();
private:
class ManagerShow;
void ensureLayerCreated();
void destroyLayer();
const not_null<RpWidget*> _widget;
base::unique_qptr<LayerStackWidget> _layer;
std::shared_ptr<ManagerShow> _cachedShow;
const style::Box *_boxSt = nullptr;
const style::Box *_layerSt = nullptr;

View file

@ -15,7 +15,25 @@ using namespace Toast;
} // 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()) {
strong->hideAnimated();
}
@ -27,13 +45,13 @@ base::weak_ptr<Instance> Show::showToast(Config &&config) {
base::weak_ptr<Instance> Show::showToast(
TextWithEntities &&text,
crl::time duration) {
crl::time duration) const {
return showToast({ .text = std::move(text), .duration = duration });
}
base::weak_ptr<Instance> Show::showToast(
const QString &text,
crl::time duration) {
crl::time duration) const {
return showToast({
.text = TextWithEntities{ text },
.duration = duration,

View file

@ -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<BoxContent> content,
LayerOptions options = LayerOption::KeepOther) const = 0;
virtual void hideLayer() const = 0;
virtual void showOrHideBoxOrLayer(
std::variant<
v::null_t,
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 bool valid() 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(
TextWithEntities &&text,
crl::time duration = 0);
crl::time duration = 0) const;
base::weak_ptr<Toast::Instance> showToast(
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:
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/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<SeparatePanel*> panel);
~PanelShow();
void showBox(
object_ptr<Ui::BoxContent> content,
Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override;
void hideLayer() const override;
void showOrHideBoxOrLayer(
std::variant<
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]] bool valid() const override;
operator bool() const override;
@ -55,20 +60,25 @@ PanelShow::PanelShow(not_null<SeparatePanel*> panel)
PanelShow::~PanelShow() = default;
void PanelShow::showBox(
object_ptr<Ui::BoxContent> 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<Ui::BoxContent>{ nullptr },
Ui::LayerOption::CloseOther,
anim::type::normal);
void PanelShow::showOrHideBoxOrLayer(
std::variant<
v::null_t,
object_ptr<BoxContent>,
std::unique_ptr<LayerWidget>> &&layer,
LayerOptions options,
anim::type animated) const {
using UniqueLayer = std::unique_ptr<LayerWidget>;
using ObjectBox = object_ptr<BoxContent>;
if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
if (const auto panel = _panel.data()) {
panel->showLayer(std::move(*layerWidget), options, animated);
}
} 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(
object_ptr<Ui::BoxContent> box,
Ui::LayerOptions options,
object_ptr<BoxContent> 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<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);
}
}

View file

@ -31,6 +31,7 @@ class BoxContent;
class IconButton;
class PopupMenu;
class LayerStackWidget;
class LayerWidget;
class FlatLabel;
template <typename Widget>
class FadeWrapScaled;
@ -59,9 +60,11 @@ public:
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated);
void destroyLayer();
[[nodiscard]] bool animationsPaused(int zorder) const;
void showLayer(
std::unique_ptr<LayerWidget> 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();