forked from qt-creator/qt-creator
QmlDesigner: Add delete action to 3D Editor's context menu
This entails selecting a model upon right-clicking if it is not selected. Also fixed a memory leak and small tweaks. Fixes: QDS-7401 Change-Id: I592acb3fff30ecc3236f3cf2fbe126de4fb389dc Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -363,7 +363,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function handleObjectClicked(object, multi)
|
||||
function handleObjectClicked(object, button, multi)
|
||||
{
|
||||
if (object instanceof View3D) {
|
||||
// View3D can be the resolved pick target in case the 3D editor is showing content
|
||||
@@ -393,7 +393,14 @@ Item {
|
||||
// Null object always clears entire selection
|
||||
var newSelection = [];
|
||||
if (clickedObject) {
|
||||
if (multi && selectedNodes.length > 0) {
|
||||
if (button === Qt.RightButton) {
|
||||
// Right-clicking does only single selection (when clickedObject is unselected)
|
||||
// This is needed for selecting a target for the context menu
|
||||
if (!selectedNodes.includes(clickedObject))
|
||||
newSelection[0] = clickedObject;
|
||||
else
|
||||
newSelection = selectedNodes;
|
||||
} else if (multi && selectedNodes.length > 0) {
|
||||
var deselect = false;
|
||||
for (var i = 0; i < selectedNodes.length; ++i) {
|
||||
// Multiselecting already selected object clears that object from selection
|
||||
@@ -697,10 +704,10 @@ Item {
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
|
||||
onPropertyValueCommit: (propName)=> {
|
||||
onPropertyValueCommit: (propName) => {
|
||||
viewRoot.commitObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
onPropertyValueChange: (propName)=> {
|
||||
onPropertyValueChange: (propName) => {
|
||||
viewRoot.changeObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
}
|
||||
@@ -772,17 +779,17 @@ Item {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
hoverEnabled: false
|
||||
|
||||
property MouseArea3D freeDraggerArea
|
||||
property point pressPoint
|
||||
property bool initialMoveBlock: false
|
||||
|
||||
onPressed: (mouse)=> {
|
||||
onPressed: (mouse) => {
|
||||
if (viewRoot.editView) {
|
||||
var pickResult = viewRoot.editView.pick(mouse.x, mouse.y);
|
||||
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
|
||||
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit), mouse.button,
|
||||
mouse.modifiers & Qt.ControlModifier);
|
||||
|
||||
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
|
||||
@@ -800,7 +807,7 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
onPositionChanged: (mouse)=> {
|
||||
onPositionChanged: (mouse) => {
|
||||
if (freeDraggerArea) {
|
||||
if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) {
|
||||
// Don't force press event at actual press, as that puts the gizmo
|
||||
@@ -825,10 +832,10 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: (mouse)=> {
|
||||
onReleased: (mouse) => {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
onCanceled: (mouse)=> {
|
||||
onCanceled: (mouse) => {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
}
|
||||
|
@@ -363,7 +363,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
function handleObjectClicked(object, multi)
|
||||
function handleObjectClicked(object, button, multi)
|
||||
{
|
||||
if (object instanceof View3D) {
|
||||
// View3D can be the resolved pick target in case the 3D editor is showing content
|
||||
@@ -393,7 +393,14 @@ Item {
|
||||
// Null object always clears entire selection
|
||||
var newSelection = [];
|
||||
if (clickedObject) {
|
||||
if (multi && selectedNodes.length > 0) {
|
||||
if (button === Qt.RightButton) {
|
||||
// Right-clicking does only single selection (when clickedObject is unselected)
|
||||
// This is needed for selecting a target for the context menu
|
||||
if (!selectedNodes.includes(clickedObject))
|
||||
newSelection[0] = clickedObject;
|
||||
else
|
||||
newSelection = selectedNodes;
|
||||
} else if (multi && selectedNodes.length > 0) {
|
||||
var deselect = false;
|
||||
for (var i = 0; i < selectedNodes.length; ++i) {
|
||||
// Multiselecting already selected object clears that object from selection
|
||||
@@ -841,10 +848,10 @@ Item {
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
|
||||
onPropertyValueCommit: (propName)=> {
|
||||
onPropertyValueCommit: (propName) => {
|
||||
viewRoot.commitObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
onPropertyValueChange: (propName)=> {
|
||||
onPropertyValueChange: (propName) => {
|
||||
viewRoot.changeObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
}
|
||||
@@ -917,14 +924,14 @@ Item {
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
hoverEnabled: false
|
||||
|
||||
property MouseArea3D freeDraggerArea
|
||||
property point pressPoint
|
||||
property bool initialMoveBlock: false
|
||||
|
||||
onPressed: (mouse)=> {
|
||||
onPressed: (mouse) => {
|
||||
if (viewRoot.editView) {
|
||||
// First pick overlay to check for hits there
|
||||
var pickResult = _generalHelper.pickViewAt(overlayView, mouse.x, mouse.y);
|
||||
@@ -935,7 +942,7 @@ Item {
|
||||
resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
|
||||
}
|
||||
|
||||
handleObjectClicked(resolvedResult, mouse.modifiers & Qt.ControlModifier);
|
||||
handleObjectClicked(resolvedResult, mouse.button, mouse.modifiers & Qt.ControlModifier);
|
||||
|
||||
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
|
||||
if (transformMode === EditView3D.TransformMode.Move)
|
||||
@@ -952,7 +959,7 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
onPositionChanged: (mouse)=> {
|
||||
onPositionChanged: (mouse) => {
|
||||
if (freeDraggerArea) {
|
||||
if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) {
|
||||
// Don't force press event at actual press, as that puts the gizmo
|
||||
@@ -977,10 +984,10 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: (mouse)=> {
|
||||
onReleased: (mouse) => {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
onCanceled: (mouse)=> {
|
||||
onCanceled: (mouse) => {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
}
|
||||
|
@@ -285,12 +285,12 @@ void Qt5InformationNodeInstanceServer::handleInputEvents()
|
||||
continue;
|
||||
}
|
||||
}
|
||||
auto me = new QMouseEvent(command.type(), command.pos(), command.button(),
|
||||
command.buttons(), command.modifiers());
|
||||
QMouseEvent me(command.type(), command.pos(), command.button(), command.buttons(),
|
||||
command.modifiers());
|
||||
// We must use sendEvent in Qt 6, as using postEvent allows the associated position
|
||||
// data stored internally in QMutableEventPoint to potentially be updated by system
|
||||
// before the event is delivered.
|
||||
QGuiApplication::sendEvent(m_editView3DData.window, me);
|
||||
QGuiApplication::sendEvent(m_editView3DData.window, &me);
|
||||
|
||||
// Context menu requested
|
||||
if (command.button() == Qt::RightButton && command.modifiers() == Qt::NoModifier)
|
||||
@@ -428,7 +428,8 @@ void Qt5InformationNodeInstanceServer::getModelAtPos(const QPointF &pos)
|
||||
|
||||
QVariant instance = resolvedPick ? instanceForObject(resolvedPick).instanceId() : -1;
|
||||
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::ModelAtPos, instance});
|
||||
return;
|
||||
#else
|
||||
Q_UNUSED(pos)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -249,6 +249,10 @@ void Edit3DView::customNotification(const AbstractView *view, const QString &ide
|
||||
void Edit3DView::modelAtPosReady(const ModelNode &modelNode)
|
||||
{
|
||||
if (m_modelAtPosReqType == ModelAtPosReqType::ContextMenu) {
|
||||
// Make sure right-clicked item is selected. Due to a bug in puppet side right-clicking an item
|
||||
// while the context-menu is shown doesn't select the item.
|
||||
if (modelNode.isValid() && !modelNode.isSelected())
|
||||
setSelectedModelNode(modelNode);
|
||||
m_edit3DWidget->showContextMenu(m_contextMenuPos, modelNode);
|
||||
} else if (m_modelAtPosReqType == ModelAtPosReqType::MaterialDrop) {
|
||||
if (m_droppedMaterial.isValid() && modelNode.isValid()) {
|
||||
|
@@ -185,7 +185,12 @@ void Edit3DWidget::createContextMenu()
|
||||
ModelNodeOperations::editMaterial(selCtx);
|
||||
});
|
||||
|
||||
// TODO: add more actions: delete, create, etc
|
||||
m_deleteAction = m_contextMenu->addAction(tr("Delete"), [&] {
|
||||
view()->executeInTransaction("Edit3DWidget::createContextMenu", [&] {
|
||||
for (ModelNode &node : m_view->selectedModelNodes())
|
||||
node.destroy();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
|
||||
@@ -241,6 +246,7 @@ void Edit3DWidget::showContextMenu(const QPoint &pos, const ModelNode &modelNode
|
||||
m_contextMenuTarget = modelNode;
|
||||
|
||||
m_editMaterialAction->setEnabled(modelNode.isValid());
|
||||
m_deleteAction->setEnabled(modelNode.isValid());
|
||||
|
||||
m_contextMenu->popup(mapToGlobal(pos));
|
||||
}
|
||||
|
@@ -76,6 +76,7 @@ private:
|
||||
QPointer<QMenu> m_backgroundColorMenu;
|
||||
QPointer<QMenu> m_contextMenu;
|
||||
QPointer<QAction> m_editMaterialAction;
|
||||
QPointer<QAction> m_deleteAction;
|
||||
ModelNode m_contextMenuTarget;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user