Skip to content

Commit

Permalink
Use QQuickWidget now that it supports RHI
Browse files Browse the repository at this point in the history
This solves a few problem we have with both the 3D part renderer
(sometimes not updating, or updating too late, after hide/show)
and for the camera preview (crash on shutdown)

Closes: #816
  • Loading branch information
rgriebl committed Jan 19, 2024
1 parent 4b2cf6b commit f2db4cc
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 58 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ else()
set(BS_DESKTOP ON)
set(BS_TYPE "Desktop")
add_compile_definitions(BS_DESKTOP)
find_package(Qt6 CONFIG QUIET REQUIRED Widgets PrintSupport Qml Quick Quick3D Multimedia)
find_package(Qt6 CONFIG QUIET REQUIRED Widgets PrintSupport Qml Quick Quick3D Multimedia QuickWidgets)
find_package(Qt6 CONFIG QUIET OPTIONAL_COMPONENTS MultimediaQuickPrivate) # Debian bug 1060228

endif()
Expand Down
30 changes: 16 additions & 14 deletions src/desktop/picturewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <QClipboard>
#include <QFileDialog>
#include <QQmlApplicationEngine>
#include <QStackedWidget>
#include <QStackedLayout>

#include <QCoro/QCoroSignal>

Expand Down Expand Up @@ -73,13 +73,14 @@ PictureWidget::PictureWidget(QWidget *parent)

w_ldraw = new LDraw::RenderWidget(Application::inst()->qmlEngine(), this);

w_stack = new QStackedWidget(this);
w_stackLayout = new QStackedLayout();
w_stackLayout->setStackingMode(QStackedLayout::StackAll);

auto layout = new QVBoxLayout(this);
layout->addWidget(w_text);
layout->addWidget(w_stack, 10);
w_stack->addWidget(w_image);
w_stack->addWidget(w_ldraw);
layout->addLayout(w_stackLayout, 10);
w_stackLayout->addWidget(w_image);
w_stackLayout->addWidget(w_ldraw);
layout->setContentsMargins(2, 6, 2, 2);

w_2d = new QToolButton(this);
Expand Down Expand Up @@ -113,7 +114,7 @@ PictureWidget::PictureWidget(QWidget *parent)
w_reloadRescale->setIcon(m_reloadIcon);
connect(w_reloadRescale, &QToolButton::clicked,
this, [this]() {
if (w_stack->currentWidget() == w_ldraw) {
if (w_stackLayout->currentWidget() == w_ldraw) {
w_ldraw->resetCamera();
} else if (m_pic) {
m_pic->update(true);
Expand Down Expand Up @@ -203,17 +204,18 @@ PictureWidget::PictureWidget(QWidget *parent)
w_ldraw->clear();
});

connect(w_stack, &QStackedWidget::currentChanged,
connect(w_stackLayout, &QStackedLayout::currentChanged,
this, [this]() {
stackSwitch();
});

connect(w_ldraw, &LDraw::RenderWidget::canRenderChanged,
this, [this](bool b) {
if (!b)
w_stack->setCurrentWidget(w_image);
else if (prefer3D() && m_supports3D)
w_stack->setCurrentWidget(w_ldraw);
w_stackLayout->setCurrentWidget(w_image);
else if (prefer3D() && m_supports3D) {
w_stackLayout->setCurrentWidget(w_ldraw);
}
w_3d->setEnabled(b);
});

Expand All @@ -235,7 +237,7 @@ PictureWidget::PictureWidget(QWidget *parent)

void PictureWidget::stackSwitch()
{
bool is3D = (w_stack->currentWidget() == w_ldraw);
bool is3D = (w_stackLayout->currentWidget() == w_ldraw);
w_reloadRescale->setIcon(is3D ? m_rescaleIcon : m_reloadIcon);
w_reloadRescale->setToolTip(is3D ? tr("Center view") : tr("Update"));
m_renderSettings->setVisible(is3D);
Expand Down Expand Up @@ -316,7 +318,7 @@ void PictureWidget::setItemAndColor(const BrickLink::Item *item, const BrickLink
w_reloadRescale->setEnabled(m_item);

// the RenderWidget will emit canRender() asynchronously, so we don't handle that here
if (w_stack->currentWidget() == w_image)
if (w_stackLayout->currentWidget() == w_image)
showImage();
}

Expand All @@ -330,12 +332,12 @@ void PictureWidget::setPrefer3D(bool b)
if (m_prefer3D != b)
m_prefer3D = b;

w_stack->setCurrentWidget((b && m_supports3D) ? static_cast<QWidget *>(w_ldraw) : w_image);
w_stackLayout->setCurrentWidget((b && m_supports3D) ? static_cast<QWidget *>(w_ldraw) : w_image);
}

void PictureWidget::showImage()
{
if (w_stack->currentWidget() != w_image)
if (w_stackLayout->currentWidget() != w_image)
return;

if (m_pic && ((m_pic->updateStatus() == BrickLink::UpdateStatus::Updating) ||
Expand Down
7 changes: 4 additions & 3 deletions src/desktop/picturewidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#pragma once

#include <QFrame>
#include <QImage>
#include <QIcon>
#include <QImage>
#include <QStackedLayout>

#include "bricklink/global.h"

Expand All @@ -17,7 +18,7 @@ QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QToolButton)
QT_FORWARD_DECLARE_CLASS(QMenu)
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
QT_FORWARD_DECLARE_CLASS(QStackedLayout)


class PictureWidget : public QFrame
Expand Down Expand Up @@ -62,7 +63,7 @@ protected slots:
QIcon m_rescaleIcon;
QIcon m_reloadIcon;
QMenu *m_contextMenu = nullptr;
QStackedWidget *w_stack;
QStackedLayout *w_stackLayout;
QSize m_currentImageSize;

QAction *m_renderSettings;
Expand Down
1 change: 1 addition & 0 deletions src/ldraw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ if (BS_DESKTOP)
)
target_link_libraries(ldraw_module PRIVATE
Qt6::Widgets
Qt6::QuickWidgets
)
endif()

Expand Down
42 changes: 13 additions & 29 deletions src/ldraw/renderwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickItemGrabResult>
#include <QtQuickWidgets/QQuickWidget>

#include "common/systeminfo.h"
#include "rendercontroller.h"
Expand Down Expand Up @@ -51,37 +52,20 @@ RenderWidget::RenderWidget(QQmlEngine *engine, QWidget *parent)
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);

if (isGPUSupported()) {
m_window = engine ? new QQuickView(engine, nullptr) : new QQuickView();
m_widget = engine ? new QQuickWidget(engine, this) : new QQuickWidget(this);

if (isGPUSupported()) {
QSurfaceFormat fmt = QQuick3D::idealSurfaceFormat();
m_window->setFormat(fmt);
m_window->setResizeMode(QQuickView::SizeRootObjectToView);

m_window->setSource(QUrl(u"qrc:/LDraw/PartRenderer.qml"_qs));

if (auto *ro = m_window->rootObject()) {
m_widget = QWidget::createWindowContainer(m_window, this);
m_controller = ro->property("renderController").value<RenderController *>();
} else {
delete m_window;
m_window = nullptr;
}
m_widget->setFormat(fmt);
m_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_widget->setSource(QUrl(u"qrc:/LDraw/PartRenderer.qml"_qs));
}
if (!m_widget) { // create a dummy widget, if the 3D view could not be created
Q_ASSERT(!m_window);

if (auto *ro = m_widget->rootObject())
m_controller = ro->property("renderController").value<RenderController *>();
else
m_controller = new RenderController(this);

m_widget = new QWidget(this);
m_widget->setBackgroundRole(QPalette::Window);
m_widget->setAutoFillBackground(true);
connect(m_controller, &RenderController::clearColorChanged,
m_widget, [this](const QColor &color) {
auto pal = m_widget->palette();
pal.setColor(QPalette::Window, color);
m_widget->setPalette(pal);
});
}
paletteChange();

m_widget->setMinimumSize(100, 100);
Expand Down Expand Up @@ -145,8 +129,8 @@ void RenderWidget::setAnimationActive(bool active)

bool RenderWidget::startGrab()
{
if (m_window && !m_grabResult) {
m_grabResult = m_window->rootObject()->grabToImage();
if (m_widget->rootObject() && !m_grabResult) {
m_grabResult = m_widget->rootObject()->grabToImage();
if (m_grabResult) {
connect(m_grabResult.get(), &QQuickItemGrabResult::ready,
this, [this]() {
Expand Down Expand Up @@ -190,7 +174,7 @@ void RenderWidget::paletteChange()

void RenderWidget::languageChange()
{
if (m_window)
if (m_widget->rootObject())
setToolTip(tr("Hold left button: Rotate\nHold right button: Move\nMouse wheel: Zoom\nDouble click: Reset camera\nRight click: Menu"));
}

Expand Down
4 changes: 2 additions & 2 deletions src/ldraw/renderwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

QT_FORWARD_DECLARE_CLASS(QQuickItemGrabResult)
QT_FORWARD_DECLARE_CLASS(QQuickView)
QT_FORWARD_DECLARE_CLASS(QQuickWidget)
QT_FORWARD_DECLARE_CLASS(QQmlEngine)


Expand Down Expand Up @@ -57,8 +58,7 @@ public slots:
void languageChange();

RenderController *m_controller = nullptr;
QQuickView *m_window = nullptr;
QWidget *m_widget = nullptr;
QQuickWidget *m_widget = nullptr;
QSharedPointer<QQuickItemGrabResult> m_grabResult;
};

Expand Down
1 change: 1 addition & 0 deletions src/scanner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ if (BS_DESKTOP)
)
target_link_libraries(scanner_module PRIVATE
Qt6::Widgets
Qt6::QuickWidgets
)
endif()

Expand Down
17 changes: 8 additions & 9 deletions src/scanner/camerapreviewwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QQmlEngine>
#include <QtQuickWidgets/QQuickWidget>

#include "camerapreviewwidget.h"
#ifdef BS_USE_TYPE_COMPILER
Expand Down Expand Up @@ -81,27 +82,25 @@ CameraPreviewWidget::CameraPreviewWidget(QQmlEngine *engine, QWidget *parent)
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);

auto window = engine ? new QQuickView(engine, nullptr) : new QQuickView();
window->setResizeMode(QQuickView::SizeRootObjectToView);
window->setColor(Qt::black);
m_widget = engine ? new QQuickWidget(engine, this) : new QQuickWidget(this);
m_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
m_widget->setClearColor(Qt::black);

m_cameraPreview = new Scanner::CameraPreview(engine);
m_cameraPreview->setParentItem(window->contentItem());
auto widget = QWidget::createWindowContainer(window, this);
m_cameraPreview->setParentItem(m_widget->quickWindow()->contentItem());

connect(m_cameraPreview, &Scanner::CameraPreview::clicked,
this, &CameraPreviewWidget::clicked);

int videoWidth = logicalDpiX() * 3; // ~7.5cm on-screen
widget->setMinimumSize(videoWidth, videoWidth * 9 / 16);
widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_widget->setMinimumSize(videoWidth, videoWidth * 9 / 16);
m_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

layout->addWidget(widget, 10);
layout->addWidget(m_widget, 10);
}

CameraPreviewWidget::~CameraPreviewWidget()
{
m_cameraPreview->setParentItem(nullptr);
delete m_cameraPreview;
}

Expand Down
2 changes: 2 additions & 0 deletions src/scanner/camerapreviewwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <QWidget>

QT_FORWARD_DECLARE_CLASS(QQuickWidget)
QT_FORWARD_DECLARE_CLASS(QQmlEngine)

namespace Scanner {
Expand All @@ -26,5 +27,6 @@ class CameraPreviewWidget : public QWidget
Q_SIGNAL void clicked();

private:
QQuickWidget *m_widget = nullptr;
Scanner::CameraPreview *m_cameraPreview = nullptr;
};

0 comments on commit f2db4cc

Please sign in to comment.