forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/qds/dev'
Change-Id: I91d9877ef6637d21e1106d6d363275295e6b55a3
This commit is contained in:
@@ -79,6 +79,7 @@ NodeInstanceClientProxy::NodeInstanceClientProxy(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_inputIoDevice(nullptr)
|
||||
, m_outputIoDevice(nullptr)
|
||||
, m_localSocket(nullptr)
|
||||
, m_writeCommandCounter(0)
|
||||
, m_synchronizeId(-1)
|
||||
{
|
||||
@@ -101,6 +102,7 @@ void NodeInstanceClientProxy::initializeSocket()
|
||||
|
||||
m_inputIoDevice = localSocket;
|
||||
m_outputIoDevice = localSocket;
|
||||
m_localSocket = localSocket;
|
||||
}
|
||||
|
||||
void NodeInstanceClientProxy::initializeCapturedStream(const QString &fileName)
|
||||
@@ -145,28 +147,28 @@ bool compareCommands(const QVariant &command, const QVariant &controlCommand)
|
||||
static const int debugOutputCommandType = QMetaType::type("DebugOutputCommand");
|
||||
static const int changeSelectionCommandType = QMetaType::type("ChangeSelectionCommand");
|
||||
|
||||
if (command.userType() == controlCommand.userType()) {
|
||||
if (command.userType() == informationChangedCommandType)
|
||||
if (command.typeId() == controlCommand.typeId()) {
|
||||
if (command.typeId() == informationChangedCommandType)
|
||||
return command.value<InformationChangedCommand>() == controlCommand.value<InformationChangedCommand>();
|
||||
else if (command.userType() == valuesChangedCommandType)
|
||||
else if (command.typeId() == valuesChangedCommandType)
|
||||
return command.value<ValuesChangedCommand>() == controlCommand.value<ValuesChangedCommand>();
|
||||
else if (command.userType() == valuesModifiedCommandType)
|
||||
else if (command.typeId() == valuesModifiedCommandType)
|
||||
return command.value<ValuesModifiedCommand>() == controlCommand.value<ValuesModifiedCommand>();
|
||||
else if (command.userType() == pixmapChangedCommandType)
|
||||
else if (command.typeId() == pixmapChangedCommandType)
|
||||
return command.value<PixmapChangedCommand>() == controlCommand.value<PixmapChangedCommand>();
|
||||
else if (command.userType() == childrenChangedCommandType)
|
||||
else if (command.typeId() == childrenChangedCommandType)
|
||||
return command.value<ChildrenChangedCommand>() == controlCommand.value<ChildrenChangedCommand>();
|
||||
else if (command.userType() == statePreviewImageChangedCommandType)
|
||||
else if (command.typeId() == statePreviewImageChangedCommandType)
|
||||
return command.value<StatePreviewImageChangedCommand>() == controlCommand.value<StatePreviewImageChangedCommand>();
|
||||
else if (command.userType() == componentCompletedCommandType)
|
||||
else if (command.typeId() == componentCompletedCommandType)
|
||||
return command.value<ComponentCompletedCommand>() == controlCommand.value<ComponentCompletedCommand>();
|
||||
else if (command.userType() == synchronizeCommandType)
|
||||
else if (command.typeId() == synchronizeCommandType)
|
||||
return command.value<SynchronizeCommand>() == controlCommand.value<SynchronizeCommand>();
|
||||
else if (command.userType() == tokenCommandType)
|
||||
else if (command.typeId() == tokenCommandType)
|
||||
return command.value<TokenCommand>() == controlCommand.value<TokenCommand>();
|
||||
else if (command.userType() == debugOutputCommandType)
|
||||
else if (command.typeId() == debugOutputCommandType)
|
||||
return command.value<DebugOutputCommand>() == controlCommand.value<DebugOutputCommand>();
|
||||
else if (command.userType() == changeSelectionCommandType)
|
||||
else if (command.typeId() == changeSelectionCommandType)
|
||||
return command.value<ChangeSelectionCommand>()
|
||||
== controlCommand.value<ChangeSelectionCommand>();
|
||||
}
|
||||
@@ -188,8 +190,8 @@ void NodeInstanceClientProxy::writeCommand(const QVariant &command)
|
||||
}
|
||||
} else if (m_outputIoDevice) {
|
||||
#ifdef NANOTRACE_ENABLED
|
||||
if (command.userType() != QMetaType::type("PuppetAliveCommand")) {
|
||||
if (command.userType() == QMetaType::type("SyncNanotraceCommand")) {
|
||||
if (command.typeId() != QMetaType::type("PuppetAliveCommand")) {
|
||||
if (command.typeId() == QMetaType::type("SyncNanotraceCommand")) {
|
||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||
NANOTRACE_INSTANT_ARGS("Sync", "writeCommand",
|
||||
{"name", cmd.name().toStdString()},
|
||||
@@ -288,6 +290,8 @@ void NodeInstanceClientProxy::sceneCreated(const SceneCreatedCommand &command)
|
||||
|
||||
void NodeInstanceClientProxy::flush()
|
||||
{
|
||||
if (m_localSocket)
|
||||
m_localSocket->flush();
|
||||
}
|
||||
|
||||
void NodeInstanceClientProxy::synchronizeWithClientProcess()
|
||||
@@ -391,8 +395,8 @@ void NodeInstanceClientProxy::readDataStream()
|
||||
|
||||
QVariant command = readCommandFromIOStream(m_inputIoDevice, &readCommandCounter, &blockSize);
|
||||
#ifdef NANOTRACE_ENABLED
|
||||
if (command.userType() != QMetaType::type("EndNanotraceCommand")) {
|
||||
if (command.userType() == QMetaType::type("SyncNanotraceCommand")) {
|
||||
if (command.typeId() != QMetaType::type("EndNanotraceCommand")) {
|
||||
if (command.typeId() == QMetaType::type("SyncNanotraceCommand")) {
|
||||
SyncNanotraceCommand cmd = command.value<SyncNanotraceCommand>();
|
||||
NANOTRACE_INSTANT_ARGS("Sync", "readCommand",
|
||||
{"name", cmd.name().toStdString()},
|
||||
@@ -570,7 +574,7 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
|
||||
static const int startNanotraceCommandType = QMetaType::type("StartNanotraceCommand");
|
||||
static const int endNanotraceCommandType = QMetaType::type("EndNanotraceCommand");
|
||||
|
||||
const int commandType = command.userType();
|
||||
const int commandType = command.typeId();
|
||||
|
||||
if (commandType == inputEventCommandType)
|
||||
inputEvent(command.value<InputEventCommand>());
|
||||
@@ -620,13 +624,13 @@ void NodeInstanceClientProxy::dispatchCommand(const QVariant &command)
|
||||
} else if (commandType == changeSelectionCommandType) {
|
||||
ChangeSelectionCommand changeSelectionCommand = command.value<ChangeSelectionCommand>();
|
||||
changeSelection(changeSelectionCommand);
|
||||
} else if (command.userType() == changeLanguageCommand) {
|
||||
} else if (command.typeId() == changeLanguageCommand) {
|
||||
changeLanguage(command.value<ChangeLanguageCommand>());
|
||||
} else if (command.userType() == changePreviewImageSizeCommand) {
|
||||
} else if (command.typeId() == changePreviewImageSizeCommand) {
|
||||
changePreviewImageSize(command.value<ChangePreviewImageSizeCommand>());
|
||||
} else if (command.userType() == startNanotraceCommandType) {
|
||||
} else if (command.typeId() == startNanotraceCommandType) {
|
||||
startNanotrace(command.value<StartNanotraceCommand>());
|
||||
} else if (command.userType() == endNanotraceCommandType) {
|
||||
} else if (command.typeId() == endNanotraceCommandType) {
|
||||
NANOTRACE_SHUTDOWN();
|
||||
} else {
|
||||
Q_ASSERT(false);
|
||||
|
||||
@@ -117,6 +117,7 @@ private:
|
||||
QTimer m_puppetAliveTimer;
|
||||
QIODevice *m_inputIoDevice;
|
||||
QIODevice *m_outputIoDevice;
|
||||
QLocalSocket *m_localSocket;
|
||||
std::unique_ptr<NodeInstanceServerInterface> m_nodeInstanceServer;
|
||||
quint32 m_writeCommandCounter;
|
||||
int m_synchronizeId;
|
||||
|
||||
@@ -181,20 +181,20 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function alignCamerasToView()
|
||||
function alignCamerasToView(cameraNodes)
|
||||
{
|
||||
if (editView) {
|
||||
cameraControl.alignCameras(selectedNodes);
|
||||
cameraControl.alignCameras(cameraNodes);
|
||||
var propertyNames = ["position", "eulerRotation"];
|
||||
viewRoot.changeObjectProperty(selectedNodes, propertyNames);
|
||||
viewRoot.commitObjectProperty(selectedNodes, propertyNames);
|
||||
viewRoot.changeObjectProperty(cameraNodes, propertyNames);
|
||||
viewRoot.commitObjectProperty(cameraNodes, propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
function alignViewToCamera()
|
||||
function alignViewToCamera(cameraNodes)
|
||||
{
|
||||
if (editView)
|
||||
cameraControl.alignView(selectedNodes);
|
||||
cameraControl.alignView(cameraNodes);
|
||||
}
|
||||
|
||||
function updateViewStates(viewStates)
|
||||
|
||||
@@ -175,20 +175,20 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function alignCamerasToView()
|
||||
function alignCamerasToView(cameraNodes)
|
||||
{
|
||||
if (editView) {
|
||||
cameraControl.alignCameras(selectedNodes);
|
||||
cameraControl.alignCameras(cameraNodes);
|
||||
var propertyNames = ["position", "eulerRotation"];
|
||||
viewRoot.changeObjectProperty(selectedNodes, propertyNames);
|
||||
viewRoot.commitObjectProperty(selectedNodes, propertyNames);
|
||||
viewRoot.changeObjectProperty(cameraNodes, propertyNames);
|
||||
viewRoot.commitObjectProperty(cameraNodes, propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
function alignViewToCamera()
|
||||
function alignViewToCamera(cameraNodes)
|
||||
{
|
||||
if (editView)
|
||||
cameraControl.alignView(selectedNodes);
|
||||
cameraControl.alignView(cameraNodes);
|
||||
}
|
||||
|
||||
function updateViewStates(viewStates)
|
||||
|
||||
@@ -520,8 +520,8 @@ void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool,
|
||||
handlePendingToolStateUpdate();
|
||||
QVariant theState;
|
||||
// Convert JS arrays to QVariantLists for easier handling down the line
|
||||
// metaType().id() which only exist in Qt6 is the same as userType()
|
||||
if (state.userType() != QMetaType::QString && state.canConvert(QMetaType::QVariantList))
|
||||
// metaType().id() which only exist in Qt6 is the same as typeId()
|
||||
if (state.typeId() != QMetaType::QString && state.canConvert(QMetaType::QVariantList))
|
||||
theState = state.value<QVariantList>();
|
||||
else
|
||||
theState = state;
|
||||
|
||||
@@ -1058,6 +1058,21 @@ QList<ServerNodeInstance> NodeInstanceServer::allView3DInstances() const
|
||||
return view3Ds;
|
||||
}
|
||||
|
||||
QList<ServerNodeInstance> NodeInstanceServer::allCameraInstances() const
|
||||
{
|
||||
QList<ServerNodeInstance> cameras;
|
||||
std::copy_if(nodeInstances().cbegin(),
|
||||
nodeInstances().cend(),
|
||||
std::back_inserter(cameras),
|
||||
[](const ServerNodeInstance &instance) {
|
||||
return instance.isValid()
|
||||
&& ServerNodeInstance::isSubclassOf(instance.internalObject(),
|
||||
QByteArrayLiteral("QQuick3DCamera"));
|
||||
});
|
||||
|
||||
return cameras;
|
||||
}
|
||||
|
||||
void NodeInstanceServer::setStateInstance(const ServerNodeInstance &stateInstance)
|
||||
{
|
||||
m_activeStateInstance = stateInstance;
|
||||
@@ -1194,7 +1209,7 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<
|
||||
const QList<PropertyName> propertyNames = instance.propertyNames();
|
||||
for (const PropertyName &propertyName : propertyNames) {
|
||||
QVariant propertyValue = instance.property(propertyName);
|
||||
if (supportedVariantType(propertyValue.userType())) {
|
||||
if (supportedVariantType(propertyValue.typeId())) {
|
||||
valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName,
|
||||
propertyValue, PropertyName()));
|
||||
}
|
||||
@@ -1236,13 +1251,13 @@ ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVecto
|
||||
|
||||
if (instance.isValid()) {
|
||||
QVariant propertyValue = instance.property(propertyName);
|
||||
bool isValid = QMetaType::isRegistered(propertyValue.userType())
|
||||
&& supportedVariantType(propertyValue.type());
|
||||
if (!isValid && propertyValue.userType() == 0) {
|
||||
bool isValid = QMetaType::isRegistered(propertyValue.typeId())
|
||||
&& supportedVariantType(propertyValue.typeId());
|
||||
if (!isValid && propertyValue.typeId() == 0) {
|
||||
// If the property is QVariant type, invalid variant can be a valid value
|
||||
const QMetaObject *mo = instance.internalObject()->metaObject();
|
||||
const int idx = mo->indexOfProperty(propertyName);
|
||||
isValid = idx >= 0 && mo->property(idx).userType() == QMetaType::QVariant;
|
||||
isValid = idx >= 0 && mo->property(idx).typeId() == QMetaType::QVariant;
|
||||
}
|
||||
if (isValid) {
|
||||
valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName,
|
||||
@@ -1265,8 +1280,8 @@ ValuesModifiedCommand NodeInstanceServer::createValuesModifiedCommand(
|
||||
const QVariant propertyValue = property.propertyValue;
|
||||
|
||||
if (instance.isValid()) {
|
||||
if (QMetaType::isRegistered(propertyValue.userType())
|
||||
&& supportedVariantType(propertyValue.type())) {
|
||||
if (QMetaType::isRegistered(propertyValue.typeId())
|
||||
&& supportedVariantType(propertyValue.typeId())) {
|
||||
valueVector.append(PropertyValueContainer(instance.instanceId(),
|
||||
propertyName,
|
||||
propertyValue,
|
||||
|
||||
@@ -180,6 +180,7 @@ public:
|
||||
|
||||
QList<ServerNodeInstance> allGroupStateInstances() const;
|
||||
QList<ServerNodeInstance> allView3DInstances() const;
|
||||
QList<ServerNodeInstance> allCameraInstances() const;
|
||||
|
||||
void notifyPropertyChange(qint32 instanceid, const PropertyName &propertyName);
|
||||
|
||||
|
||||
@@ -843,7 +843,7 @@ QObject *ObjectNodeInstance::createComponentWrap(const QString &nodeSource, cons
|
||||
|
||||
//The component might also be shipped with Creator.
|
||||
//To avoid trouble with import "." we use the component shipped with Creator.
|
||||
static inline QString fixComponentPathForIncompatibleQt(const QString &componentPath)
|
||||
inline static QString fixComponentPathForIncompatibleQt(const QString &componentPath)
|
||||
{
|
||||
QString result = componentPath;
|
||||
const QLatin1String importString("/imports/");
|
||||
|
||||
@@ -97,10 +97,11 @@ void Qt5BakeLightsNodeInstanceServer::bakeLights()
|
||||
switch (status) {
|
||||
case QQuick3DLightmapBaker::BakingStatus::Progress:
|
||||
case QQuick3DLightmapBaker::BakingStatus::Warning:
|
||||
case QQuick3DLightmapBaker::BakingStatus::Error:
|
||||
case QQuick3DLightmapBaker::BakingStatus::Error: {
|
||||
nodeInstanceClient()->handlePuppetToCreatorCommand(
|
||||
{PuppetToCreatorCommand::BakeLightsProgress, msg.value_or("")});
|
||||
break;
|
||||
{PuppetToCreatorCommand::BakeLightsProgress, msg.value_or("")});
|
||||
nodeInstanceClient()->flush();
|
||||
} break;
|
||||
case QQuick3DLightmapBaker::BakingStatus::Cancelled:
|
||||
abort(tr("Baking cancelled."));
|
||||
break;
|
||||
|
||||
@@ -179,6 +179,7 @@ void Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
||||
#else
|
||||
viewData.renderControl = new QQuickRenderControl;
|
||||
viewData.window = new QQuickWindow(viewData.renderControl);
|
||||
setPipelineCacheConfig(viewData.window);
|
||||
viewData.renderControl->initialize();
|
||||
#endif
|
||||
QQmlComponent component(engine());
|
||||
@@ -654,7 +655,7 @@ Qt5InformationNodeInstanceServer::propertyToPropertyValueTriples(
|
||||
QVector<InstancePropertyValueTriple> result;
|
||||
InstancePropertyValueTriple propTriple;
|
||||
|
||||
if (variant.type() == QVariant::Vector3D) {
|
||||
if (variant.typeId() == QVariant::Vector3D) {
|
||||
auto vector3d = variant.value<QVector3D>();
|
||||
|
||||
if (vector3d.isNull())
|
||||
@@ -950,6 +951,18 @@ void Qt5InformationNodeInstanceServer::removeNode3D(QObject *node)
|
||||
m_active3DView = nullptr;
|
||||
updateActiveSceneToEditView3D();
|
||||
}
|
||||
if (m_selectedCameras.contains(node)) {
|
||||
m_selectedCameras.remove(node);
|
||||
} else {
|
||||
auto cit = m_selectedCameras.constBegin();
|
||||
while (cit != m_selectedCameras.constEnd()) {
|
||||
if (cit.value().contains(node)) {
|
||||
m_selectedCameras[cit.key()].removeOne(node);
|
||||
break;
|
||||
}
|
||||
++cit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::resolveSceneRoots()
|
||||
@@ -1130,6 +1143,16 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
|
||||
m_render3DEditViewTimer.start(17); // 16.67ms = ~60fps, rounds up to 17
|
||||
--m_need3DEditViewRender;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
else {
|
||||
static bool pipelineSaved = false;
|
||||
if (!pipelineSaved) {
|
||||
// Store pipeline cache for quicker initialization in future
|
||||
savePipelineCacheData();
|
||||
pipelineSaved = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FPS_COUNTER
|
||||
// Force constant rendering for accurate fps count
|
||||
@@ -2173,6 +2196,7 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
QVariantList selectedObjs;
|
||||
QObject *firstSceneRoot = nullptr;
|
||||
ServerNodeInstance firstInstance;
|
||||
QObjectList selectedCameras;
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
QList<QQuick3DParticleSystem *> selectedParticleSystems;
|
||||
#endif
|
||||
@@ -2215,15 +2239,20 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
if (node) {
|
||||
const auto childItems = node->childItems();
|
||||
for (const auto &childItem : childItems) {
|
||||
if (qobject_cast<QQuick3DNode *>(childItem) && !hasInstanceForObject(childItem))
|
||||
if (qobject_cast<QQuick3DNode *>(childItem))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
};
|
||||
if (object && (firstSceneRoot != object || isSelectableAsRoot()))
|
||||
if (object && (firstSceneRoot != object || isSelectableAsRoot())) {
|
||||
selectedObjs << objectToVariant(object);
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (qobject_cast<QQuick3DCamera *>(object))
|
||||
selectedCameras << object;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2241,6 +2270,11 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
updateActiveSceneToEditView3D();
|
||||
}
|
||||
|
||||
// Only update selected cameras if there are cameras in selection.
|
||||
// This way m_selectedCameras retains previous camera selection.
|
||||
if (!selectedCameras.isEmpty())
|
||||
m_selectedCameras.insert(m_active3DScene, selectedCameras);
|
||||
|
||||
// Ensure the UI has enough selection box items. If it doesn't yet have them, which can be the
|
||||
// case when the first selection processed is a multiselection, we wait a bit as
|
||||
// using the new boxes immediately leads to visual glitches.
|
||||
@@ -2297,6 +2331,45 @@ void Qt5InformationNodeInstanceServer::setSceneEnvironmentColor(const PropertyVa
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns list of camera objects to align
|
||||
// If m_selectedCameras contains cameras, return those
|
||||
// If no cameras have been selected yet, return camera associated with current view3D, if any
|
||||
// If scene is not View3D scene, return first camera in the scene
|
||||
QVariantList Qt5InformationNodeInstanceServer::alignCameraList() const
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
QVariantList cameras;
|
||||
if (m_selectedCameras.contains(m_active3DScene)) {
|
||||
const QObjectList cameraList = m_selectedCameras[m_active3DScene];
|
||||
for (const auto camera : cameraList) {
|
||||
if (hasInstanceForObject(camera) && find3DSceneRoot(camera) == m_active3DScene)
|
||||
cameras.append(objectToVariant(camera));
|
||||
}
|
||||
}
|
||||
|
||||
if (cameras.isEmpty()) {
|
||||
if (auto activeView = qobject_cast<QQuick3DViewport *>(m_active3DView)) {
|
||||
if (auto camera = activeView->camera()) {
|
||||
if (hasInstanceForObject(camera) && find3DSceneRoot(camera) == m_active3DScene)
|
||||
cameras.append(objectToVariant(camera));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cameras.isEmpty()) {
|
||||
const QList<ServerNodeInstance> allCameras = allCameraInstances();
|
||||
for (const auto &camera : allCameras) {
|
||||
if (find3DSceneRoot(camera) == m_active3DScene) {
|
||||
cameras.append(objectToVariant(camera.internalObject()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cameras;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)
|
||||
{
|
||||
bool hasDynamicProperties = false;
|
||||
@@ -2375,10 +2448,12 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "fitToView");
|
||||
break;
|
||||
case View3DActionType::AlignCamerasToView:
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "alignCamerasToView");
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "alignCamerasToView",
|
||||
Q_ARG(QVariant, alignCameraList()));
|
||||
break;
|
||||
case View3DActionType::AlignViewToCamera:
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "alignViewToCamera");
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "alignViewToCamera",
|
||||
Q_ARG(QVariant, alignCameraList()));
|
||||
break;
|
||||
case View3DActionType::SelectionModeToggle:
|
||||
updatedToolState.insert("selectionMode", command.isEnabled() ? 1 : 0);
|
||||
|
||||
@@ -135,6 +135,7 @@ private:
|
||||
void handleParticleSystemDeselected();
|
||||
#endif
|
||||
void setSceneEnvironmentColor(const PropertyValueContainer &container);
|
||||
QVariantList alignCameraList() const;
|
||||
|
||||
RenderViewData m_editView3DData;
|
||||
RenderViewData m_modelNode3DImageViewData;
|
||||
@@ -172,6 +173,9 @@ private:
|
||||
int m_need3DEditViewRender = 0;
|
||||
QSet<QObject *> m_dynamicObjectConstructors;
|
||||
|
||||
// Current or previous camera selections for each scene
|
||||
QHash<QObject *, QObjectList> m_selectedCameras; // key: scene root, value: camera node
|
||||
|
||||
struct PreviewData {
|
||||
QString env;
|
||||
QString envValue;
|
||||
|
||||
@@ -41,6 +41,14 @@
|
||||
#include <QtQuick/private/qquickitem_p.h>
|
||||
#endif
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QQuickGraphicsConfiguration>
|
||||
#include <QStandardPaths>
|
||||
#include <QTimer>
|
||||
#endif
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient)
|
||||
@@ -90,6 +98,7 @@ void Qt5NodeInstanceServer::initializeView()
|
||||
#else
|
||||
m_viewData.renderControl = new QQuickRenderControl;
|
||||
m_viewData.window = new QQuickWindow(m_viewData.renderControl);
|
||||
setPipelineCacheConfig(m_viewData.window);
|
||||
m_viewData.renderControl->initialize();
|
||||
m_qmlEngine = new QQmlEngine;
|
||||
#endif
|
||||
@@ -160,6 +169,20 @@ void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
|
||||
|
||||
setupInstances(command);
|
||||
resizeCanvasToRootItem();
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
if (!m_pipelineCacheLocation.isEmpty()) {
|
||||
QString fileId = command.fileUrl.toLocalFile();
|
||||
fileId.remove(':');
|
||||
fileId.remove('/');
|
||||
fileId.remove('.');
|
||||
m_pipelineCacheFile = QStringLiteral("%1/%2").arg(m_pipelineCacheLocation, fileId);
|
||||
|
||||
QFile cacheFile(m_pipelineCacheFile);
|
||||
if (cacheFile.open(QIODevice::ReadOnly))
|
||||
m_pipelineCacheData = cacheFile.readAll();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QList<QQuickItem*> subItems(QQuickItem *parentItem)
|
||||
@@ -185,7 +208,61 @@ const QList<QQuickItem*> Qt5NodeInstanceServer::allItems() const
|
||||
bool Qt5NodeInstanceServer::rootIsRenderable3DObject() const
|
||||
{
|
||||
return rootNodeInstance().isSubclassOf("QQuick3DNode")
|
||||
|| rootNodeInstance().isSubclassOf("QQuick3DMaterial");
|
||||
|| rootNodeInstance().isSubclassOf("QQuick3DMaterial");
|
||||
}
|
||||
|
||||
void Qt5NodeInstanceServer::savePipelineCacheData()
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
if (!m_viewData.rhi)
|
||||
return;
|
||||
|
||||
QByteArray pipelineData = m_viewData.rhi->pipelineCacheData();
|
||||
|
||||
if (pipelineData.isEmpty())
|
||||
return;
|
||||
|
||||
char count = 0;
|
||||
if (!m_pipelineCacheData.isEmpty())
|
||||
count = m_pipelineCacheData[m_pipelineCacheData.size() - 1];
|
||||
pipelineData.append(++count);
|
||||
|
||||
const bool needWrite = m_pipelineCacheData.size() != pipelineData.size()
|
||||
&& !m_pipelineCacheFile.isEmpty();
|
||||
|
||||
if (needWrite) {
|
||||
m_pipelineCacheData = pipelineData;
|
||||
|
||||
QTimer::singleShot(0, this, [this]() {
|
||||
QFile cacheFile(m_pipelineCacheFile);
|
||||
|
||||
// Cache file can grow indefinitely, so let's just purge it every so often.
|
||||
// The count is stored as the last char in the data.
|
||||
char count = m_pipelineCacheData[m_pipelineCacheData.size() - 1];
|
||||
if (count > 25)
|
||||
cacheFile.remove();
|
||||
else if (cacheFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
cacheFile.write(m_pipelineCacheData);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5NodeInstanceServer::setPipelineCacheConfig([[maybe_unused]] QQuickWindow *w)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
// This dummy file is not actually used for cache as we manage cache save/load ourselves,
|
||||
// but some file needs to be set to enable pipeline caching
|
||||
const QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
m_pipelineCacheLocation = QStringLiteral("%1/%2").arg(cachePath, "pipecache");
|
||||
QDir(m_pipelineCacheLocation).mkpath(".");
|
||||
const QString dummyCache = m_pipelineCacheLocation + "/dummycache";
|
||||
|
||||
QQuickGraphicsConfiguration config = w->graphicsConfiguration();
|
||||
config.setPipelineCacheSaveFile(dummyCache);
|
||||
config.setAutomaticPipelineCache(false);
|
||||
w->setGraphicsConfiguration(config);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Qt5NodeInstanceServer::initRhi([[maybe_unused]] RenderViewData &viewData)
|
||||
@@ -204,6 +281,10 @@ bool Qt5NodeInstanceServer::initRhi([[maybe_unused]] RenderViewData &viewData)
|
||||
qWarning() << __FUNCTION__ << "Rhi is null";
|
||||
return false;
|
||||
}
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 1)
|
||||
if (!m_pipelineCacheData.isEmpty())
|
||||
viewData.rhi->setPipelineCacheData(m_pipelineCacheData.left(m_pipelineCacheData.size() - 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
auto cleanRhiResources = [&viewData]() {
|
||||
|
||||
@@ -59,6 +59,8 @@ protected:
|
||||
void setupScene(const CreateSceneCommand &command) override;
|
||||
const QList<QQuickItem*> allItems() const;
|
||||
bool rootIsRenderable3DObject() const;
|
||||
void savePipelineCacheData();
|
||||
void setPipelineCacheConfig(QQuickWindow *w);
|
||||
|
||||
struct RenderViewData {
|
||||
QPointer<QQuickWindow> window = nullptr;
|
||||
@@ -80,6 +82,9 @@ protected:
|
||||
|
||||
private:
|
||||
RenderViewData m_viewData;
|
||||
QByteArray m_pipelineCacheData;
|
||||
QString m_pipelineCacheLocation;
|
||||
QString m_pipelineCacheFile;
|
||||
std::unique_ptr<QQuickDesignerSupport> m_designerSupport;
|
||||
QQmlEngine *m_qmlEngine = nullptr;
|
||||
};
|
||||
|
||||
@@ -110,8 +110,8 @@ PropertyNameList allPropertyNamesInline(QObject *object,
|
||||
inspectedObjects,
|
||||
depth + 1));
|
||||
}
|
||||
} else if (QQmlGadgetPtrWrapper *valueType
|
||||
= QQmlGadgetPtrWrapper::instance(qmlEngine(object), metaProperty.userType())) {
|
||||
} else if (QQmlGadgetPtrWrapper *valueType = QQmlGadgetPtrWrapper::instance(
|
||||
qmlEngine(object), metaProperty.typeId())) {
|
||||
valueType->setValue(metaProperty.read(object));
|
||||
propertyNameList.append(baseName
|
||||
+ QQuickDesignerSupport::PropertyName(metaProperty.name()));
|
||||
@@ -224,8 +224,7 @@ static QString qmlDesignerRCPath()
|
||||
|
||||
QVariant fixResourcePaths(const QVariant &value)
|
||||
{
|
||||
if (value.type() == QVariant::Url)
|
||||
{
|
||||
if (value.typeId() == QVariant::Url) {
|
||||
const QUrl url = value.toUrl();
|
||||
if (url.scheme() == QLatin1String("qrc")) {
|
||||
const QString path = QLatin1String("qrc:") + url.path();
|
||||
@@ -246,7 +245,7 @@ QVariant fixResourcePaths(const QVariant &value)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value.type() == QVariant::String) {
|
||||
if (value.typeId() == QVariant::String) {
|
||||
const QString str = value.toString();
|
||||
if (str.contains(QLatin1String("qrc:"))) {
|
||||
if (!qmlDesignerRCPath().isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user