Implement BoxShow as a wrapper around long-living *Show.
This commit is contained in:
parent
f3744c4ba3
commit
849a840503
10 changed files with 145 additions and 25 deletions
|
|
@ -317,37 +317,65 @@ void BoxContent::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
BoxShow::BoxShow(not_null<Ui::BoxContent*> box)
|
||||
: Show()
|
||||
, _weak(Ui::MakeWeak(box.get())) {
|
||||
BoxShow::BoxShow(not_null<BoxContent*> box)
|
||||
: BoxShow(MakeWeak(box.get()), nullptr) {
|
||||
}
|
||||
|
||||
BoxShow::BoxShow(const BoxShow &other)
|
||||
: BoxShow(other._weak, other._wrapped) {
|
||||
}
|
||||
|
||||
BoxShow::BoxShow(QPointer<BoxContent> weak, ShowPtr wrapped)
|
||||
: _weak(weak)
|
||||
, _wrapped(std::move(wrapped)) {
|
||||
if (!resolve()) {
|
||||
if (const auto box = _weak.data()) {
|
||||
box->boxClosing(
|
||||
) | rpl::start_with_next([=] {
|
||||
resolve();
|
||||
_lifetime.destroy();
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BoxShow::~BoxShow() = default;
|
||||
|
||||
bool BoxShow::resolve() const {
|
||||
if (_wrapped) {
|
||||
return true;
|
||||
} else if (const auto strong = _weak.data()) {
|
||||
if (strong->hasDelegate()) {
|
||||
_wrapped = strong->getDelegate()->showFactory()();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BoxShow::showBox(
|
||||
object_ptr<BoxContent> content,
|
||||
LayerOptions options) const {
|
||||
if (const auto strong = _weak.data()) {
|
||||
strong->getDelegate()->show(std::move(content), options);
|
||||
if (resolve()) {
|
||||
_wrapped->showBox(std::move(content), options);
|
||||
}
|
||||
}
|
||||
|
||||
void BoxShow::hideLayer() const {
|
||||
if (const auto strong = _weak.data()) {
|
||||
strong->getDelegate()->hideLayer();
|
||||
if (resolve()) {
|
||||
_wrapped->hideLayer();
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> BoxShow::toastParent() const {
|
||||
if (!_toastParent) {
|
||||
Assert(_weak != nullptr);
|
||||
_toastParent = Ui::MakeWeak(_weak->window()); // =(
|
||||
if (resolve()) {
|
||||
return _wrapped->toastParent();
|
||||
}
|
||||
return _toastParent.data();
|
||||
Unexpected("Stale BoxShow::toastParent call.");
|
||||
}
|
||||
|
||||
bool BoxShow::valid() const {
|
||||
return _weak;
|
||||
return resolve() && _wrapped->valid();
|
||||
}
|
||||
|
||||
BoxShow::operator bool() const {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
virtual ShowFactory showFactory() = 0;
|
||||
virtual QPointer<QWidget> outerContainer() = 0;
|
||||
|
||||
};
|
||||
|
|
@ -190,6 +191,9 @@ public:
|
|||
prepare();
|
||||
finishPrepare();
|
||||
}
|
||||
[[nodiscard]] bool hasDelegate() const {
|
||||
return _delegate != nullptr;
|
||||
}
|
||||
[[nodiscard]] not_null<BoxContentDelegate*> getDelegate() const {
|
||||
return _delegate;
|
||||
}
|
||||
|
|
@ -352,6 +356,7 @@ private:
|
|||
class BoxShow : public Show {
|
||||
public:
|
||||
explicit BoxShow(not_null<Ui::BoxContent*> box);
|
||||
BoxShow(const BoxShow &other);
|
||||
~BoxShow();
|
||||
void showBox(
|
||||
object_ptr<BoxContent> content,
|
||||
|
|
@ -360,9 +365,16 @@ public:
|
|||
[[nodiscard]] not_null<QWidget*> toastParent() const override;
|
||||
[[nodiscard]] bool valid() const override;
|
||||
operator bool() const override;
|
||||
|
||||
private:
|
||||
mutable QPointer<QWidget> _toastParent;
|
||||
BoxShow(QPointer<BoxContent> weak, ShowPtr wrapped);
|
||||
|
||||
bool resolve() const;
|
||||
|
||||
const QPointer<Ui::BoxContent> _weak;
|
||||
mutable std::shared_ptr<Show> _wrapped;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -238,6 +238,10 @@ void BoxLayerWidget::updateButtonsPositions() {
|
|||
}
|
||||
}
|
||||
|
||||
ShowFactory BoxLayerWidget::showFactory() {
|
||||
return _layer->showFactory();
|
||||
}
|
||||
|
||||
QPointer<QWidget> BoxLayerWidget::outerContainer() {
|
||||
return parentWidget();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public:
|
|||
void addTopButton(object_ptr<AbstractButton> button) override;
|
||||
void showLoading(bool show) override;
|
||||
void updateButtonsPositions() override;
|
||||
ShowFactory showFactory() override;
|
||||
QPointer<QWidget> outerContainer() override;
|
||||
|
||||
void setDimensions(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,67 @@
|
|||
//
|
||||
#include "ui/layers/layer_manager.h"
|
||||
|
||||
#include "ui/layers/show.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
class 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;
|
||||
[[nodiscard]] not_null<QWidget*> toastParent() const override;
|
||||
[[nodiscard]] bool valid() const override;
|
||||
operator bool() const override;
|
||||
|
||||
private:
|
||||
const base::weak_ptr<LayerManager> _manager;
|
||||
|
||||
};
|
||||
|
||||
ManagerShow::ManagerShow(not_null<LayerManager*> manager)
|
||||
: _manager(manager.get()) {
|
||||
}
|
||||
|
||||
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 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 {
|
||||
const auto manager = _manager.get();
|
||||
|
||||
Ensures(manager != nullptr);
|
||||
return manager->toastParent();
|
||||
}
|
||||
|
||||
bool ManagerShow::valid() const {
|
||||
return (_manager.get() != nullptr);
|
||||
}
|
||||
|
||||
ManagerShow::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LayerManager::LayerManager(not_null<RpWidget*> widget) : _widget(widget) {
|
||||
}
|
||||
|
|
@ -67,7 +127,9 @@ void LayerManager::ensureLayerCreated() {
|
|||
if (_layer) {
|
||||
return;
|
||||
}
|
||||
_layer.emplace(_widget);
|
||||
_layer.emplace(_widget, crl::guard(this, [=] {
|
||||
return std::make_shared<ManagerShow>(this);
|
||||
}));
|
||||
_layer->setHideByBackgroundClick(_hideByBackgroundClick);
|
||||
_layer->setStyleOverrides(_boxSt, _layerSt);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "ui/layers/layer_widget.h"
|
||||
|
||||
#include <QtCore/QMargins>
|
||||
|
|
@ -19,7 +20,7 @@ namespace Ui {
|
|||
class BoxContent;
|
||||
class RpWidget;
|
||||
|
||||
class LayerManager final {
|
||||
class LayerManager final : public base::has_weak_ptr {
|
||||
public:
|
||||
explicit LayerManager(not_null<RpWidget*> widget);
|
||||
|
||||
|
|
@ -36,7 +37,10 @@ public:
|
|||
void raise();
|
||||
bool setFocus();
|
||||
|
||||
const LayerWidget *topShownLayer() const;
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> toastParent() const {
|
||||
return _widget;
|
||||
}
|
||||
[[nodiscard]] const LayerWidget *topShownLayer() const;
|
||||
|
||||
private:
|
||||
void ensureLayerCreated();
|
||||
|
|
|
|||
|
|
@ -324,9 +324,10 @@ void LayerStackWidget::BackgroundWidget::animationCallback() {
|
|||
checkIfDone();
|
||||
}
|
||||
|
||||
LayerStackWidget::LayerStackWidget(QWidget *parent)
|
||||
LayerStackWidget::LayerStackWidget(QWidget *parent, ShowFactory showFactory)
|
||||
: RpWidget(parent)
|
||||
, _background(this) {
|
||||
, _background(this)
|
||||
, _showFactory(std::move(showFactory)) {
|
||||
setGeometry(parentWidget()->rect());
|
||||
hide();
|
||||
_background->setDoneCallback([this] { animationDone(); });
|
||||
|
|
|
|||
|
|
@ -32,7 +32,11 @@ enum class LayerOption {
|
|||
using LayerOptions = base::flags<LayerOption>;
|
||||
inline constexpr auto is_flag_type(LayerOption) { return true; };
|
||||
|
||||
class LayerWidget : public Ui::RpWidget {
|
||||
class Show;
|
||||
using ShowPtr = std::shared_ptr<Show>;
|
||||
using ShowFactory = Fn<ShowPtr()>;
|
||||
|
||||
class LayerWidget : public RpWidget {
|
||||
public:
|
||||
using RpWidget::RpWidget;
|
||||
|
||||
|
|
@ -91,9 +95,9 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class LayerStackWidget : public Ui::RpWidget {
|
||||
class LayerStackWidget : public RpWidget {
|
||||
public:
|
||||
LayerStackWidget(QWidget *parent);
|
||||
LayerStackWidget(QWidget *parent, ShowFactory showFactory);
|
||||
|
||||
void finishAnimating();
|
||||
rpl::producer<> hideFinishEvents() const;
|
||||
|
|
@ -107,6 +111,9 @@ public:
|
|||
[[nodiscard]] const style::Box *boxStyleOverride() const {
|
||||
return _boxSt;
|
||||
}
|
||||
[[nodiscard]] ShowFactory showFactory() const {
|
||||
return _showFactory;
|
||||
}
|
||||
|
||||
void showBox(
|
||||
object_ptr<BoxContent> box,
|
||||
|
|
@ -222,6 +229,8 @@ private:
|
|||
class BackgroundWidget;
|
||||
object_ptr<BackgroundWidget> _background;
|
||||
|
||||
ShowFactory _showFactory;
|
||||
|
||||
const style::Box *_boxSt = nullptr;
|
||||
const style::Box *_layerSt = nullptr;
|
||||
bool _hideByBackgroundClick = true;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,4 @@ public:
|
|||
|
||||
inline Show::~Show() = default;
|
||||
|
||||
using ShowPtr = std::shared_ptr<Show>;
|
||||
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -425,7 +425,9 @@ void SeparatePanel::ensureLayerCreated() {
|
|||
if (_layer) {
|
||||
return;
|
||||
}
|
||||
_layer = base::make_unique_q<Ui::LayerStackWidget>(_body);
|
||||
_layer = base::make_unique_q<Ui::LayerStackWidget>(
|
||||
_body,
|
||||
crl::guard(this, [=] { return std::make_shared<PanelShow>(this); }));
|
||||
_layer->setHideByBackgroundClick(false);
|
||||
_layer->move(0, 0);
|
||||
_body->sizeValue(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue