Finish part mini buttons

master
Jeremy Hu 2018-04-08 09:30:55 +08:00
parent 8d558aa19f
commit 1c4515abd7
8 changed files with 294 additions and 69 deletions

View File

@ -184,9 +184,14 @@ void MeshGenerator::process()
std::map<QString, int> partMeshMap; std::map<QString, int> partMeshMap;
std::vector<int> meshIds; std::vector<int> meshIds;
for (const auto &partIdIt: m_snapshot->partIdList) { for (const auto &partIdIt: m_snapshot->partIdList) {
const auto part = m_snapshot->parts.find(partIdIt);
int bmeshId = partBmeshMap[partIdIt]; int bmeshId = partBmeshMap[partIdIt];
int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId, 0); 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()) { if (m_requirePartPreviewMap.find(partIdIt) != m_requirePartPreviewMap.end()) {
ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt]; ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt];
int trimedMeshId = meshlite_trim(meshliteContext, meshId, 1); int trimedMeshId = meshlite_trim(meshliteContext, meshId, 1);

View File

@ -26,14 +26,6 @@ void SkeletonDocument::removePart(QUuid partId)
{ {
} }
void SkeletonDocument::showPart(QUuid partId)
{
}
void SkeletonDocument::hidePart(QUuid partId)
{
}
void SkeletonDocument::removeEdge(QUuid edgeId) void SkeletonDocument::removeEdge(QUuid edgeId)
{ {
const SkeletonEdge *edge = findEdge(edgeId); const SkeletonEdge *edge = findEdge(edgeId);
@ -41,6 +33,8 @@ void SkeletonDocument::removeEdge(QUuid edgeId)
qDebug() << "Find edge failed:" << edgeId; qDebug() << "Find edge failed:" << edgeId;
return; return;
} }
if (isPartLocked(edge->partId))
return;
const SkeletonPart *oldPart = findPart(edge->partId); const SkeletonPart *oldPart = findPart(edge->partId);
if (nullptr == oldPart) { if (nullptr == oldPart) {
qDebug() << "Find part failed:" << edge->partId; qDebug() << "Find part failed:" << edge->partId;
@ -100,6 +94,8 @@ void SkeletonDocument::removeNode(QUuid nodeId)
qDebug() << "Find node failed:" << nodeId; qDebug() << "Find node failed:" << nodeId;
return; return;
} }
if (isPartLocked(node->partId))
return;
const SkeletonPart *oldPart = findPart(node->partId); const SkeletonPart *oldPart = findPart(node->partId);
if (nullptr == oldPart) { if (nullptr == oldPart) {
qDebug() << "Find part failed:" << node->partId; qDebug() << "Find part failed:" << node->partId;
@ -178,6 +174,8 @@ void SkeletonDocument::addNode(float x, float y, float z, float radius, QUuid fr
return; return;
} }
partId = fromNode->partId; partId = fromNode->partId;
if (isPartLocked(partId))
return;
} }
SkeletonNode node; SkeletonNode node;
node.partId = partId; node.partId = partId;
@ -245,12 +243,18 @@ void SkeletonDocument::addEdge(QUuid fromNodeId, QUuid toNodeId)
return; return;
} }
if (isPartLocked(fromNode->partId))
return;
toNode = findNode(toNodeId); toNode = findNode(toNodeId);
if (nullptr == toNode) { if (nullptr == toNode) {
qDebug() << "Find node failed:" << toNodeId; qDebug() << "Find node failed:" << toNodeId;
return; return;
} }
if (isPartLocked(toNode->partId))
return;
QUuid toPartId = toNode->partId; QUuid toPartId = toNode->partId;
auto fromPart = partMap.find(fromNode->partId); auto fromPart = partMap.find(fromNode->partId);
@ -335,11 +339,23 @@ void SkeletonDocument::scaleNodeByAddRadius(QUuid nodeId, float amount)
qDebug() << "Find node failed:" << nodeId; qDebug() << "Find node failed:" << nodeId;
return; return;
} }
if (isPartLocked(it->second.partId))
return;
it->second.radius += amount; it->second.radius += amount;
emit nodeRadiusChanged(nodeId); emit nodeRadiusChanged(nodeId);
emit skeletonChanged(); 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) void SkeletonDocument::moveNodeBy(QUuid nodeId, float x, float y, float z)
{ {
auto it = nodeMap.find(nodeId); 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; qDebug() << "Find node failed:" << nodeId;
return; return;
} }
if (isPartLocked(it->second.partId))
return;
it->second.x += x; it->second.x += x;
it->second.y += y; it->second.y += y;
it->second.z += z; it->second.z += z;
@ -361,6 +379,8 @@ void SkeletonDocument::setNodeOrigin(QUuid nodeId, float x, float y, float z)
qDebug() << "Find node failed:" << nodeId; qDebug() << "Find node failed:" << nodeId;
return; return;
} }
if (isPartLocked(it->second.partId))
return;
it->second.x = x; it->second.x = x;
it->second.y = y; it->second.y = y;
it->second.z = z; it->second.z = z;
@ -375,6 +395,8 @@ void SkeletonDocument::setNodeRadius(QUuid nodeId, float radius)
qDebug() << "Find node failed:" << nodeId; qDebug() << "Find node failed:" << nodeId;
return; return;
} }
if (isPartLocked(it->second.partId))
return;
it->second.radius = radius; it->second.radius = radius;
emit nodeRadiusChanged(nodeId); emit nodeRadiusChanged(nodeId);
emit skeletonChanged(); emit skeletonChanged();
@ -479,6 +501,8 @@ void SkeletonDocument::toSnapshot(SkeletonSnapshot *snapshot)
std::map<QString, QString> part; std::map<QString, QString> part;
part["id"] = partIt.second.id.toString(); part["id"] = partIt.second.id.toString();
part["visible"] = partIt.second.visible ? "true" : "false"; 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()) if (!partIt.second.name.isEmpty())
part["name"] = partIt.second.name; part["name"] = partIt.second.name;
snapshot->parts[part["id"]] = part; snapshot->parts[part["id"]] = part;
@ -560,6 +584,8 @@ void SkeletonDocument::fromSnapshot(const SkeletonSnapshot &snapshot)
SkeletonPart part(QUuid(partKv.first)); SkeletonPart part(QUuid(partKv.first));
part.name = valueOfKeyInMapOrEmpty(partKv.second, "name"); part.name = valueOfKeyInMapOrEmpty(partKv.second, "name");
part.visible = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "visible")); 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; partMap[part.id] = part;
} }
for (const auto &partIdIt: snapshot.partIdList) { for (const auto &partIdIt: snapshot.partIdList) {
@ -704,3 +730,45 @@ void SkeletonDocument::generateMesh()
connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater);
thread->start(); 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();
}

View File

@ -80,11 +80,15 @@ public:
QUuid id; QUuid id;
QString name; QString name;
bool visible; bool visible;
bool locked;
bool subdived;
QImage preview; QImage preview;
std::vector<QUuid> nodeIds; std::vector<QUuid> nodeIds;
bool previewIsObsolete; bool previewIsObsolete;
SkeletonPart(const QUuid &withId=QUuid()) : SkeletonPart(const QUuid &withId=QUuid()) :
visible(true), visible(true),
locked(false),
subdived(false),
previewIsObsolete(true) previewIsObsolete(true)
{ {
id = withId.isNull() ? QUuid::createUuid() : withId; id = withId.isNull() ? QUuid::createUuid() : withId;
@ -134,6 +138,9 @@ signals:
void turnaroundChanged(); void turnaroundChanged();
void editModeChanged(); void editModeChanged();
void skeletonChanged(); void skeletonChanged();
void partLockStateChanged(QUuid partId);
void partVisibleStateChanged(QUuid partId);
void partSubdivStateChanged(QUuid partId);
public: public:
SkeletonDocument(); SkeletonDocument();
~SkeletonDocument(); ~SkeletonDocument();
@ -157,8 +164,6 @@ public slots:
void removeNode(QUuid nodeId); void removeNode(QUuid nodeId);
void removeEdge(QUuid edgeId); void removeEdge(QUuid edgeId);
void removePart(QUuid partId); 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 addNode(float x, float y, float z, float radius, QUuid fromNodeId);
void scaleNodeByAddRadius(QUuid nodeId, float amount); void scaleNodeByAddRadius(QUuid nodeId, float amount);
void moveNodeBy(QUuid nodeId, float x, float y, float z); void moveNodeBy(QUuid nodeId, float x, float y, float z);
@ -171,10 +176,14 @@ public slots:
void uiReady(); void uiReady();
void generateMesh(); void generateMesh();
void meshReady(); void meshReady();
void setPartLockState(QUuid partId, bool locked);
void setPartVisibleState(QUuid partId, bool visible);
void setPartSubdivState(QUuid partId, bool subdived);
private: private:
void splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid nodeId); void splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid nodeId);
void joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId=QUuid()); void joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId, std::set<QUuid> *visitMap, QUuid noUseEdgeId=QUuid());
void splitPartByEdge(std::vector<std::vector<QUuid>> *groups, QUuid edgeId); void splitPartByEdge(std::vector<std::vector<QUuid>> *groups, QUuid edgeId);
bool isPartLocked(QUuid partId);
private: private:
bool m_resultMeshIsObsolete; bool m_resultMeshIsObsolete;
MeshGenerator *m_meshGenerator; MeshGenerator *m_meshGenerator;

View File

@ -97,9 +97,9 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
containerWidget->setMinimumSize(400, 400); containerWidget->setMinimumSize(400, 400);
m_modelWidget = new ModelWidget(containerWidget); m_modelWidget = new ModelWidget(containerWidget);
m_modelWidget->setMinimumSize(128, 128); m_modelWidget->setMinimumSize(256, 256);
m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_modelWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_modelWidget->move(10, 10); m_modelWidget->move(16, 16);
m_modelWidget->setGraphicsFunctions(graphicsWidget); m_modelWidget->setGraphicsFunctions(graphicsWidget);
SkeletonPartListWidget *partListWidget = new SkeletonPartListWidget(m_document); SkeletonPartListWidget *partListWidget = new SkeletonPartListWidget(m_document);
@ -193,33 +193,13 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(m_document, &SkeletonDocument::edgeRemoved, graphicsWidget, &SkeletonGraphicsWidget::edgeRemoved); connect(m_document, &SkeletonDocument::edgeRemoved, graphicsWidget, &SkeletonGraphicsWidget::edgeRemoved);
connect(m_document, &SkeletonDocument::nodeRadiusChanged, graphicsWidget, &SkeletonGraphicsWidget::nodeRadiusChanged); connect(m_document, &SkeletonDocument::nodeRadiusChanged, graphicsWidget, &SkeletonGraphicsWidget::nodeRadiusChanged);
connect(m_document, &SkeletonDocument::nodeOriginChanged, graphicsWidget, &SkeletonGraphicsWidget::nodeOriginChanged); 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::partListChanged, partListWidget, &SkeletonPartListWidget::partListChanged);
connect(m_document, &SkeletonDocument::partPreviewChanged, partListWidget, &SkeletonPartListWidget::partPreviewChanged); connect(m_document, &SkeletonDocument::partPreviewChanged, partListWidget, &SkeletonPartListWidget::partPreviewChanged);
connect(m_document, &SkeletonDocument::partLockStateChanged, partListWidget, &SkeletonPartListWidget::partLockStateChanged);
/* connect(m_document, &SkeletonDocument::partVisibleStateChanged, partListWidget, &SkeletonPartListWidget::partVisibleStateChanged);
connect(graphicsWidget, &SkeletonGraphicsWidget::checkEdge, edgePropertyWidget, &SkeletonEdgePropertyWidget::showProperties); connect(m_document, &SkeletonDocument::partSubdivStateChanged, partListWidget, &SkeletonPartListWidget::partSubdivStateChanged);
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::skeletonChanged, m_document, &SkeletonDocument::generateMesh); connect(m_document, &SkeletonDocument::skeletonChanged, m_document, &SkeletonDocument::generateMesh);

View File

@ -366,11 +366,16 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
} }
QPointF mainProfile = m_cursorNodeItem->origin(); QPointF mainProfile = m_cursorNodeItem->origin();
QPointF sideProfile = mainProfile; QPointF sideProfile = mainProfile;
if (m_checkedNodeItem) {
auto itemIt = nodeItemMap.find(m_checkedNodeItem->id());
sideProfile.setX(itemIt->second.second->origin().x());
} else {
if (mainProfile.x() >= scene()->width() / 2) { if (mainProfile.x() >= scene()->width() / 2) {
sideProfile.setX(mainProfile.x() - scene()->width() / 4); sideProfile.setX(mainProfile.x() - scene()->width() / 4);
} else { } else {
sideProfile.setX(mainProfile.x() +scene()->width() / 4); sideProfile.setX(mainProfile.x() +scene()->width() / 4);
} }
}
QPointF unifiedMainPos = scenePosToUnified(mainProfile); QPointF unifiedMainPos = scenePosToUnified(mainProfile);
QPointF unifiedSidePos = scenePosToUnified(sideProfile); QPointF unifiedSidePos = scenePosToUnified(sideProfile);
if (isFloatEqual(m_lastAddedX, unifiedMainPos.x()) && isFloatEqual(m_lastAddedY, unifiedMainPos.y()) && isFloatEqual(m_lastAddedZ, unifiedSidePos.x())) if (isFloatEqual(m_lastAddedX, unifiedMainPos.x()) && isFloatEqual(m_lastAddedY, unifiedMainPos.y()) && isFloatEqual(m_lastAddedZ, unifiedSidePos.x()))
@ -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);
}
}

View File

@ -264,6 +264,7 @@ public slots:
void canvasResized(); void canvasResized();
void editModeChanged(); void editModeChanged();
void updateCursor(); void updateCursor();
void partVisibleStateChanged(QUuid partId);
private slots: private slots:
void turnaroundImageReady(); void turnaroundImageReady();
private: private:

View File

@ -8,20 +8,17 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
m_document(document), m_document(document),
m_partId(partId) m_partId(partId)
{ {
m_visibleButton = new QPushButton(QChar(fa::eye)); m_visibleButton = new QPushButton();
m_visibleButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); updateButton(m_visibleButton, QChar(fa::eye), false);
m_visibleButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); initButton(m_visibleButton);
m_visibleButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize);
m_lockButton = new QPushButton(QChar(fa::unlock)); m_lockButton = new QPushButton();
m_lockButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); updateButton(m_lockButton, QChar(fa::unlock), false);
m_lockButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); initButton(m_lockButton);
m_lockButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize);
m_subdivButton = new QPushButton(QChar(fa::cube)); m_subdivButton = new QPushButton();
m_subdivButton->setStyleSheet("QPushButton {border: none; background: none; color: #252525;}"); updateButton(m_subdivButton, QChar(fa::cube), false);
m_subdivButton->setFont(Theme::awesome()->font(Theme::miniIconFontSize)); initButton(m_subdivButton);
m_subdivButton->setFixedSize(Theme::miniIconSize, Theme::miniIconSize);
m_previewLabel = new QLabel; m_previewLabel = new QLabel;
@ -34,46 +31,141 @@ SkeletonPartWidget::SkeletonPartWidget(const SkeletonDocument *document, QUuid p
miniToolLayout->addWidget(m_subdivButton); miniToolLayout->addWidget(m_subdivButton);
miniToolLayout->addStretch(); 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; QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->setSpacing(0); mainLayout->setSpacing(0);
mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addLayout(miniToolLayout); mainLayout->addLayout(miniToolLayout);
mainLayout->addWidget(m_previewLabel); mainLayout->addWidget(m_previewLabel);
mainLayout->addWidget(hrWidget);
setLayout(mainLayout); 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); const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) { if (!part) {
qDebug() << "Part not found:" << m_partId; qDebug() << "Part not found:" << m_partId;
return; return;
} }
//m_nameLabel->setText(part->name.isEmpty() ? part->id.toString() : part->name);
m_previewLabel->setPixmap(QPixmap::fromImage(part->preview)); 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) : SkeletonPartListWidget::SkeletonPartListWidget(const SkeletonDocument *document) :
m_document(document) m_document(document)
{ {
setSelectionMode(QAbstractItemView::NoSelection); setSelectionMode(QAbstractItemView::NoSelection);
setFocusPolicy(Qt::NoFocus);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setSpacing(1); setSpacing(0);
setContentsMargins(0, 0, 0, 0); setContentsMargins(0, 0, 0, 0);
} }
void SkeletonPartListWidget::partChanged(QUuid partId) void SkeletonPartListWidget::partChanged(QUuid partId)
{ {
auto itemIt = m_itemMap.find(partId); auto item = m_itemMap.find(partId);
if (itemIt == m_itemMap.end()) { if (item == m_itemMap.end()) {
qDebug() << "Part item not found:" << partId;
return; return;
} }
SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second);
widget->reload();
} }
void SkeletonPartListWidget::partListChanged() 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); auto item = m_itemMap.find(partId);
if (!part) {
qDebug() << "Part not found:" << partid;
return;
}
auto item = m_itemMap.find(partid);
if (item == m_itemMap.end()) { if (item == m_itemMap.end()) {
qDebug() << "Part item not found:" << partid; qDebug() << "Part item not found:" << partId;
return; return;
} }
SkeletonPartWidget *widget = (SkeletonPartWidget *)itemWidget(item->second); 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();
} }

View File

@ -9,10 +9,17 @@
class SkeletonPartWidget : public QWidget class SkeletonPartWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
signals:
void setPartLockState(QUuid partId, bool locked);
void setPartVisibleState(QUuid partId, bool visible);
void setPartSubdivState(QUuid partId, bool subdived);
public: public:
SkeletonPartWidget(const SkeletonDocument *document, QUuid partId); SkeletonPartWidget(const SkeletonDocument *document, QUuid partId);
void reload(); void reload();
QLabel *previewLabel(); void updatePreview();
void updateLockButton();
void updateVisibleButton();
void updateSubdivButton();
private: private:
const SkeletonDocument *m_document; const SkeletonDocument *m_document;
QUuid m_partId; QUuid m_partId;
@ -21,6 +28,9 @@ private:
QPushButton *m_lockButton; QPushButton *m_lockButton;
QPushButton *m_subdivButton; QPushButton *m_subdivButton;
QLabel *m_nameLabel; QLabel *m_nameLabel;
private:
void initButton(QPushButton *button);
void updateButton(QPushButton *button, QChar icon, bool highlighted);
}; };
class SkeletonPartListWidget : public QListWidget class SkeletonPartListWidget : public QListWidget
@ -32,6 +42,9 @@ public slots:
void partChanged(QUuid partId); void partChanged(QUuid partId);
void partListChanged(); void partListChanged();
void partPreviewChanged(QUuid partid); void partPreviewChanged(QUuid partid);
void partLockStateChanged(QUuid partId);
void partVisibleStateChanged(QUuid partId);
void partSubdivStateChanged(QUuid partId);
private: private:
const SkeletonDocument *m_document; const SkeletonDocument *m_document;
std::map<QUuid, QListWidgetItem *> m_itemMap; std::map<QUuid, QListWidgetItem *> m_itemMap;