diff --git a/application/sources/part_manage_widget.cc b/application/sources/part_manage_widget.cc index 22ebf002..b827b5be 100644 --- a/application/sources/part_manage_widget.cc +++ b/application/sources/part_manage_widget.cc @@ -12,6 +12,8 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent): QWidget(parent), m_document(document) { + setContextMenuPolicy(Qt::CustomContextMenu); + QHBoxLayout *toolsLayout = new QHBoxLayout; toolsLayout->setSpacing(0); toolsLayout->setMargin(0); @@ -111,6 +113,11 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent): connect(m_document, &Document::partDisableStateChanged, this, &PartManageWidget::updateToolButtons); connect(m_document, &Document::componentChildrenChanged, this, &PartManageWidget::updateToolButtons); + connect(this, &PartManageWidget::groupComponents, m_document, &Document::createNewComponentAndMoveTheseIn); + connect(this, &PartManageWidget::groupOperationAdded, m_document, &Document::saveSnapshot); + + connect(this, &PartManageWidget::customContextMenuRequested, this, &PartManageWidget::showContextMenu); + QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(toolsLayout); mainLayout->addWidget(m_componentPreviewGridWidget); @@ -217,3 +224,23 @@ void PartManageWidget::updateToolButtons() m_linkButton->setEnabled(enableLinkButton); m_propertyButton->setEnabled(enablePropertyButton); } + +void PartManageWidget::showContextMenu(const QPoint &pos) +{ + auto selectedComponentIds = m_componentPreviewGridWidget->getSelectedComponentIds(); + if (selectedComponentIds.empty()) + return; + + QMenu contextMenu(this); + + QAction makeGroupAction(tr("Make group"), this); + makeGroupAction.setIcon(Theme::awesome()->icon(fa::folder)); + connect(&makeGroupAction, &QAction::triggered, this, [=]() { + emit this->groupComponents(selectedComponentIds); + emit this->groupOperationAdded(); + }); + + contextMenu.addAction(&makeGroupAction); + + contextMenu.exec(mapToGlobal(pos)); +} diff --git a/application/sources/part_manage_widget.h b/application/sources/part_manage_widget.h index 073f9d2a..e5d1f465 100644 --- a/application/sources/part_manage_widget.h +++ b/application/sources/part_manage_widget.h @@ -15,9 +15,12 @@ class PartManageWidget: public QWidget signals: void unselectAllOnCanvas(); void selectPartOnCanvas(const dust3d::Uuid &partId); + void groupComponents(const std::vector &componentIds); + void groupOperationAdded(); public slots: void selectComponentByPartId(const dust3d::Uuid &partId); void showSelectedComponentProperties(); + void showContextMenu(const QPoint &pos); public: PartManageWidget(Document *document, QWidget *parent=nullptr); private: diff --git a/application/sources/skeleton_document.cc b/application/sources/skeleton_document.cc index c60f7b7f..94b68f78 100644 --- a/application/sources/skeleton_document.cc +++ b/application/sources/skeleton_document.cc @@ -520,29 +520,41 @@ void SkeletonDocument::setComponentExpandState(dust3d::Uuid componentId, bool ex emit optionsChanged(); } -void SkeletonDocument::createNewComponentAndMoveThisIn(dust3d::Uuid componentId) +void SkeletonDocument::createNewComponentAndMoveTheseIn(const std::vector &componentIds) { - auto component = componentMap.find(componentId); - if (component == componentMap.end()) { + if (componentIds.empty()) return; - } - - SkeletonComponent *oldParent = (SkeletonComponent *)findComponentParent(componentId); - + + dust3d::Uuid newParentId; + SkeletonComponent newParent(dust3d::Uuid::createUuid()); + newParentId = newParent.id; + + auto it = componentIds.begin(); + + SkeletonComponent *oldParent = (SkeletonComponent *)findComponentParent(*it); + auto oldParentId = oldParent->id; + oldParent->replaceChild(*it, newParentId); + for (++it; it != componentIds.end(); ++it) { + oldParent->removeChild(*it); + } + + for (const auto &componentId: componentIds) { + auto component = componentMap.find(componentId); + if (component == componentMap.end()) { + continue; + } + component->second.parentId = newParentId; + newParent.addChild(componentId); + } + + newParent.parentId = oldParentId; newParent.name = tr("Group") + " " + QString::number(componentMap.size() - partMap.size() + 1); - - oldParent->replaceChild(componentId, newParent.id); - newParent.parentId = oldParent->id; - newParent.addChild(componentId); - auto newParentId = newParent.id; componentMap.emplace(newParentId, std::move(newParent)); - - component->second.parentId = newParentId; - - emit componentChildrenChanged(oldParent->id); + + emit componentChildrenChanged(oldParentId); emit componentAdded(newParentId); - emit optionsChanged(); + emit skeletonChanged(); } void SkeletonDocument::createNewChildComponent(dust3d::Uuid parentComponentId) diff --git a/application/sources/skeleton_document.h b/application/sources/skeleton_document.h index 98f086cf..6bfed1fb 100644 --- a/application/sources/skeleton_document.h +++ b/application/sources/skeleton_document.h @@ -678,7 +678,7 @@ public slots: void addComponent(dust3d::Uuid parentId); void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId); void setCurrentCanvasComponentId(dust3d::Uuid componentId); - void createNewComponentAndMoveThisIn(dust3d::Uuid componentId); + void createNewComponentAndMoveTheseIn(const std::vector &componentIds); void createNewChildComponent(dust3d::Uuid parentComponentId); void setComponentExpandState(dust3d::Uuid componentId, bool expanded); void hideOtherComponents(dust3d::Uuid componentId);