/* 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 "styles/style_widgets.h" #include "ui/rp_widget.h" namespace Ui { template class Wrap; namespace details { struct UnwrapHelper { struct Large { char data[2]; }; static char Check(...); template static Large Check(Wrap*); template static Large Check(const Wrap*); template static constexpr bool Is() { return sizeof(Check(std::declval())) == sizeof(Large); } template static auto Unwrap(Entity *entity, std::true_type) { return entity ? entity->entity() : nullptr; } template static Entity *Unwrap(Entity *entity, std::false_type) { return entity; } template static auto Unwrap(Entity *entity) { return Unwrap( entity, std::integral_constant()>()); } }; } // namespace details template class Wrap : public RpWidget { public: Wrap(QWidget *parent, object_ptr child); Widget *wrapped() { return _wrapped; } const Widget *wrapped() const { return _wrapped; } auto entity() { return details::UnwrapHelper::Unwrap(wrapped()); } auto entity() const { return details::UnwrapHelper::Unwrap(wrapped()); } QMargins getMargins() const override { if (auto weak = wrapped()) { return weak->getMargins(); } return RpWidget::getMargins(); } int naturalWidth() const override { if (auto weak = wrapped()) { return weak->naturalWidth(); } return RpWidget::naturalWidth(); } private: object_ptr _wrapped; }; template Wrap::Wrap(QWidget *parent, object_ptr child) : RpWidget(parent) , _wrapped(std::move(child)) { if (_wrapped) { resize(_wrapped->size()); AttachParentChild(this, _wrapped); _wrapped->move(0, 0); _wrapped->alive() | rpl::on_done([this] { _wrapped->setParent(nullptr); _wrapped = nullptr; delete this; }) | rpl::start(lifetime()); } } template class Wrap : public ParentType { public: using ParentType::ParentType; Widget *wrapped() { return static_cast(ParentType::wrapped()); } const Widget *wrapped() const { return static_cast(ParentType::wrapped()); } auto entity() { return details::UnwrapHelper::Unwrap(wrapped()); } auto entity() const { return details::UnwrapHelper::Unwrap(wrapped()); } }; template class PaddingWrap; template <> class PaddingWrap : public Wrap { using Parent = Wrap; public: PaddingWrap( QWidget *parent, object_ptr child, const style::margins &padding); PaddingWrap( QWidget *parent, const style::margins &padding) : PaddingWrap(parent, nullptr, padding) { } int naturalWidth() const override; protected: int resizeGetHeight(int newWidth) override; private: void updateSize(); int _innerWidth = 0; style::margins _padding; }; template class PaddingWrap : public Wrap> { using Parent = Wrap>; public: PaddingWrap( QWidget *parent, object_ptr child, const style::margins &padding) : Parent(parent, std::move(child), padding) { } PaddingWrap(QWidget *parent, const style::margins &padding) : Parent(parent, padding) { } }; template class SlideWrap; template <> class SlideWrap : public Wrap> { using Parent = Wrap>; public: SlideWrap(QWidget *parent, object_ptr child); SlideWrap( QWidget *parent, object_ptr child, const style::margins &padding); SlideWrap( QWidget *parent, object_ptr child, int duration); SlideWrap( QWidget *parent, object_ptr child, const style::margins &padding, int duration); void toggleAnimated(bool visible); void toggleFast(bool visible); void showAnimated() { toggleAnimated(true); } void hideAnimated() { toggleAnimated(false); } void showFast() { toggleFast(true); } void hideFast() { toggleFast(false); } bool animating() const { return _slideAnimation.animating(); } void finishAnimations(); QMargins getMargins() const override; bool isHiddenOrHiding() const { return !_visible; } protected: int resizeGetHeight(int newWidth) override; private: void animationStep(); bool _visible = true; Animation _slideAnimation; int _duration = 0; }; template class SlideWrap : public Wrap, SlideWrap> { using Parent = Wrap, SlideWrap>; public: SlideWrap(QWidget *parent, object_ptr child) : Parent(parent, std::move(child)) { } SlideWrap( QWidget *parent, object_ptr child, const style::margins &padding) : Parent(parent, std::move(child), padding) { } SlideWrap( QWidget *parent, object_ptr child, int duration) : Parent(parent, std::move(child), duration) { } SlideWrap( QWidget *parent, object_ptr child, const style::margins &padding, int duration) : Parent(parent, std::move(child), padding, duration) { } }; } // namespace Ui