| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- // 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
- //
- #pragma once
- #include "ui/rp_widget.h"
- #include "base/object_ptr.h"
- namespace Ui {
- template <typename Widget, typename ParentType = RpWidget>
- class Wrap;
- namespace details {
- struct UnwrapHelper {
- template <
- typename Widget,
- typename = typename std::decay_t<Widget>::WrapParentType>
- static std::true_type Is(Widget &&widget);
- static std::false_type Is(...);
- template <typename Entity>
- static auto Unwrap(Entity *entity, std::true_type) {
- return entity
- ? entity->entity()
- : nullptr;
- }
- template <typename Entity>
- static Entity *Unwrap(Entity *entity, std::false_type) {
- return entity;
- }
- template <typename Entity>
- static auto Unwrap(Entity *entity) {
- using Selector = decltype(Is(std::declval<Entity>()));
- return Unwrap(
- entity,
- Selector());
- }
- };
- } // namespace details
- template <typename Widget>
- class Wrap<Widget, RpWidget> : public RpWidget {
- public:
- Wrap(QWidget *parent, object_ptr<Widget> &&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();
- }
- using WrapParentType = RpWidget;
- protected:
- int resizeGetHeight(int newWidth) override {
- if (auto weak = wrapped()) {
- weak->resizeToWidth(newWidth);
- return weak->heightNoMargins();
- }
- return heightNoMargins();
- }
- void visibleTopBottomUpdated(
- int visibleTop,
- int visibleBottom) override {
- setChildVisibleTopBottom(
- wrapped(),
- visibleTop,
- visibleBottom);
- }
- virtual void wrappedSizeUpdated(QSize size) {
- resize(size);
- }
- private:
- object_ptr<Widget> _wrapped;
- };
- template <typename Widget>
- Wrap<Widget, RpWidget>::Wrap(
- QWidget *parent,
- object_ptr<Widget> &&child)
- : RpWidget(parent)
- , _wrapped(std::move(child)) {
- if (_wrapped) {
- _wrapped->sizeValue(
- ) | rpl::start_with_next([this](const QSize &value) {
- wrappedSizeUpdated(value);
- }, lifetime());
- _wrapped->setParent(this);
- _wrapped->show();
- _wrapped->move(0, 0);
- _wrapped->alive(
- ) | rpl::start_with_done([this] {
- _wrapped->setParent(nullptr);
- _wrapped = nullptr;
- delete this;
- }, lifetime());
- }
- }
- template <typename Widget, typename ParentType>
- class Wrap : public ParentType {
- public:
- using ParentType::ParentType;
- Widget *wrapped() {
- return static_cast<Widget*>(ParentType::wrapped());
- }
- const Widget *wrapped() const {
- return static_cast<const Widget*>(ParentType::wrapped());
- }
- auto entity() {
- return details::UnwrapHelper::Unwrap(wrapped());
- }
- auto entity() const {
- return details::UnwrapHelper::Unwrap(wrapped());
- }
- using WrapParentType = ParentType;
- };
- class OverrideMargins : public Wrap<RpWidget> {
- using Parent = Wrap<RpWidget>;
- public:
- OverrideMargins(
- QWidget *parent,
- object_ptr<RpWidget> &&child,
- QMargins margins = QMargins())
- : Parent(parent, std::move(child)), _margins(margins) {
- if (auto weak = wrapped()) {
- auto margins = weak->getMargins();
- resizeToWidth(weak->width()
- - margins.left()
- - margins.right());
- }
- }
- QMargins getMargins() const override {
- return _margins;
- }
- protected:
- int resizeGetHeight(int newWidth) override {
- if (auto weak = wrapped()) {
- weak->resizeToWidth(newWidth);
- weak->moveToLeft(_margins.left(), _margins.top());
- return weak->heightNoMargins();
- }
- return height();
- }
- private:
- void wrappedSizeUpdated(QSize size) override {
- auto margins = wrapped()->getMargins();
- resize(
- (size.width()
- - margins.left()
- - margins.right()
- + _margins.left()
- + _margins.right()),
- (size.height()
- - margins.top()
- - margins.bottom()
- + _margins.top()
- + _margins.bottom()));
- }
- QMargins _margins;
- };
- } // namespace Ui
|