diff --git a/src/qtquick/views/ViewWrapper_qtquick.cpp b/src/qtquick/views/ViewWrapper_qtquick.cpp index 5a26d1e8..10590868 100644 --- a/src/qtquick/views/ViewWrapper_qtquick.cpp +++ b/src/qtquick/views/ViewWrapper_qtquick.cpp @@ -170,8 +170,7 @@ std::shared_ptr ViewWrapper_qtquick::rootView() const std::shared_ptr ViewWrapper_qtquick::parentView() const { - // return std::shared_ptr(new ViewWrapper_qtquick(m_item->parentWidget())); - return {}; + return View_qtquick::parentViewFor(m_item); } HANDLE ViewWrapper_qtquick::handle() const @@ -236,14 +235,34 @@ QSize ViewWrapper_qtquick::minSize() const QVector> ViewWrapper_qtquick::childViews() const { - return {}; + QVector> result; + const auto childItems = m_item->childItems(); + for (QQuickItem *child : childItems) { + result << asQQuickWrapper(child); + } + + return result; } -void ViewWrapper_qtquick::setParent(View *) +void ViewWrapper_qtquick::setParent(View *parent) { + if (auto view = unwrap()) { + view->setParent(parent); + } else { + auto parentItem = Views::asQQuickItem(parent); + m_item->QQuickItem::setParent(parentItem); + m_item->QQuickItem::setParentItem(parentItem); + } + + m_item->setVisible(false); } bool ViewWrapper_qtquick::close() { return View_qtquick::close(m_item); } + +View *ViewWrapper_qtquick::unwrap() +{ + return qobject_cast(m_item); +} diff --git a/src/qtquick/views/ViewWrapper_qtquick.h b/src/qtquick/views/ViewWrapper_qtquick.h index e3f72479..5fe77368 100644 --- a/src/qtquick/views/ViewWrapper_qtquick.h +++ b/src/qtquick/views/ViewWrapper_qtquick.h @@ -63,6 +63,8 @@ public: QSize minSize() const override; bool close() override; + View *unwrap(); + private: QPointer m_item; }; diff --git a/src/qtquick/views/View_qtquick.cpp b/src/qtquick/views/View_qtquick.cpp index fe1c96f7..68c7fcb7 100644 --- a/src/qtquick/views/View_qtquick.cpp +++ b/src/qtquick/views/View_qtquick.cpp @@ -687,10 +687,11 @@ std::shared_ptr View_qtquick::childViewAt(QPoint p) const return child ? asQQuickWrapper(child) : nullptr; } -std::shared_ptr View_qtquick::parentView() const +/*static*/ +std::shared_ptr View_qtquick::parentViewFor(const QQuickItem *item) { - auto p = QQuickItem::parentItem(); - if (QQuickWindow *window = QQuickItem::window()) { + auto p = item->parentItem(); + if (QQuickWindow *window = item->window()) { if (p == window->contentItem()) { // For our purposes, the root view is the one directly bellow QQuickWindow::contentItem return nullptr; @@ -700,6 +701,11 @@ std::shared_ptr View_qtquick::parentView() const return p ? asQQuickWrapper(p) : nullptr; } +std::shared_ptr View_qtquick::parentView() const +{ + return parentViewFor(this); +} + std::shared_ptr View_qtquick::asWrapper() { ViewWrapper *wrapper = new ViewWrapper_qtquick(this); diff --git a/src/qtquick/views/View_qtquick.h b/src/qtquick/views/View_qtquick.h index 4e34bfe8..f5b8e8c7 100644 --- a/src/qtquick/views/View_qtquick.h +++ b/src/qtquick/views/View_qtquick.h @@ -129,6 +129,7 @@ public: std::shared_ptr childViewAt(QPoint p) const override; std::shared_ptr rootView() const override; std::shared_ptr parentView() const override; + std::shared_ptr asWrapper() override; void setObjectName(const QString &name) override; @@ -162,6 +163,7 @@ public: /// @brief Convenience to create a QQuickItem static QQuickItem *createItem(QQmlEngine *engine, const QString &filename); + static std::shared_ptr parentViewFor(const QQuickItem *); Q_SIGNALS: void geometryUpdated(); // similar to QLayout stuff, when size constraints change diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b35f96ca..55e8b232 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,3 +60,6 @@ target_link_libraries(tst_viewguard kddockwidgets) add_executable(tst_view tst_view.cpp ${TESTING_RESOURCES}) target_link_libraries(tst_view kddockwidgets) + +add_executable(tst_viewwrapper tst_viewwrapper.cpp ${TESTING_RESOURCES}) +target_link_libraries(tst_viewwrapper kddockwidgets) diff --git a/tests/tst_viewwrapper.cpp b/tests/tst_viewwrapper.cpp new file mode 100644 index 00000000..15dc3d9c --- /dev/null +++ b/tests/tst_viewwrapper.cpp @@ -0,0 +1,46 @@ +/* + This file is part of KDDockWidgets. + + SPDX-FileCopyrightText: 2019-2022 Klarälvdalens Datakonsult AB, a KDAB Group company + Author: Sérgio Martins + + SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only + + Contact KDAB at for commercial licensing options. +*/ + +#include "main.h" + +TEST_CASE("View::setParent") +{ + auto r = Platform::instance()->tests_createView({}); + auto rootView = r->asWrapper(); + REQUIRE(rootView); + REQUIRE(!rootView->isNull()); + CHECK(rootView->childViews().isEmpty()); + + auto c = Platform::instance()->tests_createView({}, r); + auto childView = c->asWrapper(); + + CHECK(!rootView->parentView()); + REQUIRE(childView->parentView()); + CHECK(childView->parentView()->equals(rootView)); + const auto children = rootView->childViews(); + + REQUIRE_EQ(children.size(), 1); + CHECK(children[0]->equals(childView)); + + auto r2 = Platform::instance()->tests_createView({}); + auto rootView2 = r2->asWrapper(); + childView->setParent(r2); + CHECK(childView->parentView()->equals(rootView2)); + CHECK(rootView->childViews().isEmpty()); + CHECK_EQ(rootView2->childViews().size(), 1); + + // Deleting a view will remove it from its parent + delete c; + CHECK(rootView2->childViews().isEmpty()); + + delete r; + delete r2; +} \ No newline at end of file