From 671c2d3dd9b31cc3e62346857f5c22709a5c2fba Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 26 Mar 2019 13:21:30 +0200 Subject: Fix master slide item grouping issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disallow grouping mixed non-master and master items. If master items are grouped, the resulting group is a master group. Disallow dragging master items under non-master items in some edge cases that still allowed it. Change-Id: Id4e18405526fb5b0f9ed17bc29e758101a19875e Fixes: QT3DS-3224 Reviewed-by: Mahmoud Badri Reviewed-by: Tomi Korpipää --- .../Client/Code/Core/Doc/DocumentEditor.cpp | 24 +++++++++++++--------- src/Authoring/Studio/Application/StudioApp.cpp | 13 +++++++++--- .../Bindings/Qt3DSDMTimelineItemBinding.cpp | 6 ++++++ .../Timeline/Bindings/Qt3DSDMTimelineItemBinding.h | 3 +++ .../Palettes/TimelineGraphicsView/RowMover.cpp | 19 ++++++++++------- .../Palettes/TimelineGraphicsView/ui/RowTree.cpp | 8 ++++++++ .../Palettes/TimelineGraphicsView/ui/RowTree.h | 1 + 7 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp index e8883a86..4606e146 100644 --- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp +++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp @@ -3268,16 +3268,20 @@ public: // Creates a new group object and moves the specified objects as its children void groupObjects(const TInstanceHandleList &inInstances) override { - TInstanceHandleList sortedList(ToGraphOrdering(inInstances)); - - // Create a new group next to the topmost item in the graph - TInstanceHandle sibling = sortedList.front(); - Qt3DSDMSlideHandle slide = GetActiveSlide(sibling); - TInstanceHandle group = CreateSceneGraphInstance(ComposerObjectTypes::Group, sibling, slide, - DocumentEditorInsertType::PreviousSibling, - CPt(), PRIMITIVETYPE_UNKNOWN, -1); - // Move items into the group - RearrangeObjects(sortedList, group, DocumentEditorInsertType::LastChild, true); + if (inInstances.size() > 0) { + TInstanceHandleList sortedList(ToGraphOrdering(inInstances)); + // Create a new group next to the topmost item in the graph + TInstanceHandle sibling = sortedList.front(); + Qt3DSDMSlideHandle slide = GetActiveSlide(sibling); + if (m_Bridge.IsMaster(sibling)) + slide = m_SlideSystem.GetMasterSlide(slide); + TInstanceHandle group = CreateSceneGraphInstance( + ComposerObjectTypes::Group, sibling, slide, + DocumentEditorInsertType::PreviousSibling, CPt(), + PRIMITIVETYPE_UNKNOWN, -1); + // Move items into the group + RearrangeObjects(sortedList, group, DocumentEditorInsertType::LastChild, true); + } } Qt3DSDMInstanceHandle MakeComponent(const qt3dsdm::TInstanceHandleList &inInstances) override diff --git a/src/Authoring/Studio/Application/StudioApp.cpp b/src/Authoring/Studio/Application/StudioApp.cpp index 5dc9fbe5..789dd4ba 100644 --- a/src/Authoring/Studio/Application/StudioApp.cpp +++ b/src/Authoring/Studio/Application/StudioApp.cpp @@ -1053,8 +1053,8 @@ bool CStudioApp::canGroupSelectedObjects() const // cannot be multiselected, we treat it as ungroupable. qt3dsdm::Qt3DSDMInstanceHandle first = selected[0]; if (first.Valid()) { - EStudioObjectType type = m_core->GetDoc()->GetStudioSystem()->GetClientDataModelBridge() - ->GetObjectType(first); + auto bridge = m_core->GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); + EStudioObjectType type = bridge->GetObjectType(first); const int ungroupableTypes = OBJTYPE_SCENE | OBJTYPE_LAYER | OBJTYPE_MATERIAL | OBJTYPE_CUSTOMMATERIAL | OBJTYPE_REFERENCEDMATERIAL | OBJTYPE_BEHAVIOR @@ -1065,10 +1065,17 @@ bool CStudioApp::canGroupSelectedObjects() const if (type == OBJTYPE_COMPONENT) { // Components can't be grouped if they are the root of currently active time context - auto bridge = m_core->GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); if (bridge->IsActiveComponent(first)) return false; } + + // All items must either be on master slide or not be on master slide + bool isMaster = bridge->IsMaster(first); + for (size_t i = 1, end = selected.size(); i < end; ++i) { + if (isMaster != bridge->IsMaster(selected[i])) + return false; + } + return true; } } diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp index 47df8a27..0297e17e 100644 --- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp +++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp @@ -857,6 +857,12 @@ Qt3DSDMTimelineItemBinding::GetPropertyBinding(Qt3DSDMPropertyHandle inPropertyH return nullptr; } +bool Qt3DSDMTimelineItemBinding::isRootComponent() const +{ + auto bridge = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetClientDataModelBridge(); + return bridge->IsActiveComponent(m_DataHandle); +} + ITimelineItemProperty * Qt3DSDMTimelineItemBinding::GetOrCreatePropertyBinding(Qt3DSDMPropertyHandle inPropertyHandle) { diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h index 5ababf96..f8b5f0de 100644 --- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h +++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.h @@ -183,6 +183,9 @@ public: ITimelineItemProperty *GetOrCreatePropertyBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle); ITimelineItemProperty *GetPropertyBinding(qt3dsdm::Qt3DSDMPropertyHandle inPropertyHandle); + + bool isRootComponent() const; + protected: virtual ITimelineTimebar *CreateTimelineTimebar(); void RemoveAllPropertyBindings(); diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp index 3e35a361..437d81dc 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/RowMover.cpp @@ -310,15 +310,20 @@ void RowMover::updateTargetRow(const QPointF &scenePos, EStudioObjectType rowTyp bool srcHasMaster = sourceRowsHasMaster(); if (!rowInsert1->locked() && rowInsert1->isContainer() && !m_sourceRows.contains(rowInsert1) // prevent insertion a master row under a non-master unless under a component root - && (!(srcHasMaster && !rowInsert1->isMaster()) || rowInsert1->isComponent())) { + && (!(srcHasMaster && !rowInsert1->isMaster()) || rowInsert1->isComponentRoot())) { depthMax++; // Container: allow insertion as a child - } else if (rowInsert1->isPropertyOrMaterial() && !rowInsert1->parentRow()->isContainer()) { - depthMax--; // non-container with properties and/or a material - } else if (srcHasMaster) { + } else { RowTree *row = rowInsert1->parentRow(); - while (row && !row->isMaster() && !row->isComponent()) { - depthMax--; - row = row->parentRow(); + if (rowInsert1->isPropertyOrMaterial() && !rowInsert1->parentRow()->isContainer()) { + depthMax--; // non-container with properties and/or a material + if (row) + row = row->parentRow(); + } + if (srcHasMaster) { + while (row && !row->isMaster() && !row->isComponent()) { + depthMax--; + row = row->parentRow(); + } } } diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp index c4a2392f..8445278c 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.cpp @@ -1138,6 +1138,14 @@ bool RowTree::isComponent() const return m_rowType == OBJTYPE_COMPONENT; } +bool RowTree::isComponentRoot() const +{ + if (m_rowType == OBJTYPE_COMPONENT && m_binding) + return static_cast(m_binding)->isRootComponent(); + + return false; +} + bool RowTree::isMaster() const { return m_master; diff --git a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h index 249a3271..f6c54b56 100644 --- a/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h +++ b/src/Authoring/Studio/Palettes/TimelineGraphicsView/ui/RowTree.h @@ -112,6 +112,7 @@ public: bool isProperty() const; bool isPropertyOrMaterial() const; bool isComponent() const; + bool isComponentRoot() const; bool isMaster() const; bool hasPropertyChildren() const; bool empty() const; // has zero child rows (and zero properties) -- cgit v1.2.3