From 9a3e96a6a90400c39bcc11c0f6e7e1e9ffed8616 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 20 Jun 2016 14:05:23 +0300 Subject: Properly update group selection box in various undo/redo situations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1e950465c4e0fb0e2dd79d6eed5047266fd525d2 Reviewed-by: Tomi Korpipää --- editorlib/src/editorscene.cpp | 27 ++++++++++++++++++++-- editorlib/src/editorscene.h | 5 +++- editorlib/src/editorsceneitem.cpp | 22 ++++++++++-------- editorlib/src/editorsceneitem.h | 2 +- editorlib/src/editorsceneitemmodel.cpp | 5 +++- .../src/undohandler/propertychangecommand.cpp | 2 ++ .../src/undohandler/replacecomponentcommand.cpp | 1 + editorlib/src/undohandler/resetentitycommand.cpp | 9 ++++++-- .../src/undohandler/resettransformcommand.cpp | 2 ++ 9 files changed, 58 insertions(+), 17 deletions(-) diff --git a/editorlib/src/editorscene.cpp b/editorlib/src/editorscene.cpp index c01e590..6bf2a48 100644 --- a/editorlib/src/editorscene.cpp +++ b/editorlib/src/editorscene.cpp @@ -127,6 +127,7 @@ EditorScene::EditorScene(QObject *parent) , m_previousDuplicate(nullptr) , m_ctrlDownOnLastLeftPress(false) , m_clipboardOperation(ClipboardNone) + , m_groupBoxUpdatePending(false) { setLanguage(language()); retranslateUi(); @@ -241,7 +242,9 @@ void EditorScene::removeEntity(Qt3DCore::QEntity *entity) m_sceneItems.remove(entity->id()); if (m_selectedEntity == entity || multiSelection()) - ensureSelection(); + queueEnsureSelection(); + + queueUpdateGroupSelectionBoxes(); delete item; delete entity; @@ -809,7 +812,7 @@ void EditorScene::showDebugHandle(bool show, int handleIndex, const QVector3D &w show, handleIndex, 0); } -void EditorScene::ensureSelection() +void EditorScene::queueEnsureSelection() { // Ensure that something is selected after the current pending events have executed if (m_sceneEntity && m_ensureSelectionEntityName.isEmpty()) { @@ -860,6 +863,26 @@ void EditorScene::doEnsureSelection() m_ensureSelectionEntityName.clear(); } +void EditorScene::queueUpdateGroupSelectionBoxes() +{ + // Queue asynchronous update to group selection boxes + if (!m_groupBoxUpdatePending) { + m_groupBoxUpdatePending = true; + QMetaObject::invokeMethod(this, "doUpdateGroupSelectionBoxes", Qt::QueuedConnection); + } +} + +void EditorScene::doUpdateGroupSelectionBoxes() +{ + const QList items = m_sceneItems.values(); + for (int i = 0; i < items.size(); ++i) { + EditorSceneItem *item = items.at(i); + if (item && item->itemType() == EditorSceneItem::Group && item->isSelectionBoxShowing()) + item->updateGroupExtents(); + } + m_groupBoxUpdatePending = false; +} + EditorSceneItem *EditorScene::itemByName(const QString &name) { const QList items = m_sceneItems.values(); diff --git a/editorlib/src/editorscene.h b/editorlib/src/editorscene.h index 88ea589..728dbb1 100644 --- a/editorlib/src/editorscene.h +++ b/editorlib/src/editorscene.h @@ -310,7 +310,8 @@ public: Qt3DRender::QObjectPicker *createObjectPickerForEntity(Qt3DCore::QEntity *entity); void showDebugHandle(bool show, int handleIndex = 0, const QVector3D &worldPosition = QVector3D()); - void ensureSelection(); + void queueEnsureSelection(); + void queueUpdateGroupSelectionBoxes(); public slots: void clearSelectionBoxes(Qt3DCore::QEntity *skipEntity = nullptr); @@ -389,6 +390,7 @@ private: Q_INVOKABLE void doEnsureSelection(); EditorSceneItem *itemByName(const QString &name); void clearSingleSelection(); + Q_INVOKABLE void doUpdateGroupSelectionBoxes(); private: Qt3DCore::QEntity *m_rootEntity; @@ -479,6 +481,7 @@ private: ClipboardOperation m_clipboardOperation; QMap m_placeholderEntityMap; + bool m_groupBoxUpdatePending; }; #endif // EDITORSCENE_H diff --git a/editorlib/src/editorsceneitem.cpp b/editorlib/src/editorsceneitem.cpp index fc018d3..ec2aea5 100644 --- a/editorlib/src/editorsceneitem.cpp +++ b/editorlib/src/editorsceneitem.cpp @@ -487,20 +487,22 @@ void EditorSceneItem::doUpdateSelectionBoxTransform() void EditorSceneItem::findTotalExtents(QVector3D &min, QVector3D &max, const QMatrix4x4 &matrix) { - doUpdateSelectionBoxTransform(); - QMatrix4x4 newMatrix = matrix; + doUpdateSelectionBoxTransform(); if (m_entityTransform) newMatrix *= m_entityTransform->matrix(); - QVector corners = getSelectionBoxCorners(newMatrix); - Q_FOREACH (QVector3D corner, corners) { - min.setX(qMin(corner.x(), min.x())); - min.setY(qMin(corner.y(), min.y())); - min.setZ(qMin(corner.z(), min.z())); - max.setX(qMax(corner.x(), max.x())); - max.setY(qMax(corner.y(), max.y())); - max.setZ(qMax(corner.z(), max.z())); + // Skip groups when finding total extents + if (m_itemType != EditorSceneItem::Group) { + QVector corners = getSelectionBoxCorners(newMatrix); + Q_FOREACH (QVector3D corner, corners) { + min.setX(qMin(corner.x(), min.x())); + min.setY(qMin(corner.y(), min.y())); + min.setZ(qMin(corner.z(), min.z())); + max.setX(qMax(corner.x(), max.x())); + max.setY(qMax(corner.y(), max.y())); + max.setZ(qMax(corner.z(), max.z())); + } } Q_FOREACH (EditorSceneItem *child, childItems()) diff --git a/editorlib/src/editorsceneitem.h b/editorlib/src/editorsceneitem.h index ecb9d17..a588152 100644 --- a/editorlib/src/editorsceneitem.h +++ b/editorlib/src/editorsceneitem.h @@ -106,6 +106,7 @@ public: QList *internalPickers(); void recalculateSubMeshesExtents(); void doUpdateSelectionBoxTransform(); + void updateGroupExtents(); public slots: void updateSelectionBoxTransform(); @@ -125,7 +126,6 @@ private: QVector3D &meshCenter); void populateSubMeshData(Qt3DCore::QEntity *entity, QVector &subMeshPoints); void updateChildLightTransforms(); - void updateGroupExtents(); void findTotalExtents(QVector3D &min, QVector3D &max, const QMatrix4x4 &matrix); QVector getSelectionBoxCorners(const QMatrix4x4 &matrix); diff --git a/editorlib/src/editorsceneitemmodel.cpp b/editorlib/src/editorsceneitemmodel.cpp index d3912b3..12b5b9b 100644 --- a/editorlib/src/editorsceneitemmodel.cpp +++ b/editorlib/src/editorsceneitemmodel.cpp @@ -260,7 +260,8 @@ QHash EditorSceneItemModel::roleNames() const void EditorSceneItemModel::resetModel() { - m_scene->ensureSelection(); + m_scene->queueEnsureSelection(); + m_scene->queueUpdateGroupSelectionBoxes(); QAbstractItemModel::beginResetModel(); @@ -316,6 +317,8 @@ Qt3DCore::QEntity *EditorSceneItemModel::insertEntity(EditorUtils::InsertableEnt m_lastInsertedIndex = createIndex(childCount - 1, 0, childItem); } + m_scene->queueUpdateGroupSelectionBoxes(); + return newEntity; } diff --git a/editorlib/src/undohandler/propertychangecommand.cpp b/editorlib/src/undohandler/propertychangecommand.cpp index 7e0c95c..982e701 100644 --- a/editorlib/src/undohandler/propertychangecommand.cpp +++ b/editorlib/src/undohandler/propertychangecommand.cpp @@ -87,6 +87,7 @@ void PropertyChangeCommand::undo() setProperty(object, m_propertyName, m_oldValue); if (!m_propertyName2.isEmpty()) setProperty(object, m_propertyName2, m_oldValue2); + m_sceneModel->scene()->queueUpdateGroupSelectionBoxes(); } void PropertyChangeCommand::redo() @@ -97,6 +98,7 @@ void PropertyChangeCommand::redo() setProperty(object, m_propertyName, m_newValue); if (!m_propertyName2.isEmpty()) setProperty(object, m_propertyName2, m_newValue2); + m_sceneModel->scene()->queueUpdateGroupSelectionBoxes(); } bool PropertyChangeCommand::mergeWith(const QUndoCommand *other) diff --git a/editorlib/src/undohandler/replacecomponentcommand.cpp b/editorlib/src/undohandler/replacecomponentcommand.cpp index 92441d4..c236836 100644 --- a/editorlib/src/undohandler/replacecomponentcommand.cpp +++ b/editorlib/src/undohandler/replacecomponentcommand.cpp @@ -76,5 +76,6 @@ void ReplaceComponentCommand::replaceAndSwap() // Grab explicit ownership of the component, otherwise QML garbage collector may clean it up QQmlEngine::setObjectOwnership(m_component2, QQmlEngine::CppOwnership); std::swap(m_component1, m_component2); + m_sceneModel->scene()->queueUpdateGroupSelectionBoxes(); } } diff --git a/editorlib/src/undohandler/resetentitycommand.cpp b/editorlib/src/undohandler/resetentitycommand.cpp index a7fb755..bb3a6c3 100644 --- a/editorlib/src/undohandler/resetentitycommand.cpp +++ b/editorlib/src/undohandler/resetentitycommand.cpp @@ -55,12 +55,15 @@ void ResetEntityCommand::undo() if (m_removedEntity) { // Remove the new entity with default values QModelIndex index = m_sceneModel->getModelIndexByName(m_entityName); + EditorSceneItem *item = m_sceneModel->editorSceneItemFromIndex(index); + bool reselect = item->entity() == m_sceneModel->scene()->selection(); m_sceneModel->removeEntity(index); // Insert the old entity back QModelIndex parentIndex = m_sceneModel->getModelIndexByName(m_parentEntityName); m_sceneModel->insertExistingEntity(m_removedEntity, m_row, parentIndex); - m_sceneModel->scene()->setSelection(m_removedEntity); + if (reselect) + m_sceneModel->scene()->setSelection(m_removedEntity); m_removedEntity = nullptr; } } @@ -73,6 +76,7 @@ void ResetEntityCommand::redo() m_row = index.row(); EditorSceneItem *item = m_sceneModel->editorSceneItemFromIndex(index); m_type = EditorUtils::insertableEntityType(item->entity()); + bool reselect = item->entity() == m_sceneModel->scene()->selection(); // Insert a new entity with default values Qt3DCore::QEntity *entity = m_sceneModel->createEntity(m_type, QVector3D(), parentIndex); @@ -94,5 +98,6 @@ void ResetEntityCommand::redo() break; } } - m_sceneModel->scene()->setSelection(entity); + if (reselect) + m_sceneModel->scene()->setSelection(entity); } diff --git a/editorlib/src/undohandler/resettransformcommand.cpp b/editorlib/src/undohandler/resettransformcommand.cpp index e4b3aa7..f7f7eb1 100644 --- a/editorlib/src/undohandler/resettransformcommand.cpp +++ b/editorlib/src/undohandler/resettransformcommand.cpp @@ -55,6 +55,7 @@ void ResetTransformCommand::undo() EditorSceneItem *item = m_sceneModel->editorSceneItemFromIndex(index); Qt3DCore::QTransform *transform = EditorUtils::entityTransform(item->entity()); transform->setMatrix(m_transformMatrix); + m_sceneModel->scene()->queueUpdateGroupSelectionBoxes(); } void ResetTransformCommand::redo() @@ -64,4 +65,5 @@ void ResetTransformCommand::redo() Qt3DCore::QTransform *transform = EditorUtils::entityTransform(item->entity()); m_transformMatrix = transform->matrix(); transform->setMatrix(QMatrix4x4()); + m_sceneModel->scene()->queueUpdateGroupSelectionBoxes(); } -- cgit v1.2.3