Add a m_thisWeakPtr member to Views

Allows to promote back to shared pointer
This commit is contained in:
Sergio Martins
2022-07-02 20:12:33 +01:00
parent ba71ad7407
commit 7d21516f6d
14 changed files with 83 additions and 59 deletions

View File

@@ -10,6 +10,7 @@
*/
#include "ViewWrapper.h"
#include "private/View_p.h"
#include <QDebug>
@@ -157,7 +158,9 @@ void ViewWrapper::setMouseTracking(bool)
std::shared_ptr<View> ViewWrapper::asWrapper()
{
// could be implemented with a weak pointer, but we have no use case
qFatal("Don't call on wrappers");
if (auto sharedptr = d->m_thisWeakPtr.lock())
return sharedptr;
qFatal("No shared ptr. Shouldn't happen.");
return {};
}

View File

@@ -15,6 +15,7 @@
#include "kdbindings/signal.h"
#include <vector>
#include <memory>
namespace KDDockWidgets {
@@ -44,5 +45,8 @@ public:
/// List of event filters
std::vector<EventFilterInterface *> m_viewEventFilters;
/// If this view is wrapped in a shared ptr, this weak ptr allows us to promote to shared ptr
std::weak_ptr<View> m_thisWeakPtr;
};
}

View File

@@ -86,8 +86,7 @@ void Platform_qtquick::init()
QQuickWindow::setDefaultAlphaBuffer(true);
qGuiApp->connect(qApp, &QGuiApplication::focusObjectChanged, qApp, [this](QObject *obj) {
ViewWrapper *wrapper = obj ? new Views::ViewWrapper_qtquick(obj) : nullptr;
d->focusedViewChanged.emit(std::shared_ptr<View>(wrapper));
d->focusedViewChanged.emit(Views::ViewWrapper_qtquick::create(obj));
});
}
@@ -103,12 +102,7 @@ const char *Platform_qtquick::name() const
std::shared_ptr<View> Platform_qtquick::qobjectAsView(QObject *obj) const
{
if (auto w = qobject_cast<QQuickItem *>(obj)) {
ViewWrapper *wrapper = new Views::ViewWrapper_qtquick(w);
return std::shared_ptr<View>(wrapper);
}
return nullptr;
return Views::ViewWrapper_qtquick::create(obj);
}
std::shared_ptr<Window> Platform_qtquick::windowFromQWindow(QWindow *qwindow) const

View File

@@ -12,6 +12,7 @@
#include "ViewWrapper_qtquick.h"
#include "qtquick/views/RubberBand_qtquick.h"
#include "qtquick/views/View_qtquick.h"
#include "private/View_p.h"
#include "qtquick/views/DockWidget_qtquick.h"
#include "qtquick/views/FloatingWindow_qtquick.h"
@@ -459,3 +460,22 @@ SizePolicy ViewWrapper_qtquick::horizontalSizePolicy() const
}
return {};
}
/*static*/
std::shared_ptr<View> ViewWrapper_qtquick::create(QObject *item)
{
return create(qobject_cast<QQuickItem *>(item));
}
/*static*/
std::shared_ptr<View> ViewWrapper_qtquick::create(QQuickItem *item)
{
if (!item)
return {};
auto wrapper = new ViewWrapper_qtquick(item);
auto sharedptr = std::shared_ptr<View>(wrapper);
wrapper->d->m_thisWeakPtr = sharedptr;
return sharedptr;
}

View File

@@ -24,9 +24,6 @@ namespace KDDockWidgets::Views {
class DOCKS_EXPORT ViewWrapper_qtquick : public ViewWrapper
{
public:
explicit ViewWrapper_qtquick(QObject *widget);
explicit ViewWrapper_qtquick(QQuickItem *widget);
QRect geometry() const override;
void setGeometry(QRect) override;
void move(int x, int y) override;
@@ -68,7 +65,12 @@ public:
const View *unwrap() const;
View *unwrap();
static std::shared_ptr<View> create(QObject *widget);
static std::shared_ptr<View> create(QQuickItem *widget);
private:
explicit ViewWrapper_qtquick(QObject *widget);
explicit ViewWrapper_qtquick(QQuickItem *widget);
QPointer<QQuickItem> m_item;
};

View File

@@ -720,8 +720,7 @@ std::shared_ptr<View> View_qtquick::parentViewFor(const QQuickItem *item)
/* static */
std::shared_ptr<View> View_qtquick::asQQuickWrapper(QQuickItem *item)
{
auto wrapper = new ViewWrapper_qtquick(item);
return std::shared_ptr<View>(wrapper);
return ViewWrapper_qtquick::create(item);
}
std::shared_ptr<View> View_qtquick::parentView() const
@@ -731,8 +730,7 @@ std::shared_ptr<View> View_qtquick::parentView() const
std::shared_ptr<View> View_qtquick::asWrapper()
{
ViewWrapper *wrapper = new ViewWrapper_qtquick(this);
return std::shared_ptr<View>(wrapper);
return ViewWrapper_qtquick::create(this);
}
void View_qtquick::grabMouse()

View File

@@ -60,13 +60,11 @@ public:
if (auto w = qobject_cast<QWidget *>(o)) {
if (w->isWindow()) {
if (ev->type() == QEvent::WindowActivate) {
auto wrapper = new Views::ViewWrapper_qtwidgets(w);
Platform::instance()->d->windowActivated.emit(std::shared_ptr<View>(wrapper));
Platform::instance()->d->windowActivated.emit(Views::ViewWrapper_qtwidgets::create(w));
}
if (ev->type() == QEvent::WindowDeactivate) {
auto wrapper = new Views::ViewWrapper_qtwidgets(w);
Platform::instance()->d->windowDeactivated.emit(std::shared_ptr<View>(wrapper));
Platform::instance()->d->windowDeactivated.emit(Views::ViewWrapper_qtwidgets::create(w));
}
}
}
@@ -99,8 +97,7 @@ void Platform_qtwidgets::init()
#endif
qGuiApp->connect(qApp, &QGuiApplication::focusObjectChanged, qApp, [this](QObject *obj) {
ViewWrapper *wrapper = obj ? new Views::ViewWrapper_qtwidgets(obj) : nullptr;
d->focusedViewChanged.emit(std::shared_ptr<View>(wrapper));
d->focusedViewChanged.emit(Views::ViewWrapper_qtwidgets::create(obj));
});
}
@@ -121,12 +118,7 @@ bool Platform_qtwidgets::hasActivePopup() const
std::shared_ptr<View> Platform_qtwidgets::qobjectAsView(QObject *obj) const
{
if (auto w = qobject_cast<QWidget *>(obj)) {
ViewWrapper *wrapper = new Views::ViewWrapper_qtwidgets(w);
return std::shared_ptr<View>(wrapper);
}
return nullptr;
return Views::ViewWrapper_qtwidgets::create(obj);
}
std::shared_ptr<Window> Platform_qtwidgets::windowFromQWindow(QWindow *qwindow) const

View File

@@ -44,7 +44,7 @@ std::shared_ptr<View> Window_qtwidgets::rootView() const
return {};
if (QWidget *widget = m_window->property("kddockwidgets_qwidget").value<QWidget *>())
return std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(widget));
return Views::ViewWrapper_qtwidgets::create(widget);
qWarning() << Q_FUNC_INFO << "Window does not have a root";
return nullptr;

View File

@@ -71,8 +71,7 @@ void DockWidget_qtwidgets::init()
void DockWidget_qtwidgets::setWidget(QWidget *widget)
{
auto wrapper = widget ? new ViewWrapper_qtwidgets(widget) : nullptr;
m_dockWidget->setGuestView(std::shared_ptr<View>(wrapper));
m_dockWidget->setGuestView(ViewWrapper_qtwidgets::create(widget));
}
bool DockWidget_qtwidgets::event(QEvent *e)

View File

@@ -170,12 +170,7 @@ void MainWindow_qtwidgets::setContentsMargins(int left, int top, int right, int
void MainWindow_qtwidgets::setPersistentCentralWidget(QWidget *widget)
{
if (widget) {
auto wrapper = std::shared_ptr<KDDockWidgets::ViewWrapper>(new KDDockWidgets::Views::ViewWrapper_qtwidgets(widget));
m_mainWindow->setPersistentCentralView(wrapper);
} else {
m_mainWindow->setPersistentCentralView({});
}
m_mainWindow->setPersistentCentralView(Views::ViewWrapper_qtwidgets::create(widget));
}
QWidget *MainWindow_qtwidgets::persistentCentralWidget() const

View File

@@ -10,6 +10,7 @@
*/
#include "ViewWrapper_qtwidgets.h"
#include "private/View_p.h"
#include "qtwidgets/views/DockWidget_qtwidgets.h"
#include "qtwidgets/views/DropArea_qtwidgets.h"
#include "qtwidgets/views/FloatingWindow_qtwidgets.h"
@@ -104,6 +105,25 @@ static Controller *controllerForWidget(QWidget *widget)
return nullptr;
}
/*static*/
std::shared_ptr<View> ViewWrapper_qtwidgets::create(QObject *widget)
{
return create(qobject_cast<QWidget *>(widget));
}
/*static*/
std::shared_ptr<View> ViewWrapper_qtwidgets::create(QWidget *widget)
{
if (!widget)
return {};
auto wrapper = new ViewWrapper_qtwidgets(widget);
auto sharedptr = std::shared_ptr<View>(wrapper);
wrapper->d->m_thisWeakPtr = sharedptr;
return sharedptr;
}
ViewWrapper_qtwidgets::ViewWrapper_qtwidgets(QObject *widget)
: ViewWrapper_qtwidgets(qobject_cast<QWidget *>(widget))
{

View File

@@ -24,9 +24,6 @@ namespace KDDockWidgets::Views {
class DOCKS_EXPORT ViewWrapper_qtwidgets : public ViewWrapper
{
public:
explicit ViewWrapper_qtwidgets(QObject *widget);
explicit ViewWrapper_qtwidgets(QWidget *widget);
QRect geometry() const override;
void setGeometry(QRect) override;
void move(int x, int y) override;
@@ -66,7 +63,12 @@ public:
SizePolicy verticalSizePolicy() const override;
QWidget *widget() const;
static std::shared_ptr<View> create(QObject *widget);
static std::shared_ptr<View> create(QWidget *widget);
private:
explicit ViewWrapper_qtwidgets(QObject *widget);
explicit ViewWrapper_qtwidgets(QWidget *widget);
QPointer<QWidget> m_widget;
};

View File

@@ -115,7 +115,7 @@ template<class T>
std::shared_ptr<View> View_qtwidgets<T>::childViewAt(QPoint localPos) const
{
if (QWidget *child = QWidget::childAt(localPos))
return std::shared_ptr<View>(new ViewWrapper_qtwidgets(child));
return ViewWrapper_qtwidgets::create(child);
return {};
}
@@ -124,8 +124,7 @@ template<class T>
std::shared_ptr<View> View_qtwidgets<T>::rootView() const
{
if (auto w = QWidget::window()) {
View *wrapper = new ViewWrapper_qtwidgets(w);
return std::shared_ptr<View>(wrapper);
return ViewWrapper_qtwidgets::create(w);
}
return {};
@@ -135,8 +134,7 @@ template<class T>
std::shared_ptr<View> View_qtwidgets<T>::parentView() const
{
if (QWidget *p = QWidget::parentWidget()) {
View *wrapper = new ViewWrapper_qtwidgets(p);
return std::shared_ptr<View>(wrapper);
return ViewWrapper_qtwidgets::create(p);
}
return {};
@@ -145,8 +143,7 @@ std::shared_ptr<View> View_qtwidgets<T>::parentView() const
template<class T>
std::shared_ptr<View> View_qtwidgets<T>::asWrapper()
{
View *wrapper = new ViewWrapper_qtwidgets(this);
return std::shared_ptr<View>(wrapper);
return ViewWrapper_qtwidgets::create(this);
}
/* static */
@@ -158,8 +155,7 @@ QVector<std::shared_ptr<View>> View_qtwidgets<T>::childViewsFor(const QWidget *p
result.reserve(children.size());
for (QObject *child : children) {
if (auto widget = qobject_cast<QWidget *>(child)) {
View *wrapper = new ViewWrapper_qtwidgets(widget);
result.push_back(std::shared_ptr<View>(wrapper));
result.push_back(ViewWrapper_qtwidgets::create(widget));
}
}

View File

@@ -67,7 +67,7 @@ inline Controllers::DockWidget *createDockWidget(const QString &name, QWidget *w
w->setFocusPolicy(Qt::StrongFocus);
auto dock = newDockWidget(name, options, layoutSaverOptions);
dock->setAffinityName(affinityName);
dock->setGuestView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(w)));
dock->setGuestView(Views::ViewWrapper_qtwidgets::create(w));
dock->setObjectName(name);
dock->view()->setGeometry(QRect(0, 0, 400, 400));
if (show) {
@@ -314,7 +314,7 @@ void TestQtWidgets::tst_mdi_mixed_with_docking()
m->addDockWidget(dock1, Location_OnBottom);
auto mdiArea = new Views::MDIArea_qtwidgets();
m->setPersistentCentralView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(mdiArea)));
m->setPersistentCentralView(Views::ViewWrapper_qtwidgets::create(mdiArea));
auto mdiWidget1 = createDockWidget("mdi1", new QPushButton("mdi1"));
auto mdiWidget2 = createDockWidget("mdi2", new QPushButton("mdi12"));
@@ -361,14 +361,13 @@ void TestQtWidgets::tst_mdi_mixed_with_docking2()
auto mdiArea = new Views::MDIArea_qtwidgets();
m->setPersistentCentralView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(mdiArea)));
m->setPersistentCentralView(Views::ViewWrapper_qtwidgets::create(mdiArea));
auto createSheet = [](int id) -> Controllers::DockWidget * {
auto dock = newDockWidget(QStringLiteral("dw-sheet-%1").arg(id), DockWidgetOption_MDINestable);
auto btn = new QPushButton(QStringLiteral("Sheet %1").arg(id));
auto btnw = std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(btn));
dock->setGuestView(btnw);
dock->setGuestView(Views::ViewWrapper_qtwidgets::create(btn));
dock->setTitle(QStringLiteral("Sheet %1").arg(id));
return dock;
@@ -531,11 +530,11 @@ void TestQtWidgets::tst_mdi_mixed_with_docking_setMDISize()
m->addDockWidget(dock1, Location_OnBottom);
auto mdiArea = new Views::MDIArea_qtwidgets();
m->setPersistentCentralView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(mdiArea)));
m->setPersistentCentralView(Views::ViewWrapper_qtwidgets::create(mdiArea));
auto createSheet = [](int id) -> Controllers::DockWidget * {
auto dock = newDockWidget(QStringLiteral("dw-sheet-%1").arg(id), DockWidgetOption_MDINestable);
dock->setGuestView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(new QPushButton(QStringLiteral("Sheet %1").arg(id)))));
dock->setGuestView(Views::ViewWrapper_qtwidgets::create(new QPushButton(QStringLiteral("Sheet %1").arg(id))));
dock->setTitle(QStringLiteral("Sheet %1").arg(id));
return dock;
@@ -572,13 +571,13 @@ void TestQtWidgets::tst_floatingWindowDeleted()
{
auto dock1 = newDockWidget(QStringLiteral("DockWidget #1"));
auto myWidget = new QWidget();
dock1->setGuestView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(myWidget)));
dock1->setGuestView(Views::ViewWrapper_qtwidgets::create((myWidget)));
dock1->view()->resize(QSize(600, 600));
dock1->show();
auto dock2 = newDockWidget(QStringLiteral("DockWidget #2"));
myWidget = new QWidget();
dock2->setGuestView(std::shared_ptr<View>(new Views::ViewWrapper_qtwidgets(myWidget)));
dock2->setGuestView(Views::ViewWrapper_qtwidgets::create(myWidget));
dock2->view()->resize(QSize(600, 600));
dock2->show();