init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
203
Telegram/lib_ui/ui/wrap/wrap.h
Normal file
203
Telegram/lib_ui/ui/wrap/wrap.h
Normal file
@@ -0,0 +1,203 @@
|
||||
// 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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
virtual void wrappedNaturalWidthUpdated(int naturalWidth) {
|
||||
setNaturalWidth(naturalWidth);
|
||||
}
|
||||
|
||||
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::on_next([this](const QSize &value) {
|
||||
wrappedSizeUpdated(value);
|
||||
}, lifetime());
|
||||
_wrapped->naturalWidthValue(
|
||||
) | rpl::on_next([this](int naturalWidth) {
|
||||
wrappedNaturalWidthUpdated(naturalWidth);
|
||||
}, lifetime());
|
||||
_wrapped->setParent(this);
|
||||
_wrapped->show();
|
||||
_wrapped->move(0, 0);
|
||||
_wrapped->alive(
|
||||
) | rpl::on_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
|
||||
Reference in New Issue
Block a user