Simplify working with Ui::Show and toasts.
This commit is contained in:
parent
7c9aa94533
commit
b850852221
12 changed files with 242 additions and 169 deletions
|
|
@ -97,6 +97,7 @@ PRIVATE
|
|||
ui/layers/layer_manager.h
|
||||
ui/layers/layer_widget.cpp
|
||||
ui/layers/layer_widget.h
|
||||
ui/layers/show.cpp
|
||||
ui/layers/show.h
|
||||
ui/paint/arcs.cpp
|
||||
ui/paint/arcs.h
|
||||
|
|
@ -180,8 +181,6 @@ PRIVATE
|
|||
ui/toast/toast_manager.h
|
||||
ui/toast/toast_widget.cpp
|
||||
ui/toast/toast_widget.h
|
||||
ui/toasts/common_toasts.cpp
|
||||
ui/toasts/common_toasts.h
|
||||
ui/widgets/box_content_divider.cpp
|
||||
ui/widgets/box_content_divider.h
|
||||
ui/widgets/buttons.cpp
|
||||
|
|
|
|||
|
|
@ -19,6 +19,98 @@
|
|||
#include "styles/palette.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
class BoxShow final : public Show {
|
||||
public:
|
||||
explicit BoxShow(not_null<Ui::BoxContent*> box);
|
||||
BoxShow(const BoxShow &other);
|
||||
~BoxShow();
|
||||
void showBox(
|
||||
object_ptr<BoxContent> content,
|
||||
LayerOptions options = 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:
|
||||
BoxShow(QPointer<BoxContent> weak, ShowPtr wrapped);
|
||||
|
||||
bool resolve() const;
|
||||
|
||||
const QPointer<Ui::BoxContent> _weak;
|
||||
mutable std::shared_ptr<Show> _wrapped;
|
||||
rpl::lifetime _lifetime;
|
||||
|
||||
};
|
||||
|
||||
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 (resolve()) {
|
||||
_wrapped->showBox(std::move(content), options);
|
||||
}
|
||||
}
|
||||
|
||||
void BoxShow::hideLayer() const {
|
||||
if (resolve()) {
|
||||
_wrapped->hideLayer();
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> BoxShow::toastParent() const {
|
||||
if (resolve()) {
|
||||
return _wrapped->toastParent();
|
||||
}
|
||||
Unexpected("Stale BoxShow::toastParent call.");
|
||||
}
|
||||
|
||||
bool BoxShow::valid() const {
|
||||
return resolve() && _wrapped->valid();
|
||||
}
|
||||
|
||||
BoxShow::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void BoxContent::setTitle(rpl::producer<QString> title) {
|
||||
getDelegate()->setTitle(std::move(title) | Text::ToWithEntities());
|
||||
|
|
@ -197,6 +289,27 @@ int BoxContent::scrollHeight() const {
|
|||
return _scroll ? _scroll->height() : 0;
|
||||
}
|
||||
|
||||
base::weak_ptr<Toast::Instance> BoxContent::showToast(
|
||||
Toast::Config &&config) {
|
||||
return BoxShow(this).showToast(std::move(config));
|
||||
}
|
||||
|
||||
base::weak_ptr<Toast::Instance> BoxContent::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return BoxShow(this).showToast(std::move(text), duration);
|
||||
}
|
||||
|
||||
base::weak_ptr<Toast::Instance> BoxContent::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return BoxShow(this).showToast(text, duration);
|
||||
}
|
||||
|
||||
std::shared_ptr<Show> BoxContent::uiShow() {
|
||||
return std::make_shared<BoxShow>(this);
|
||||
}
|
||||
|
||||
void BoxContent::scrollByDraggingDelta(int delta) {
|
||||
_draggingScroll.checkDeltaScroll(_scroll ? delta : 0);
|
||||
}
|
||||
|
|
@ -335,69 +448,4 @@ void BoxContent::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
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 (resolve()) {
|
||||
_wrapped->showBox(std::move(content), options);
|
||||
}
|
||||
}
|
||||
|
||||
void BoxShow::hideLayer() const {
|
||||
if (resolve()) {
|
||||
_wrapped->hideLayer();
|
||||
}
|
||||
}
|
||||
|
||||
not_null<QWidget*> BoxShow::toastParent() const {
|
||||
if (resolve()) {
|
||||
return _wrapped->toastParent();
|
||||
}
|
||||
Unexpected("Stale BoxShow::toastParent call.");
|
||||
}
|
||||
|
||||
bool BoxShow::valid() const {
|
||||
return resolve() && _wrapped->valid();
|
||||
}
|
||||
|
||||
BoxShow::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ namespace st {
|
|||
extern const style::ScrollArea &boxScroll;
|
||||
} // namespace st
|
||||
|
||||
namespace Ui::Toast {
|
||||
struct Config;
|
||||
class Instance;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Ui {
|
||||
class GenericBox;
|
||||
} // namespace Ui
|
||||
|
|
@ -101,7 +106,6 @@ public:
|
|||
};
|
||||
|
||||
class BoxContent : public RpWidget {
|
||||
|
||||
public:
|
||||
BoxContent() {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
|
@ -214,6 +218,16 @@ public:
|
|||
[[nodiscard]] int scrollTop() const;
|
||||
[[nodiscard]] int scrollHeight() const;
|
||||
|
||||
base::weak_ptr<Toast::Instance> showToast(Toast::Config &&config);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Show> uiShow();
|
||||
|
||||
protected:
|
||||
virtual void prepare() = 0;
|
||||
|
||||
|
|
@ -357,28 +371,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class BoxShow : public Show {
|
||||
public:
|
||||
explicit BoxShow(not_null<Ui::BoxContent*> box);
|
||||
BoxShow(const BoxShow &other);
|
||||
~BoxShow();
|
||||
void showBox(
|
||||
object_ptr<BoxContent> content,
|
||||
LayerOptions options = 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:
|
||||
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
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ ManagerShow::operator bool() const {
|
|||
|
||||
} // namespace
|
||||
|
||||
LayerManager::LayerManager(not_null<RpWidget*> widget) : _widget(widget) {
|
||||
LayerManager::LayerManager(not_null<RpWidget*> widget)
|
||||
: _widget(widget) {
|
||||
}
|
||||
|
||||
void LayerManager::setStyleOverrides(
|
||||
|
|
|
|||
43
ui/layers/show.cpp
Normal file
43
ui/layers/show.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// This file is part of Desktop App Toolkit,
|
||||
// a set of libraries for developing nice desktop applications.
|
||||
//
|
||||
// For license and copyright information please follow this link:
|
||||
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
||||
//
|
||||
#include "ui/layers/show.h"
|
||||
|
||||
#include "ui/toast/toast.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
using namespace Toast;
|
||||
|
||||
} // namespace
|
||||
|
||||
base::weak_ptr<Instance> Show::showToast(Config &&config) {
|
||||
if (const auto strong = _lastToast.get()) {
|
||||
strong->hideAnimated();
|
||||
}
|
||||
_lastToast = valid()
|
||||
? Toast::Show(toastParent(), std::move(config))
|
||||
: base::weak_ptr<Instance>();
|
||||
return _lastToast;
|
||||
}
|
||||
|
||||
base::weak_ptr<Instance> Show::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return showToast({ .text = std::move(text), .duration = duration });
|
||||
}
|
||||
|
||||
base::weak_ptr<Instance> Show::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return showToast({
|
||||
.text = TextWithEntities{ text },
|
||||
.duration = duration,
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
@ -6,12 +6,22 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "ui/layers/layer_widget.h"
|
||||
|
||||
struct TextWithEntities;
|
||||
|
||||
namespace Ui::Toast {
|
||||
struct Config;
|
||||
class Instance;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class BoxContent;
|
||||
|
||||
inline constexpr auto kZOrderBasic = 0;
|
||||
|
||||
class Show {
|
||||
public:
|
||||
virtual ~Show() = 0;
|
||||
|
|
@ -22,6 +32,18 @@ public:
|
|||
[[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);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
|
||||
private:
|
||||
base::weak_ptr<Toast::Instance> _lastToast;
|
||||
|
||||
};
|
||||
|
||||
inline Show::~Show() = default;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ Instance::Instance(
|
|||
not_null<QWidget*> widgetParent,
|
||||
const Private &)
|
||||
: _st(config.st)
|
||||
, _hideAt(crl::now() + config.durationMs)
|
||||
, _hideAt(crl::now()
|
||||
+ (config.duration ? config.duration : kDefaultDuration))
|
||||
, _sliding(config.slideSide != RectPart::None)
|
||||
, _widget(std::make_unique<internal::Widget>(widgetParent, config)) {
|
||||
_shownAnimation.start(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ namespace style {
|
|||
struct Toast;
|
||||
} // namespace style
|
||||
|
||||
namespace st {
|
||||
extern const style::Toast &defaultMultilineToast;
|
||||
} // namespace st
|
||||
|
||||
namespace Ui {
|
||||
namespace Toast {
|
||||
|
||||
|
|
@ -30,10 +34,10 @@ using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
|
|||
inline constexpr auto kDefaultDuration = crl::time(1500);
|
||||
struct Config {
|
||||
TextWithEntities text;
|
||||
not_null<const style::Toast*> st;
|
||||
crl::time durationMs = kDefaultDuration;
|
||||
not_null<const style::Toast*> st = &st::defaultMultilineToast;
|
||||
crl::time duration = kDefaultDuration;
|
||||
int maxLines = 16;
|
||||
bool multiline = false;
|
||||
bool multiline = true;
|
||||
bool dark = false;
|
||||
RectPart slideSide = RectPart::None;
|
||||
ClickHandlerFilter filter;
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
|
||||
#include "ui/toast/toast.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
base::weak_ptr<Toast::Instance> ShowMultilineToast(
|
||||
MultilineToastArgs &&args) {
|
||||
auto config = Ui::Toast::Config{
|
||||
.text = std::move(args.text),
|
||||
.st = &st::defaultMultilineToast,
|
||||
.durationMs = (args.duration
|
||||
? args.duration
|
||||
: Ui::Toast::kDefaultDuration),
|
||||
.multiline = true,
|
||||
.filter = std::move(args.filter),
|
||||
};
|
||||
return args.parentOverride
|
||||
? Ui::Toast::Show(args.parentOverride, std::move(config))
|
||||
: Ui::Toast::Show(std::move(config));
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/text/text_entity.h"
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
class ClickHandler;
|
||||
using ClickHandlerPtr = std::shared_ptr<ClickHandler>;
|
||||
using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
|
||||
|
||||
namespace Ui {
|
||||
namespace Toast {
|
||||
class Instance;
|
||||
} // namespace Toast
|
||||
|
||||
struct MultilineToastArgs {
|
||||
QWidget *parentOverride = nullptr;
|
||||
TextWithEntities text;
|
||||
crl::time duration = 0;
|
||||
ClickHandlerFilter filter;
|
||||
};
|
||||
|
||||
base::weak_ptr<Toast::Instance> ShowMultilineToast(
|
||||
MultilineToastArgs &&args);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/layers/layer_widget.h"
|
||||
#include "ui/layers/show.h"
|
||||
|
|
@ -410,15 +409,25 @@ void SeparatePanel::showBox(
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Show> SeparatePanel::uiShow() {
|
||||
return std::make_shared<PanelShow>(this);
|
||||
base::weak_ptr<Toast::Instance> SeparatePanel::showToast(
|
||||
Toast::Config &&config) {
|
||||
return PanelShow(this).showToast(std::move(config));
|
||||
}
|
||||
|
||||
void SeparatePanel::showToast(const TextWithEntities &text) {
|
||||
Ui::ShowMultilineToast({
|
||||
.parentOverride = this,
|
||||
.text = text,
|
||||
});
|
||||
base::weak_ptr<Toast::Instance> SeparatePanel::showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration) {
|
||||
return PanelShow(this).showToast(std::move(text), duration);
|
||||
}
|
||||
|
||||
base::weak_ptr<Toast::Instance> SeparatePanel::showToast(
|
||||
const QString &text,
|
||||
crl::time duration) {
|
||||
return PanelShow(this).showToast(text, duration);
|
||||
}
|
||||
|
||||
std::shared_ptr<Show> SeparatePanel::uiShow() {
|
||||
return std::make_shared<PanelShow>(this);
|
||||
}
|
||||
|
||||
void SeparatePanel::ensureLayerCreated() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/layers/layer_widget.h"
|
||||
|
|
@ -18,6 +19,11 @@ namespace Ui::Menu {
|
|||
struct MenuCallback;
|
||||
} // namespace Ui::Menu
|
||||
|
||||
namespace Ui::Toast {
|
||||
struct Config;
|
||||
class Instance;
|
||||
} // namespace Ui::Toast
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class Show;
|
||||
|
|
@ -32,6 +38,7 @@ class FadeWrapScaled;
|
|||
struct SeparatePanelArgs {
|
||||
QWidget *parent = nullptr;
|
||||
bool onAllSpaces = false;
|
||||
Fn<bool(int zorder)> animationsPaused;
|
||||
};
|
||||
|
||||
class SeparatePanel final : public RpWidget {
|
||||
|
|
@ -52,15 +59,25 @@ public:
|
|||
object_ptr<BoxContent> box,
|
||||
LayerOptions options,
|
||||
anim::type animated);
|
||||
void showToast(const TextWithEntities &text);
|
||||
void destroyLayer();
|
||||
|
||||
[[nodiscard]] bool animationsPaused(int zorder) const;
|
||||
|
||||
[[nodiscard]] rpl::producer<> backRequests() const;
|
||||
[[nodiscard]] rpl::producer<> closeRequests() const;
|
||||
[[nodiscard]] rpl::producer<> closeEvents() const;
|
||||
void setBackAllowed(bool allowed);
|
||||
|
||||
void setMenuAllowed(Fn<void(const Menu::MenuCallback&)> fill);
|
||||
|
||||
base::weak_ptr<Toast::Instance> showToast(Toast::Config &&config);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
TextWithEntities &&text,
|
||||
crl::time duration = 0);
|
||||
base::weak_ptr<Toast::Instance> showToast(
|
||||
const QString &text,
|
||||
crl::time duration = 0);
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Show> uiShow();
|
||||
|
||||
protected:
|
||||
|
|
@ -127,6 +144,8 @@ private:
|
|||
QPixmap _animationCache;
|
||||
QPixmap _borderParts;
|
||||
|
||||
Fn<bool(int zorder)> _animationsPaused;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue