forked from qt-creator/qt-creator
QmlDesigner: Add lock feature support to 3D editor
Added lock feature support for 3D editor. Also refactored the hide support, since the two use largely similar logic. Task-number: QDS-2915 Change-Id: I627848f3a3a73881427a03aeec6793fd26a1885a Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
committed by
Miikka Heikkinen
parent
3d78fef4ef
commit
f2883c19b1
@@ -46,8 +46,8 @@ IconGizmo {
|
|||||||
frustum.targetNode = targetNode;
|
frustum.targetNode = targetNode;
|
||||||
frustum.targetNode = Qt.binding(function() {return targetNode;});
|
frustum.targetNode = Qt.binding(function() {return targetNode;});
|
||||||
|
|
||||||
frustum.visible = visible;
|
frustum.visible = visible || (targetNode && selected && activeScene === scene);
|
||||||
frustum.visible = Qt.binding(function() {return visible;});
|
frustum.visible = Qt.binding(function() {return visible || (targetNode && selected && activeScene === scene);});
|
||||||
}
|
}
|
||||||
|
|
||||||
onActiveSceneChanged: {
|
onActiveSceneChanged: {
|
||||||
|
|||||||
@@ -263,11 +263,16 @@ Item {
|
|||||||
|
|
||||||
function handleObjectClicked(object, multi)
|
function handleObjectClicked(object, multi)
|
||||||
{
|
{
|
||||||
var theObject = object;
|
var clickedObject;
|
||||||
|
|
||||||
|
// Click on locked object is treated same as click on empty space
|
||||||
|
if (!_generalHelper.isLocked(object))
|
||||||
|
clickedObject = object;
|
||||||
|
|
||||||
if (selectionMode === EditView3D.SelectionMode.Group) {
|
if (selectionMode === EditView3D.SelectionMode.Group) {
|
||||||
while (theObject && theObject !== activeScene
|
while (clickedObject && clickedObject !== activeScene
|
||||||
&& (activeScene instanceof Model || theObject.parent !== activeScene)) {
|
&& (activeScene instanceof Model || clickedObject.parent !== activeScene)) {
|
||||||
theObject = theObject.parent;
|
clickedObject = clickedObject.parent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Object selection logic:
|
// Object selection logic:
|
||||||
@@ -276,20 +281,20 @@ Item {
|
|||||||
// One or more objects selected: Multiselect
|
// One or more objects selected: Multiselect
|
||||||
// Null object always clears entire selection
|
// Null object always clears entire selection
|
||||||
var newSelection = [];
|
var newSelection = [];
|
||||||
if (object !== null) {
|
if (clickedObject) {
|
||||||
if (multi && selectedNodes.length > 0) {
|
if (multi && selectedNodes.length > 0) {
|
||||||
var deselect = false;
|
var deselect = false;
|
||||||
for (var i = 0; i < selectedNodes.length; ++i) {
|
for (var i = 0; i < selectedNodes.length; ++i) {
|
||||||
// Multiselecting already selected object clears that object from selection
|
// Multiselecting already selected object clears that object from selection
|
||||||
if (selectedNodes[i] !== object)
|
if (selectedNodes[i] !== clickedObject)
|
||||||
newSelection[newSelection.length] = selectedNodes[i];
|
newSelection[newSelection.length] = selectedNodes[i];
|
||||||
else
|
else
|
||||||
deselect = true;
|
deselect = true;
|
||||||
}
|
}
|
||||||
if (!deselect)
|
if (!deselect)
|
||||||
newSelection[newSelection.length] = object;
|
newSelection[newSelection.length] = clickedObject;
|
||||||
} else {
|
} else {
|
||||||
newSelection[0] = theObject;
|
newSelection[0] = clickedObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectObjects(newSelection);
|
selectObjects(newSelection);
|
||||||
@@ -312,16 +317,22 @@ Item {
|
|||||||
if (slotFound !== -1) {
|
if (slotFound !== -1) {
|
||||||
lightIconGizmos[slotFound].scene = scene;
|
lightIconGizmos[slotFound].scene = scene;
|
||||||
lightIconGizmos[slotFound].targetNode = obj;
|
lightIconGizmos[slotFound].targetNode = obj;
|
||||||
|
lightIconGizmos[slotFound].locked = _generalHelper.isLocked(obj);
|
||||||
|
lightIconGizmos[slotFound].hidden = _generalHelper.isHidden(obj);
|
||||||
|
_generalHelper.registerGizmoTarget(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No free gizmos available, create a new one
|
// No free gizmos available, create a new one
|
||||||
var gizmoComponent = Qt.createComponent("LightIconGizmo.qml");
|
var gizmoComponent = Qt.createComponent("LightIconGizmo.qml");
|
||||||
if (gizmoComponent.status === Component.Ready) {
|
if (gizmoComponent.status === Component.Ready) {
|
||||||
|
_generalHelper.registerGizmoTarget(obj);
|
||||||
var gizmo = gizmoComponent.createObject(overlayView,
|
var gizmo = gizmoComponent.createObject(overlayView,
|
||||||
{"view3D": overlayView, "targetNode": obj,
|
{"view3D": overlayView, "targetNode": obj,
|
||||||
"selectedNodes": selectedNodes, "scene": scene,
|
"selectedNodes": selectedNodes, "scene": scene,
|
||||||
"activeScene": activeScene});
|
"activeScene": activeScene,
|
||||||
|
"locked": _generalHelper.isLocked(obj),
|
||||||
|
"hidden": _generalHelper.isHidden(obj)});
|
||||||
lightIconGizmos[lightIconGizmos.length] = gizmo;
|
lightIconGizmos[lightIconGizmos.length] = gizmo;
|
||||||
gizmo.clicked.connect(handleObjectClicked);
|
gizmo.clicked.connect(handleObjectClicked);
|
||||||
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
||||||
@@ -345,6 +356,9 @@ Item {
|
|||||||
if (slotFound !== -1) {
|
if (slotFound !== -1) {
|
||||||
cameraGizmos[slotFound].scene = scene;
|
cameraGizmos[slotFound].scene = scene;
|
||||||
cameraGizmos[slotFound].targetNode = obj;
|
cameraGizmos[slotFound].targetNode = obj;
|
||||||
|
cameraGizmos[slotFound].locked = _generalHelper.isLocked(obj);
|
||||||
|
cameraGizmos[slotFound].hidden = _generalHelper.isHidden(obj);
|
||||||
|
_generalHelper.registerGizmoTarget(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +366,7 @@ Item {
|
|||||||
var gizmoComponent = Qt.createComponent("CameraGizmo.qml");
|
var gizmoComponent = Qt.createComponent("CameraGizmo.qml");
|
||||||
var frustumComponent = Qt.createComponent("CameraFrustum.qml");
|
var frustumComponent = Qt.createComponent("CameraFrustum.qml");
|
||||||
if (gizmoComponent.status === Component.Ready && frustumComponent.status === Component.Ready) {
|
if (gizmoComponent.status === Component.Ready && frustumComponent.status === Component.Ready) {
|
||||||
|
_generalHelper.registerGizmoTarget(obj);
|
||||||
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
|
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
|
||||||
var frustum = frustumComponent.createObject(
|
var frustum = frustumComponent.createObject(
|
||||||
overlayScene,
|
overlayScene,
|
||||||
@@ -359,7 +374,8 @@ Item {
|
|||||||
var gizmo = gizmoComponent.createObject(
|
var gizmo = gizmoComponent.createObject(
|
||||||
overlayView,
|
overlayView,
|
||||||
{"view3D": overlayView, "targetNode": obj,
|
{"view3D": overlayView, "targetNode": obj,
|
||||||
"selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene});
|
"selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene,
|
||||||
|
"locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj)});
|
||||||
|
|
||||||
cameraGizmos[cameraGizmos.length] = gizmo;
|
cameraGizmos[cameraGizmos.length] = gizmo;
|
||||||
gizmo.clicked.connect(handleObjectClicked);
|
gizmo.clicked.connect(handleObjectClicked);
|
||||||
@@ -376,6 +392,7 @@ Item {
|
|||||||
if (lightIconGizmos[i].targetNode === obj) {
|
if (lightIconGizmos[i].targetNode === obj) {
|
||||||
lightIconGizmos[i].scene = null;
|
lightIconGizmos[i].scene = null;
|
||||||
lightIconGizmos[i].targetNode = null;
|
lightIconGizmos[i].targetNode = null;
|
||||||
|
_generalHelper.unregisterGizmoTarget(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,6 +404,7 @@ Item {
|
|||||||
if (cameraGizmos[i].targetNode === obj) {
|
if (cameraGizmos[i].targetNode === obj) {
|
||||||
cameraGizmos[i].scene = null;
|
cameraGizmos[i].scene = null;
|
||||||
cameraGizmos[i].targetNode = null;
|
cameraGizmos[i].targetNode = null;
|
||||||
|
_generalHelper.unregisterGizmoTarget(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,6 +441,40 @@ Item {
|
|||||||
onWidthChanged: _generalHelper.requestOverlayUpdate()
|
onWidthChanged: _generalHelper.requestOverlayUpdate()
|
||||||
onHeightChanged: _generalHelper.requestOverlayUpdate()
|
onHeightChanged: _generalHelper.requestOverlayUpdate()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: _generalHelper
|
||||||
|
function onLockedStateChanged(node)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||||
|
if (cameraGizmos[i].targetNode === node) {
|
||||||
|
cameraGizmos[i].locked = _generalHelper.isLocked(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||||
|
if (lightIconGizmos[i].targetNode === node) {
|
||||||
|
lightIconGizmos[i].locked = _generalHelper.isLocked(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function onHiddenStateChanged(node)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||||
|
if (cameraGizmos[i].targetNode === node) {
|
||||||
|
cameraGizmos[i].hidden = _generalHelper.isHidden(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||||
|
if (lightIconGizmos[i].targetNode === node) {
|
||||||
|
lightIconGizmos[i].hidden = _generalHelper.isHidden(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
id: overlayScene
|
id: overlayScene
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ Item {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
property bool hasMouse: false
|
property bool hasMouse: false
|
||||||
|
property bool hidden: false
|
||||||
|
property bool locked: false
|
||||||
|
|
||||||
property alias iconSource: iconImage.source
|
property alias iconSource: iconImage.source
|
||||||
|
|
||||||
@@ -53,7 +55,7 @@ Item {
|
|||||||
hasMouse = false;
|
hasMouse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: activeScene === scene && (targetNode ? targetNode.visible : false)
|
visible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false)
|
||||||
|
|
||||||
Overlay2D {
|
Overlay2D {
|
||||||
id: iconOverlay
|
id: iconOverlay
|
||||||
@@ -70,7 +72,7 @@ Item {
|
|||||||
y: -height / 2
|
y: -height / 2
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: "#7777ff"
|
border.color: "#7777ff"
|
||||||
border.width: iconGizmo.highlightOnHover && iconGizmo.hasMouse ? 2 : 0
|
border.width: !iconGizmo.locked && iconGizmo.highlightOnHover && iconGizmo.hasMouse ? 2 : 0
|
||||||
radius: 5
|
radius: 5
|
||||||
opacity: iconGizmo.selected ? 0.2 : 1
|
opacity: iconGizmo.selected ? 0.2 : 1
|
||||||
Image {
|
Image {
|
||||||
|
|||||||
@@ -244,6 +244,40 @@ QQuick3DNode *GeneralHelper::resolvePick(QQuick3DNode *pickNode)
|
|||||||
return pickNode;
|
return pickNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneralHelper::registerGizmoTarget(QQuick3DNode *node)
|
||||||
|
{
|
||||||
|
if (!m_gizmoTargets.contains(node)) {
|
||||||
|
m_gizmoTargets.insert(node);
|
||||||
|
node->installEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneralHelper::unregisterGizmoTarget(QQuick3DNode *node)
|
||||||
|
{
|
||||||
|
if (m_gizmoTargets.contains(node)) {
|
||||||
|
m_gizmoTargets.remove(node);
|
||||||
|
node->removeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GeneralHelper::isLocked(QQuick3DNode *node)
|
||||||
|
{
|
||||||
|
if (node) {
|
||||||
|
QVariant lockValue = node->property("_edit3dLocked");
|
||||||
|
return lockValue.isValid() && lockValue.toBool();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GeneralHelper::isHidden(QQuick3DNode *node)
|
||||||
|
{
|
||||||
|
if (node) {
|
||||||
|
QVariant hideValue = node->property("_edit3dHidden");
|
||||||
|
return hideValue.isValid() && hideValue.toBool();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool, const QVariant &state,
|
void GeneralHelper::storeToolState(const QString &sceneId, const QString &tool, const QVariant &state,
|
||||||
int delay)
|
int delay)
|
||||||
{
|
{
|
||||||
@@ -322,6 +356,21 @@ bool GeneralHelper::isMacOS() const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GeneralHelper::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::DynamicPropertyChange) {
|
||||||
|
auto node = qobject_cast<QQuick3DNode *>(obj);
|
||||||
|
if (m_gizmoTargets.contains(node)) {
|
||||||
|
auto de = static_cast<QDynamicPropertyChangeEvent *>(event);
|
||||||
|
if (de->propertyName() == "_edit3dLocked")
|
||||||
|
emit lockedStateChanged(node);
|
||||||
|
else if (de->propertyName() == "_edit3dHidden")
|
||||||
|
emit hiddenStateChanged(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
void GeneralHelper::handlePendingToolStateUpdate()
|
void GeneralHelper::handlePendingToolStateUpdate()
|
||||||
{
|
{
|
||||||
m_toolStateUpdateTimer.stop();
|
m_toolStateUpdateTimer.stop();
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ public:
|
|||||||
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
||||||
const QVariant& value);
|
const QVariant& value);
|
||||||
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
||||||
|
|
||||||
|
Q_INVOKABLE void registerGizmoTarget(QQuick3DNode *node);
|
||||||
|
Q_INVOKABLE void unregisterGizmoTarget(QQuick3DNode *node);
|
||||||
|
Q_INVOKABLE bool isLocked(QQuick3DNode *node);
|
||||||
|
Q_INVOKABLE bool isHidden(QQuick3DNode *node);
|
||||||
|
|
||||||
Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool,
|
Q_INVOKABLE void storeToolState(const QString &sceneId, const QString &tool,
|
||||||
const QVariant &state, int delayEmit = 0);
|
const QVariant &state, int delayEmit = 0);
|
||||||
void initToolStates(const QString &sceneId, const QVariantMap &toolStates);
|
void initToolStates(const QString &sceneId, const QVariantMap &toolStates);
|
||||||
@@ -90,6 +96,11 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void overlayUpdateNeeded();
|
void overlayUpdateNeeded();
|
||||||
void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState);
|
void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState);
|
||||||
|
void hiddenStateChanged(QQuick3DNode *node);
|
||||||
|
void lockedStateChanged(QQuick3DNode *node);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handlePendingToolStateUpdate();
|
void handlePendingToolStateUpdate();
|
||||||
@@ -98,6 +109,7 @@ private:
|
|||||||
QTimer m_toolStateUpdateTimer;
|
QTimer m_toolStateUpdateTimer;
|
||||||
QHash<QString, QVariantMap> m_toolStates;
|
QHash<QString, QVariantMap> m_toolStates;
|
||||||
QHash<QString, QVariantMap> m_toolStatesPending;
|
QHash<QString, QVariantMap> m_toolStatesPending;
|
||||||
|
QSet<QQuick3DNode *> m_gizmoTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -998,9 +998,17 @@ void NodeInstanceServer::setInstanceAuxiliaryData(const PropertyValueContainer &
|
|||||||
if (hasInstanceForId(auxiliaryContainer.instanceId())) {
|
if (hasInstanceForId(auxiliaryContainer.instanceId())) {
|
||||||
ServerNodeInstance instance = instanceForId(auxiliaryContainer.instanceId());
|
ServerNodeInstance instance = instanceForId(auxiliaryContainer.instanceId());
|
||||||
if (!auxiliaryContainer.value().isNull())
|
if (!auxiliaryContainer.value().isNull())
|
||||||
instance.setHideInEditor(auxiliaryContainer.value().toBool());
|
instance.setHiddenInEditor(auxiliaryContainer.value().toBool());
|
||||||
else
|
else
|
||||||
instance.setHideInEditor(false);
|
instance.setHiddenInEditor(false);
|
||||||
|
}
|
||||||
|
} else if (auxiliaryContainer.name() == "locked") {
|
||||||
|
if (hasInstanceForId(auxiliaryContainer.instanceId())) {
|
||||||
|
ServerNodeInstance instance = instanceForId(auxiliaryContainer.instanceId());
|
||||||
|
if (!auxiliaryContainer.value().isNull())
|
||||||
|
instance.setLockedInEditor(auxiliaryContainer.value().toBool());
|
||||||
|
else
|
||||||
|
instance.setLockedInEditor(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1480,4 +1488,14 @@ void NodeInstanceServer::initializeAuxiliaryViews()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeInstanceServer::handleInstanceLocked(const ServerNodeInstance &/*instance*/, bool /*enable*/,
|
||||||
|
bool /*checkAncestors*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeInstanceServer::handleInstanceHidden(const ServerNodeInstance &/*instance*/, bool /*enable*/,
|
||||||
|
bool /*checkAncestors*/)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -208,6 +208,9 @@ public:
|
|||||||
|
|
||||||
virtual void collectItemChangesAndSendChangeCommands() = 0;
|
virtual void collectItemChangesAndSendChangeCommands() = 0;
|
||||||
|
|
||||||
|
virtual void handleInstanceLocked(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||||
|
virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void refreshLocalFileProperty(const QString &path);
|
void refreshLocalFileProperty(const QString &path);
|
||||||
void refreshDummyData(const QString &path);
|
void refreshDummyData(const QString &path);
|
||||||
|
|||||||
@@ -392,8 +392,24 @@ PropertyNameList ObjectNodeInstance::ignoredProperties() const
|
|||||||
return PropertyNameList();
|
return PropertyNameList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectNodeInstance::setHideInEditor(bool)
|
void ObjectNodeInstance::setHiddenInEditor(bool b)
|
||||||
{
|
{
|
||||||
|
m_isHiddenInEditor = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectNodeInstance::isHiddenInEditor() const
|
||||||
|
{
|
||||||
|
return m_isHiddenInEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectNodeInstance::setLockedInEditor(bool b)
|
||||||
|
{
|
||||||
|
m_isLockedInEditor = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ObjectNodeInstance::isLockedInEditor() const
|
||||||
|
{
|
||||||
|
return m_isLockedInEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectNodeInstance::setModifiedFlag(bool b)
|
void ObjectNodeInstance::setModifiedFlag(bool b)
|
||||||
|
|||||||
@@ -196,7 +196,11 @@ public:
|
|||||||
|
|
||||||
virtual PropertyNameList ignoredProperties() const;
|
virtual PropertyNameList ignoredProperties() const;
|
||||||
|
|
||||||
void virtual setHideInEditor(bool b);
|
virtual void setHiddenInEditor(bool b);
|
||||||
|
bool isHiddenInEditor() const;
|
||||||
|
|
||||||
|
virtual void setLockedInEditor(bool b);
|
||||||
|
bool isLockedInEditor() const;
|
||||||
|
|
||||||
void setModifiedFlag(bool b);
|
void setModifiedFlag(bool b);
|
||||||
|
|
||||||
@@ -213,6 +217,7 @@ protected:
|
|||||||
|
|
||||||
void initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance);
|
void initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance);
|
||||||
void ensureVector3DDotProperties(PropertyNameList &list) const;
|
void ensureVector3DDotProperties(PropertyNameList &list) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
|
|
||||||
@@ -227,6 +232,8 @@ private:
|
|||||||
bool m_deleteHeldInstance;
|
bool m_deleteHeldInstance;
|
||||||
bool m_isInLayoutable;
|
bool m_isInLayoutable;
|
||||||
bool m_isModified = false;
|
bool m_isModified = false;
|
||||||
|
bool m_isLockedInEditor = false;
|
||||||
|
bool m_isHiddenInEditor = false;
|
||||||
static QHash<EnumerationName, QVariant> m_enumationValueHash;
|
static QHash<EnumerationName, QVariant> m_enumationValueHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,12 @@ static bool imageHasContent(const QImage &image)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isQuick3DMode()
|
||||||
|
{
|
||||||
|
static bool mode3D = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE");
|
||||||
|
return mode3D;
|
||||||
|
}
|
||||||
|
|
||||||
QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
||||||
QQuickItem *&rootItem)
|
QQuickItem *&rootItem)
|
||||||
{
|
{
|
||||||
@@ -154,6 +160,23 @@ QQuickView *Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUr
|
|||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances)
|
||||||
|
{
|
||||||
|
if (!isQuick3DMode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We only want to update the topmost parents in the set
|
||||||
|
for (const auto &instance : instances) {
|
||||||
|
if (instance.isValid()) {
|
||||||
|
const auto parentInst = instance.parent();
|
||||||
|
if (!parentInst.isValid() || !instances.contains(parentInst)) {
|
||||||
|
handleInstanceHidden(instance, instance.internalInstance()->isHiddenInEditor(), true);
|
||||||
|
handleInstanceLocked(instance, instance.internalInstance()->isLockedInEditor(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::createEditView3D()
|
void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
@@ -860,7 +883,7 @@ QList<ServerNodeInstance> Qt5InformationNodeInstanceServer::createInstances(
|
|||||||
void Qt5InformationNodeInstanceServer::initializeAuxiliaryViews()
|
void Qt5InformationNodeInstanceServer::initializeAuxiliaryViews()
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE")) {
|
if (isQuick3DMode()) {
|
||||||
createEditView3D();
|
createEditView3D();
|
||||||
m_ModelNode3DImageView = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml"),
|
m_ModelNode3DImageView = createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml"),
|
||||||
m_ModelNode3DImageViewRootItem);
|
m_ModelNode3DImageViewRootItem);
|
||||||
@@ -1243,6 +1266,7 @@ void Qt5InformationNodeInstanceServer::collectItemChangesAndSendChangeCommands()
|
|||||||
|
|
||||||
if (!m_parentChangedSet.isEmpty()) {
|
if (!m_parentChangedSet.isEmpty()) {
|
||||||
sendChildrenChangedCommand(QtHelpers::toList(m_parentChangedSet));
|
sendChildrenChangedCommand(QtHelpers::toList(m_parentChangedSet));
|
||||||
|
updateLockedAndHiddenStates(m_parentChangedSet);
|
||||||
m_parentChangedSet.clear();
|
m_parentChangedSet.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1307,7 +1331,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
|||||||
sendChildrenChangedCommand(instanceList);
|
sendChildrenChangedCommand(instanceList);
|
||||||
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
|
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
|
||||||
|
|
||||||
if (qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE"))
|
if (isQuick3DMode())
|
||||||
setup3DEditView(instanceList, command.edit3dToolStates());
|
setup3DEditView(instanceList, command.edit3dToolStates());
|
||||||
|
|
||||||
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
|
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
|
||||||
@@ -1621,6 +1645,110 @@ void Qt5InformationNodeInstanceServer::removeProperties(const RemovePropertiesCo
|
|||||||
render3DEditView();
|
render3DEditView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::handleInstanceLocked(const ServerNodeInstance &instance,
|
||||||
|
bool enable, bool checkAncestors)
|
||||||
|
{
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
if (!isQuick3DMode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool edit3dLocked = enable;
|
||||||
|
if (!edit3dLocked || checkAncestors) {
|
||||||
|
auto parentInst = instance.parent();
|
||||||
|
while (!edit3dLocked && parentInst.isValid()) {
|
||||||
|
edit3dLocked = parentInst.internalInstance()->isLockedInEditor();
|
||||||
|
parentInst = parentInst.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject *obj = instance.internalObject();
|
||||||
|
auto node = qobject_cast<QQuick3DNode *>(obj);
|
||||||
|
if (node)
|
||||||
|
node->setProperty("_edit3dLocked", edit3dLocked);
|
||||||
|
const auto children = obj->children();
|
||||||
|
for (auto child : children) {
|
||||||
|
if (hasInstanceForObject(child)) {
|
||||||
|
const ServerNodeInstance childInstance = instanceForObject(child);
|
||||||
|
if (childInstance.isValid()) {
|
||||||
|
auto objInstance = childInstance.internalInstance();
|
||||||
|
// Don't override explicit lock on children
|
||||||
|
handleInstanceLocked(childInstance, edit3dLocked || objInstance->isLockedInEditor(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInstance &instance,
|
||||||
|
bool enable, bool checkAncestors)
|
||||||
|
{
|
||||||
|
#ifdef QUICK3D_MODULE
|
||||||
|
if (!isQuick3DMode())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool edit3dHidden = enable;
|
||||||
|
if (!edit3dHidden || checkAncestors) {
|
||||||
|
// We do not care about hidden status of non-3D ancestor nodes, as the 3D scene
|
||||||
|
// can be considered a separate visual entity in the whole scene.
|
||||||
|
auto parentInst = instance.parent();
|
||||||
|
while (!edit3dHidden && parentInst.isValid() && qobject_cast<QQuick3DNode *>(parentInst.internalObject())) {
|
||||||
|
edit3dHidden = parentInst.internalInstance()->isHiddenInEditor();
|
||||||
|
parentInst = parentInst.parent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto node = qobject_cast<QQuick3DNode *>(instance.internalObject());
|
||||||
|
if (node) {
|
||||||
|
bool isInstanceHidden = false;
|
||||||
|
auto getQuick3DInstanceAndHidden = [this, &isInstanceHidden](QQuick3DObject *obj) -> ServerNodeInstance {
|
||||||
|
if (hasInstanceForObject(obj)) {
|
||||||
|
const ServerNodeInstance instance = instanceForObject(obj);
|
||||||
|
if (instance.isValid() && qobject_cast<QQuick3DNode *>(instance.internalObject())) {
|
||||||
|
auto objInstance = instance.internalInstance();
|
||||||
|
isInstanceHidden = objInstance->isHiddenInEditor();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
// Always make sure the hide status is correct on the node tree from this point on,
|
||||||
|
// as changes in the node tree (reparenting, adding new nodes) can make the previously set
|
||||||
|
// hide status based on ancestor unreliable.
|
||||||
|
node->setProperty("_edit3dHidden", edit3dHidden);
|
||||||
|
if (auto model = qobject_cast<QQuick3DModel *>(node))
|
||||||
|
model->setPickable(!edit3dHidden); // allow 3D objects to receive mouse clicks
|
||||||
|
const auto childItems = node->childItems();
|
||||||
|
for (auto childItem : childItems) {
|
||||||
|
const ServerNodeInstance quick3dInstance = getQuick3DInstanceAndHidden(childItem);
|
||||||
|
if (quick3dInstance.isValid()) {
|
||||||
|
// Don't override explicit hide in children
|
||||||
|
handleInstanceHidden(quick3dInstance, edit3dHidden || isInstanceHidden, false);
|
||||||
|
} else {
|
||||||
|
// Children of components do not have instances, but will still need to be pickable
|
||||||
|
std::function<void(QQuick3DNode *)> checkChildren;
|
||||||
|
checkChildren = [&](QQuick3DNode *checkNode) {
|
||||||
|
const auto childItems = checkNode->childItems();
|
||||||
|
for (auto child : childItems) {
|
||||||
|
if (auto childNode = qobject_cast<QQuick3DNode *>(child))
|
||||||
|
checkChildren(childNode);
|
||||||
|
}
|
||||||
|
if (auto checkModel = qobject_cast<QQuick3DModel *>(checkNode)) {
|
||||||
|
QVariant value;
|
||||||
|
if (!edit3dHidden)
|
||||||
|
value = QVariant::fromValue(node);
|
||||||
|
// Specify the actual pick target with dynamic property
|
||||||
|
checkModel->setProperty("_pickTarget", value);
|
||||||
|
checkModel->setPickable(!edit3dHidden);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (auto childNode = qobject_cast<QQuick3DNode *>(childItem))
|
||||||
|
checkChildren(childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// update 3D view size when it changes in creator side
|
// update 3D view size when it changes in creator side
|
||||||
void Qt5InformationNodeInstanceServer::update3DViewState(const Update3dViewStateCommand &command)
|
void Qt5InformationNodeInstanceServer::update3DViewState(const Update3dViewStateCommand &command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ public:
|
|||||||
void changeState(const ChangeStateCommand &command) override;
|
void changeState(const ChangeStateCommand &command) override;
|
||||||
void removeProperties(const RemovePropertiesCommand &command) override;
|
void removeProperties(const RemovePropertiesCommand &command) override;
|
||||||
|
|
||||||
|
void handleInstanceLocked(const ServerNodeInstance &instance, bool enable, bool checkAncestors) override;
|
||||||
|
void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleSelectionChanged(const QVariant &objs);
|
void handleSelectionChanged(const QVariant &objs);
|
||||||
void handleObjectPropertyCommit(const QVariant &object, const QVariant &propName);
|
void handleObjectPropertyCommit(const QVariant &object, const QVariant &propName);
|
||||||
@@ -127,6 +130,7 @@ private:
|
|||||||
void doRenderModelNode3DImageView();
|
void doRenderModelNode3DImageView();
|
||||||
void doRenderModelNode2DImageView();
|
void doRenderModelNode2DImageView();
|
||||||
QQuickView *createAuxiliaryQuickView(const QUrl &url, QQuickItem *&rootItem);
|
QQuickView *createAuxiliaryQuickView(const QUrl &url, QQuickItem *&rootItem);
|
||||||
|
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
||||||
|
|
||||||
QPointer<QQuickView> m_editView3D;
|
QPointer<QQuickView> m_editView3D;
|
||||||
QQuickItem *m_editView3DRootItem = nullptr;
|
QQuickItem *m_editView3DRootItem = nullptr;
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo
|
|||||||
InstanceContainer::NodeFlags flags)
|
InstanceContainer::NodeFlags flags)
|
||||||
{
|
{
|
||||||
ObjectNodeInstance::initialize(objectNodeInstance, flags);
|
ObjectNodeInstance::initialize(objectNodeInstance, flags);
|
||||||
setPickable(true, true, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
|
Qt5NodeInstanceServer *Quick3DNodeInstance::qt5NodeInstanceServer() const
|
||||||
@@ -74,71 +73,6 @@ QQuick3DNode *Quick3DNodeInstance::quick3DNode() const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quick3DNodeInstance::setPickable(bool enable, bool checkParent, bool applyToChildInstances)
|
|
||||||
{
|
|
||||||
#ifdef QUICK3D_MODULE
|
|
||||||
auto node = quick3DNode();
|
|
||||||
if (node) {
|
|
||||||
bool parentHidden = false;
|
|
||||||
if (checkParent) {
|
|
||||||
// First check if any parent node is already hidden. Never set pickable on that case.
|
|
||||||
auto parentNode = node->parentNode();
|
|
||||||
while (parentNode && !parentHidden) {
|
|
||||||
parentHidden = QQuick3DNodePrivate::get(parentNode)->m_isHiddenInEditor;
|
|
||||||
parentNode = parentNode->parentNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!parentHidden) {
|
|
||||||
auto getQuick3DInstance = [this](QQuick3DObject *obj) -> Quick3DNodeInstance * {
|
|
||||||
if (nodeInstanceServer()->hasInstanceForObject(obj)) {
|
|
||||||
ServerNodeInstance instance = nodeInstanceServer()->instanceForObject(obj);
|
|
||||||
if (instance.isValid() && qobject_cast<QQuick3DNode *>(instance.internalObject()))
|
|
||||||
return static_cast<Quick3DNodeInstance *>(instance.internalInstance().data());
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
const auto childItems = node->childItems();
|
|
||||||
for (auto childItem : childItems) {
|
|
||||||
if (auto quick3dInstance = getQuick3DInstance(childItem)) {
|
|
||||||
if (applyToChildInstances) {
|
|
||||||
// Don't override explicit block in children
|
|
||||||
if (!QQuick3DNodePrivate::get(quick3dInstance->quick3DNode())->m_isHiddenInEditor)
|
|
||||||
quick3dInstance->setPickable(enable, false, true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Children of components do not have instances, but will still need to be
|
|
||||||
// pickable. These need to be set even if applyToChildInstances is false.
|
|
||||||
std::function<void(QQuick3DNode *)> checkChildren;
|
|
||||||
checkChildren = [&](QQuick3DNode *checkNode) {
|
|
||||||
const auto childItems = checkNode->childItems();
|
|
||||||
for (auto child : childItems) {
|
|
||||||
if (auto childNode = qobject_cast<QQuick3DNode *>(child))
|
|
||||||
checkChildren(childNode);
|
|
||||||
}
|
|
||||||
if (auto checkModel = qobject_cast<QQuick3DModel *>(checkNode)) {
|
|
||||||
QVariant value;
|
|
||||||
if (enable)
|
|
||||||
value = QVariant::fromValue(node);
|
|
||||||
// Specify the actual pick target with dynamic property
|
|
||||||
checkModel->setProperty("_pickTarget", value);
|
|
||||||
checkModel->setPickable(enable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
checkChildren(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (qobject_cast<QQuick3DModel *>(node))
|
|
||||||
setPropertyVariant("pickable", enable); // allow 3D objects to receive mouse clicks
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(enable)
|
|
||||||
Q_UNUSED(checkParent)
|
|
||||||
Q_UNUSED(applyToChildInstances)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Quick3DNodeInstance::Pointer Quick3DNodeInstance::create(QObject *object)
|
Quick3DNodeInstance::Pointer Quick3DNodeInstance::create(QObject *object)
|
||||||
{
|
{
|
||||||
Pointer instance(new Quick3DNodeInstance(object));
|
Pointer instance(new Quick3DNodeInstance(object));
|
||||||
@@ -146,18 +80,13 @@ Quick3DNodeInstance::Pointer Quick3DNodeInstance::create(QObject *object)
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quick3DNodeInstance::setHideInEditor(bool b)
|
void Quick3DNodeInstance::setHiddenInEditor(bool b)
|
||||||
{
|
{
|
||||||
|
ObjectNodeInstance::setHiddenInEditor(b);
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
QQuick3DNodePrivate *privateNode = QQuick3DNodePrivate::get(quick3DNode());
|
QQuick3DNodePrivate *privateNode = QQuick3DNodePrivate::get(quick3DNode());
|
||||||
if (privateNode) {
|
if (privateNode)
|
||||||
privateNode->setIsHiddenInEditor(b);
|
privateNode->setIsHiddenInEditor(b);
|
||||||
|
|
||||||
// Hidden objects should not be pickable
|
|
||||||
setPickable(!b, true, true);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
Q_UNUSED(b)
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
~Quick3DNodeInstance() override;
|
~Quick3DNodeInstance() override;
|
||||||
static Pointer create(QObject *objectToBeWrapped);
|
static Pointer create(QObject *objectToBeWrapped);
|
||||||
void setHideInEditor(bool b) override;
|
void setHiddenInEditor(bool b) override;
|
||||||
void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
||||||
InstanceContainer::NodeFlags flags) override;
|
InstanceContainer::NodeFlags flags) override;
|
||||||
|
|
||||||
@@ -53,7 +53,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
|
Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
|
||||||
QQuick3DNode *quick3DNode() const;
|
QQuick3DNode *quick3DNode() const;
|
||||||
void setPickable(bool enable, bool checkParent, bool applyToChildInstances);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -270,6 +270,9 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
|
|||||||
|
|
||||||
instance.internalInstance()->initialize(instance.m_nodeInstance, instanceContainer.metaFlags());
|
instance.internalInstance()->initialize(instance.m_nodeInstance, instanceContainer.metaFlags());
|
||||||
|
|
||||||
|
// Handle hidden state to initialize pickable state
|
||||||
|
nodeInstanceServer->handleInstanceHidden(instance, false, false);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,9 +349,16 @@ void ServerNodeInstance::setPropertyBinding(const PropertyName &name, const QStr
|
|||||||
m_nodeInstance->setPropertyBinding(name, expression);
|
m_nodeInstance->setPropertyBinding(name, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerNodeInstance::setHideInEditor(bool b)
|
void ServerNodeInstance::setHiddenInEditor(bool b)
|
||||||
{
|
{
|
||||||
m_nodeInstance->setHideInEditor(b);
|
m_nodeInstance->setHiddenInEditor(b);
|
||||||
|
m_nodeInstance->nodeInstanceServer()->handleInstanceHidden(*this, b, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerNodeInstance::setLockedInEditor(bool b)
|
||||||
|
{
|
||||||
|
m_nodeInstance->setLockedInEditor(b);
|
||||||
|
m_nodeInstance->nodeInstanceServer()->handleInstanceLocked(*this, b, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerNodeInstance::resetProperty(const PropertyName &name)
|
void ServerNodeInstance::resetProperty(const PropertyName &name)
|
||||||
|
|||||||
@@ -185,7 +185,8 @@ private: // functions
|
|||||||
|
|
||||||
void setPropertyBinding(const PropertyName &name, const QString &expression);
|
void setPropertyBinding(const PropertyName &name, const QString &expression);
|
||||||
|
|
||||||
void setHideInEditor(bool b);
|
void setHiddenInEditor(bool b);
|
||||||
|
void setLockedInEditor(bool b);
|
||||||
|
|
||||||
void resetProperty(const PropertyName &name);
|
void resetProperty(const PropertyName &name);
|
||||||
void refreshProperty(const PropertyName &name);
|
void refreshProperty(const PropertyName &name);
|
||||||
|
|||||||
@@ -102,15 +102,22 @@ void Edit3DCanvas::resizeEvent(QResizeEvent *e)
|
|||||||
|
|
||||||
void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
|
void Edit3DCanvas::dragEnterEvent(QDragEnterEvent *e)
|
||||||
{
|
{
|
||||||
|
// Block all drags if scene root node is locked
|
||||||
|
ModelNode node;
|
||||||
|
if (m_parent->view()->hasModelNodeForInternalId(m_activeScene))
|
||||||
|
node = m_parent->view()->modelNodeForInternalId(m_activeScene);
|
||||||
|
|
||||||
|
// Allow drop when there is no valid active scene, as the drop goes under the root node of
|
||||||
|
// the document in that case.
|
||||||
|
if (!node.isValid() || !ModelNode::isThisOrAncestorLocked(node)) {
|
||||||
QByteArray data = e->mimeData()->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
QByteArray data = e->mimeData()->data(QStringLiteral("application/vnd.bauhaus.itemlibraryinfo"));
|
||||||
if (!data.isEmpty()) {
|
if (!data.isEmpty()) {
|
||||||
QDataStream stream(data);
|
QDataStream stream(data);
|
||||||
stream >> m_itemLibraryEntry;
|
stream >> m_itemLibraryEntry;
|
||||||
bool canDrop = NodeHints::fromItemLibraryEntry(m_itemLibraryEntry).canBeDroppedInView3D();
|
if (NodeHints::fromItemLibraryEntry(m_itemLibraryEntry).canBeDroppedInView3D())
|
||||||
|
|
||||||
if (canDrop)
|
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Edit3DCanvas::dropEvent(QDropEvent *e)
|
void Edit3DCanvas::dropEvent(QDropEvent *e)
|
||||||
|
|||||||
Reference in New Issue
Block a user