diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 52179dae..08db948a 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -184,9 +184,14 @@ void MeshGenerator::process() std::map partMeshMap; std::vector meshIds; for (const auto &partIdIt: m_snapshot->partIdList) { + const auto part = m_snapshot->parts.find(partIdIt); int bmeshId = partBmeshMap[partIdIt]; int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId, 0); - qDebug() << "m_requirePartPreviewMap.find:" << partIdIt; + if (isTrueValueString(part->second["subdived"])) { + int subdivedMeshId = meshlite_subdivide(meshliteContext, meshId); + if (subdivedMeshId > 0) + meshId = subdivedMeshId; + } if (m_requirePartPreviewMap.find(partIdIt) != m_requirePartPreviewMap.end()) { ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt]; int trimedMeshId = meshlite_trim(meshliteContext, meshId, 1); diff --git a/src/skeletondocument.cpp b/src/skeletondocument.cpp index c24d9a30..f7b72ebf 100644 --- a/src/skeletondocument.cpp +++ b/src/skeletondocument.cpp @@ -26,14 +26,6 @@ void SkeletonDocument::removePart(QUuid partId) { } -void SkeletonDocument::showPart(QUuid partId) -{ -} - -void SkeletonDocument::hidePart(QUuid partId) -{ -} - void SkeletonDocument::removeEdge(QUuid edgeId) { const SkeletonEdge *edge = findEdge(edgeId); @@ -41,6 +33,8 @@ void SkeletonDocument::removeEdge(QUuid edgeId) qDebug() << "Find edge failed:" << edgeId; return; } + if (isPartLocked(edge->partId)) + return; const SkeletonPart *oldPart = findPart(edge->partId); if (nullptr == oldPart) { qDebug() << "Find part failed:" << edge->partId; @@ -100,6 +94,8 @@ void SkeletonDocument::removeNode(QUuid nodeId) qDebug() << "Find node failed:" << nodeId; return; } + if (isPartLocked(node->partId)) + return; const SkeletonPart *oldPart = findPart(node->partId); if (nullptr == oldPart) { qDebug() << "Find part failed:" << node->partId; @@ -178,6 +174,8 @@ void SkeletonDocument::addNode(float x, float y, float z, float radius, QUuid fr return; } partId = fromNode->partId; + if (isPartLocked(partId)) + return; } SkeletonNode node; node.partId = partId; @@ -245,12 +243,18 @@ void SkeletonDocument::addEdge(QUuid fromNodeId, QUuid toNodeId) return; } + if (isPartLocked(fromNode->partId)) + return; + toNode = findNode(toNodeId); if (nullptr == toNode) { qDebug() << "Find node failed:" << toNodeId; return; } + if (isPartLocked(toNode->partId)) + return; + QUuid toPartId = toNode->partId; auto fromPart = partMap.find(fromNode->partId); @@ -335,11 +339,23 @@ void SkeletonDocument::scaleNodeByAddRadius(QUuid nodeId, float amount) qDebug() << "Find node failed:" << nodeId; return; } + if (isPartLocked(it->second.partId)) + return; it->second.radius += amount; emit nodeRadiusChanged(nodeId); emit skeletonChanged(); } +bool SkeletonDocument::isPartLocked(QUuid partId) +{ + const SkeletonPart *part = findPart(partId); + if (nullptr == part) { + qDebug() << "Find part failed:" << partId; + return true; + } + return part->locked; +} + void SkeletonDocument::moveNodeBy(QUuid nodeId, float x, float y, float z) { auto it = nodeMap.find(nodeId); @@ -347,6 +363,8 @@ void SkeletonDocument::moveNodeBy(QUuid nodeId, float x, float y, float z) qDebug() << "Find node failed:" << nodeId; return; } + if (isPartLocked(it->second.partId)) + return; it->second.x += x; it->second.y += y; it->second.z += z; @@ -361,6 +379,8 @@ void SkeletonDocument::setNodeOrigin(QUuid nodeId, float x, float y, float z) qDebug() << "Find node failed:" << nodeId; return; } + if (isPartLocked(it->second.partId)) + return; it->second.x = x; it->second.y = y; it->second.z = z; @@ -375,6 +395,8 @@ void SkeletonDocument::setNodeRadius(QUuid nodeId, float radius) qDebug() << "Find node failed:" << nodeId; return; } + if (isPartLocked(it->second.partId)) + return; it->second.radius = radius; emit nodeRadiusChanged(nodeId); emit skeletonChanged(); @@ -479,6 +501,8 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot) std::map part; part["id"] = partIt.second.id.toString(); part["visible"] = partIt.second.visible ? "true" : "false"; + part["locked"] = partIt.second.locked ? "true" : "false"; + part["subdived"] = partIt.second.subdived ? "true" : "false"; if (!partIt.second.name.isEmpty()) part["name"] = partIt.second.name; snapshot->parts[part["id"]] = part; @@ -560,6 +584,8 @@ void SkeletonDocument::fromSnapshot(const SkeletonSnapshot &snapshot) SkeletonPart part(QUuid(partKv.first)); part.name = valueOfKeyInMapOrEmpty(partKv.second, "name"); part.visible = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "visible")); + part.locked = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "locked")); + part.subdived = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "subdived")); partMap[part.id] = part; } for (const auto &partIdIt: snapshot.partIdList) { @@ -704,3 +730,45 @@ void SkeletonDocument::generateMesh() connect(thread, &QThread::finished, thread, &QThread::deleteLater); thread->start(); } + +void SkeletonDocument::setPartLockState(QUuid partId, bool locked) +{ + auto part = partMap.find(partId); + if (part == partMap.end()) { + qDebug() << "Part not found:" << partId; + return; + } + if (part->second.locked == locked) + return; + part->second.locked = locked; + emit partLockStateChanged(partId); +} + +void SkeletonDocument::setPartVisibleState(QUuid partId, bool visible) +{ + auto part = partMap.find(partId); + if (part == partMap.end()) { + qDebug() << "Part not found:" << partId; + return; + } + if (part->second.visible == visible) + return; + part->second.visible = visible; + emit partVisibleStateChanged(partId); + emit skeletonChanged(); +} + +void SkeletonDocument::setPartSubdivState(QUuid partId, bool subdived) +{ + auto part = partMap.find(partId); + if (part == partMap.end()) { + qDebug() << "Part not found:" << partId; + return; + } + if (part->second.subdived == subdived) + return; + part->second.subdived = subdived; + emit partSubdivStateChanged(partId); + emit skeletonChanged(); +} + diff --git a/src/skeletondocument.h b/src/skeletondocument.h index 5dd39399..6c4d03c4 100644 --- a/src/skeletondocument.h +++ b/src/skeletondocument.h @@ -80,11 +80,15 @@ public: QUuid id; QString name; bool visible; + bool locked; + bool subdived; QImage preview; std::vector nodeIds; bool previewIsObsolete; SkeletonPart(const QUuid &withId=QUuid()) : visible(true), + locked(false), + subdived(false), previewIsObsolete(true) { id = withId.isNull() ? QUuid::createUuid() : withId; @@ -134,6 +138,9 @@ signals: void turnaroundChanged(); void editModeChanged(); void skeletonChanged(); + void partLockStateChanged(QUuid partId); + void partVisibleStateChanged(QUuid partId); + void partSubdivStateChanged(QUuid partId); public: SkeletonDocument(); ~SkeletonDocument(); @@ -157,8 +164,6 @@ public slots: void removeNode(QUuid nodeId); void removeEdge(QUuid edgeId); void removePart(QUuid partId); - void showPart(QUuid partId); - void hidePart(QUuid partId); void addNode(float x, float y, float z, float radius, QUuid fromNodeId); void scaleNodeByAddRadius(QUuid nodeId, float amount); void moveNodeBy(QUuid nodeId, float x, float y, float z); @@ -171,10 +176,14 @@ public slots: void uiReady(); void generateMesh(); void meshReady(); + void setPartLockState(QUuid partId, bool locked); + void setPartVisibleState(QUuid partId, bool visible); + void setPartSubdivState(QUuid partId, bool subdived); private: void splitPartByNode(std::vector> *groups, QUuid nodeId); void joinNodeAndNeiborsToGroup(std::vector *group, QUuid nodeId, std::set *visitMap, QUuid noUseEdgeId=QUuid()); void splitPartByEdge(std::vector> *groups, QUuid edgeId); + bool isPartLocked(QUuid partId); private: bool m_resultMeshIsObsolete; MeshGenerator *m_meshGenerator; diff --git a/src/skeletondocumentwindow.cpp b/src/skeletondocumentwindow.cpp index bd3dffee..53f97b24 100644 --- a/src/skeletondocumentwindow.cpp +++ b/src/skeletondocumentwindow.cpp @@ -97,9 +97,9 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : containerWidget->setMinimumSize(400, 400); m_modelWidget = new ModelWidget(containerWidget); - m_modelWidget->setMinimumSize(128, 128); + m_modelWidget->setMinimumSize(256, 256); m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - m_modelWidget->move(10, 10); + m_modelWidget->move(16, 16); m_modelWidget->setGraphicsFunctions(graphicsWidget); SkeletonPartListWidget *partListWidget = new SkeletonPartListWidget(m_document); @@ -193,33 +193,13 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : connect(m_document, &SkeletonDocument::edgeRemoved, graphicsWidget, &SkeletonGraphicsWidget::edgeRemoved); connect(m_document, &SkeletonDocument::nodeRadiusChanged, graphicsWidget, &SkeletonGraphicsWidget::nodeRadiusChanged); connect(m_document, &SkeletonDocument::nodeOriginChanged, graphicsWidget, &SkeletonGraphicsWidget::nodeOriginChanged); + connect(m_document, &SkeletonDocument::partVisibleStateChanged, graphicsWidget, &SkeletonGraphicsWidget::partVisibleStateChanged); connect(m_document, &SkeletonDocument::partListChanged, partListWidget, &SkeletonPartListWidget::partListChanged); connect(m_document, &SkeletonDocument::partPreviewChanged, partListWidget, &SkeletonPartListWidget::partPreviewChanged); - - /* - connect(graphicsWidget, &SkeletonGraphicsWidget::checkEdge, edgePropertyWidget, &SkeletonEdgePropertyWidget::showProperties); - connect(graphicsWidget, &SkeletonGraphicsWidget::uncheckEdge, [=](QUuid edgeId) { - edgePropertyWidget->hide(); - }); - connect(m_document, &SkeletonDocument::edgeRemoved, [=](QUuid edgeId) { - if (edgeId == edgePropertyWidget->currentEdgeId()) { - edgePropertyWidget->hide(); - } - }); - connect(edgePropertyWidget, &SkeletonEdgePropertyWidget::setEdgeBranchMode, m_document, &SkeletonDocument::setEdgeBranchMode); - - connect(graphicsWidget, &SkeletonGraphicsWidget::checkNode, nodePropertyWidget, &SkeletonNodePropertyWidget::showProperties); - connect(graphicsWidget, &SkeletonGraphicsWidget::uncheckNode, [=](QUuid nodeId) { - nodePropertyWidget->hide(); - }); - connect(m_document, &SkeletonDocument::nodeRemoved, [=](QUuid nodeId) { - if (nodeId == nodePropertyWidget->currentNodeId()) { - nodePropertyWidget->hide(); - } - }); - connect(nodePropertyWidget, &SkeletonNodePropertyWidget::setNodeRootMarkMode, m_document, &SkeletonDocument::setNodeRootMarkMode); - */ + connect(m_document, &SkeletonDocument::partLockStateChanged, partListWidget, &SkeletonPartListWidget::partLockStateChanged); + connect(m_document, &SkeletonDocument::partVisibleStateChanged, partListWidget, &SkeletonPartListWidget::partVisibleStateChanged); + connect(m_document, &SkeletonDocument::partSubdivStateChanged, partListWidget, &SkeletonPartListWidget::partSubdivStateChanged); connect(m_document, &SkeletonDocument::skeletonChanged, m_document, &SkeletonDocument::generateMesh); diff --git a/src/skeletongraphicswidget.cpp b/src/skeletongraphicswidget.cpp index 1a27dea0..c50964c5 100644 --- a/src/skeletongraphicswidget.cpp +++ b/src/skeletongraphicswidget.cpp @@ -366,10 +366,15 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event) } QPointF mainProfile = m_cursorNodeItem->origin(); QPointF sideProfile = mainProfile; - if (mainProfile.x() >= scene()->width() / 2) { - sideProfile.setX(mainProfile.x() - scene()->width() / 4); + if (m_checkedNodeItem) { + auto itemIt = nodeItemMap.find(m_checkedNodeItem->id()); + sideProfile.setX(itemIt->second.second->origin().x()); } else { - sideProfile.setX(mainProfile.x() +scene()->width() / 4); + if (mainProfile.x() >= scene()->width() / 2) { + sideProfile.setX(mainProfile.x() - scene()->width() / 4); + } else { + sideProfile.setX(mainProfile.x() +scene()->width() / 4); + } } QPointF unifiedMainPos = scenePosToUnified(mainProfile); QPointF unifiedSidePos = scenePosToUnified(sideProfile); @@ -642,3 +647,27 @@ void SkeletonGraphicsWidget::edgeChanged(QUuid edgeId) { } +void SkeletonGraphicsWidget::partVisibleStateChanged(QUuid partId) +{ + const SkeletonPart *part = m_document->findPart(partId); + for (const auto &nodeId: part->nodeIds) { + const SkeletonNode *node = m_document->findNode(nodeId); + for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { + auto edgeItemIt = edgeItemMap.find(*edgeIt); + if (edgeItemIt == edgeItemMap.end()) { + qDebug() << "Edge item not found:" << *edgeIt; + continue; + } + edgeItemIt->second.first->setVisible(part->visible); + edgeItemIt->second.second->setVisible(part->visible); + } + auto nodeItemIt = nodeItemMap.find(nodeId); + if (nodeItemIt == nodeItemMap.end()) { + qDebug() << "Node item not found:" << nodeId; + continue; + } + nodeItemIt->second.first->setVisible(part->visible); + nodeItemIt->second.second->setVisible(part->visible); + } +} + diff --git a/src/skeletongraphicswidget.h b/src/skeletongraphicswidget.h index 62c2e99b..5977d853 100644 --- a/src/skeletongraphicswidget.h +++ b/src/skeletongraphicswidget.h @@ -264,6 +264,7 @@ public slots: void canvasResized(); void editModeChanged(); void updateCursor(); + void partVisibleStateChanged(QUuid partId); private slots: void turnaroundImageReady(); private: diff --git a/src/skeletonpartlistwidget.cpp b/src/skeletonpartlistwidget.cpp index 8f749f9b..278871a9 100644 --- a/src/skeletonpartlistwidget.cpp +++ b/src/skeletonpartlistwidget.cpp @@ -8,20 +8,17 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p m_document(document), m_partId(partId) { - m_visibleButton = new QPushButton(QChar(fa::eye)); - m_visibleButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); - m_visibleButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); - m_visibleButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize); + m_visibleButton = new QPushButton(); + updateButton(m_visibleButton, QChar(fa::eye), false); + initButton(m_visibleButton); - m_lockButton = new QPushButton(QChar(fa::unlock)); - m_lockButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); - m_lockButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); - m_lockButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize); + m_lockButton = new QPushButton(); + updateButton(m_lockButton, QChar(fa::unlock), false); + initButton(m_lockButton); - m_subdivButton = new QPushButton(QChar(fa::cube)); - m_subdivButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); - m_subdivButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); - m_subdivButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize); + m_subdivButton = new QPushButton(); + updateButton(m_subdivButton, QChar(fa::cube), false); + initButton(m_subdivButton); m_previewLabel = new QLabel; @@ -34,46 +31,141 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p miniToolLayout->addWidget(m_subdivButton); miniToolLayout->addStretch(); + QWidget *hrWidget = new QWidget; + hrWidget->setFixedHeight(1); + hrWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + hrWidget->setStyleSheet(QString("background-color: #252525;")); + hrWidget->setContentsMargins(0, 0, 0, 0); + QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->setSpacing(0); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addLayout(miniToolLayout); mainLayout->addWidget(m_previewLabel); + mainLayout->addWidget(hrWidget); setLayout(mainLayout); + + connect(this, &SkeletonPartWidget::setPartLockState, m_document, &SkeletonDocument::setPartLockState); + connect(this, &SkeletonPartWidget::setPartVisibleState, m_document, &SkeletonDocument::setPartVisibleState); + connect(this, &SkeletonPartWidget::setPartSubdivState, m_document, &SkeletonDocument::setPartSubdivState); + + connect(m_lockButton, &QPushButton::clicked, [=]() { + if (m_lockButton->text() == QChar(fa::lock)) { + emit setPartLockState(m_partId, false); + } else { + emit setPartLockState(m_partId, true); + } + }); + + connect(m_visibleButton, &QPushButton::clicked, [=]() { + if (m_visibleButton->text() == QChar(fa::eye)) { + emit setPartVisibleState(m_partId, false); + } else { + emit setPartVisibleState(m_partId, true); + } + }); + + connect(m_subdivButton, &QPushButton::clicked, [=]() { + if (m_subdivButton->text() == QChar(fa::cube)) { + emit setPartSubdivState(m_partId, true); + } else { + emit setPartSubdivState(m_partId, false); + } + }); } -QLabel *SkeletonPartWidget::previewLabel() +void SkeletonPartWidget::initButton(QPushButton *button) { - return m_previewLabel; + button->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); + button->setFixedSize(Theme::miniIconSize, Theme::miniIconSize); } -void SkeletonPartWidget::reload() +void SkeletonPartWidget::updateButton(QPushButton *button, QChar icon, bool highlighted) +{ + button->setText(icon); + if (highlighted) + button->setStyleSheet("QPushButton {border: none; background: none; color: #f7d9c8;}"); + else + button->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); +} + +void SkeletonPartWidget::updatePreview() { const SkeletonPart *part = m_document->findPart(m_partId); if (!part) { qDebug() << "Part not found:" << m_partId; return; } - //m_nameLabel->setText(part->name.isEmpty() ? part->id.toString() : part->name); m_previewLabel->setPixmap(QPixmap::fromImage(part->preview)); } +void SkeletonPartWidget::updateLockButton() +{ + const SkeletonPart *part = m_document->findPart(m_partId); + if (!part) { + qDebug() << "Part not found:" << m_partId; + return; + } + if (part->locked) + updateButton(m_lockButton, QChar(fa::lock), true); + else + updateButton(m_lockButton, QChar(fa::unlock), false); +} + +void SkeletonPartWidget::updateVisibleButton() +{ + const SkeletonPart *part = m_document->findPart(m_partId); + if (!part) { + qDebug() << "Part not found:" << m_partId; + return; + } + if (part->visible) + updateButton(m_visibleButton, QChar(fa::eye), false); + else + updateButton(m_visibleButton, QChar(fa::eyeslash), true); +} + +void SkeletonPartWidget::updateSubdivButton() +{ + const SkeletonPart *part = m_document->findPart(m_partId); + if (!part) { + qDebug() << "Part not found:" << m_partId; + return; + } + if (part->subdived) + updateButton(m_subdivButton, QChar(fa::cubes), true); + else + updateButton(m_subdivButton, QChar(fa::cube), false); +} + +void SkeletonPartWidget::reload() +{ + updatePreview(); + updateLockButton(); + updateVisibleButton(); + updateSubdivButton(); +} + SkeletonPartListWidget::SkeletonPartListWidget(const SkeletonDocument *document) : m_document(document) { setSelectionMode(QAbstractItemView::NoSelection); + setFocusPolicy(Qt::NoFocus); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setSpacing(1); + setSpacing(0); setContentsMargins(0, 0, 0, 0); } void SkeletonPartListWidget::partChanged(QUuid partId) { - auto itemIt = m_itemMap.find(partId); - if (itemIt == m_itemMap.end()) { + auto item = m_itemMap.find(partId); + if (item == m_itemMap.end()) { + qDebug() << "Part item not found:" << partId; return; } + SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); + widget->reload(); } void SkeletonPartListWidget::partListChanged() @@ -93,18 +185,46 @@ void SkeletonPartListWidget::partListChanged() } } -void SkeletonPartListWidget::partPreviewChanged(QUuid partid) +void SkeletonPartListWidget::partPreviewChanged(QUuid partId) { - const SkeletonPart *part = m_document->findPart(partid); - if (!part) { - qDebug() << "Part not found:" << partid; - return; - } - auto item = m_itemMap.find(partid); + auto item = m_itemMap.find(partId); if (item == m_itemMap.end()) { - qDebug() << "Part item not found:" << partid; + qDebug() << "Part item not found:" << partId; return; } SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); - widget->previewLabel()->setPixmap(QPixmap::fromImage(part->preview)); + widget->updatePreview(); +} + +void SkeletonPartListWidget::partLockStateChanged(QUuid partId) +{ + auto item = m_itemMap.find(partId); + if (item == m_itemMap.end()) { + qDebug() << "Part item not found:" << partId; + return; + } + SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); + widget->updateLockButton(); +} + +void SkeletonPartListWidget::partVisibleStateChanged(QUuid partId) +{ + auto item = m_itemMap.find(partId); + if (item == m_itemMap.end()) { + qDebug() << "Part item not found:" << partId; + return; + } + SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); + widget->updateVisibleButton(); +} + +void SkeletonPartListWidget::partSubdivStateChanged(QUuid partId) +{ + auto item = m_itemMap.find(partId); + if (item == m_itemMap.end()) { + qDebug() << "Part item not found:" << partId; + return; + } + SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); + widget->updateSubdivButton(); } diff --git a/src/skeletonpartlistwidget.h b/src/skeletonpartlistwidget.h index edf64f7d..343cde81 100644 --- a/src/skeletonpartlistwidget.h +++ b/src/skeletonpartlistwidget.h @@ -9,10 +9,17 @@ class SkeletonPartWidget : public QWidget { Q_OBJECT +signals: + void setPartLockState(QUuid partId, bool locked); + void setPartVisibleState(QUuid partId, bool visible); + void setPartSubdivState(QUuid partId, bool subdived); public: SkeletonPartWidget(const SkeletonDocument *document, QUuid partId); void reload(); - QLabel *previewLabel(); + void updatePreview(); + void updateLockButton(); + void updateVisibleButton(); + void updateSubdivButton(); private: const SkeletonDocument *m_document; QUuid m_partId; @@ -21,6 +28,9 @@ private: QPushButton *m_lockButton; QPushButton *m_subdivButton; QLabel *m_nameLabel; +private: + void initButton(QPushButton *button); + void updateButton(QPushButton *button, QChar icon, bool highlighted); }; class SkeletonPartListWidget : public QListWidget @@ -32,6 +42,9 @@ public slots: void partChanged(QUuid partId); void partListChanged(); void partPreviewChanged(QUuid partid); + void partLockStateChanged(QUuid partId); + void partVisibleStateChanged(QUuid partId); + void partSubdivStateChanged(QUuid partId); private: const SkeletonDocument *m_document; std::map m_itemMap;