Add bone list model
parent
eba729d785
commit
5c9898f25b
|
@ -95,6 +95,8 @@ include(third_party/QtAwesome/QtAwesome/QtAwesome.pri)
|
||||||
|
|
||||||
HEADERS += sources/about_widget.h
|
HEADERS += sources/about_widget.h
|
||||||
SOURCES += sources/about_widget.cc
|
SOURCES += sources/about_widget.cc
|
||||||
|
HEADERS += sources/bone_list_model.h
|
||||||
|
SOURCES += sources/bone_list_model.cc
|
||||||
HEADERS += sources/ccd_ik_resolver.h
|
HEADERS += sources/ccd_ik_resolver.h
|
||||||
SOURCES += sources/ccd_ik_resolver.cc
|
SOURCES += sources/ccd_ik_resolver.cc
|
||||||
HEADERS += sources/component_list_model.h
|
HEADERS += sources/component_list_model.h
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
#include "bone_list_model.h"
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <dust3d/base/debug.h>
|
||||||
|
|
||||||
|
BoneListModel::BoneListModel(const Document* document, QObject* parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
, m_document(document)
|
||||||
|
{
|
||||||
|
connect(m_document, &Document::bonePreviewPixmapChanged, [this](const dust3d::Uuid& boneId) {
|
||||||
|
auto findIndex = this->m_boneIdToIndexMap.find(boneId);
|
||||||
|
if (findIndex != this->m_boneIdToIndexMap.end()) {
|
||||||
|
emit this->dataChanged(findIndex->second, findIndex->second);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(m_document, &Document::cleanup, this, &BoneListModel::reload);
|
||||||
|
connect(m_document, &Document::boneIdListChanged, this, &BoneListModel::reload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoneListModel::reload()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_boneIdToIndexMap.clear();
|
||||||
|
for (int i = 0; i < (int)m_document->boneIdList.size(); ++i) {
|
||||||
|
m_boneIdToIndexMap[m_document->boneIdList[i]] = createIndex(i, 0);
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex BoneListModel::boneIdToIndex(const dust3d::Uuid& boneId) const
|
||||||
|
{
|
||||||
|
auto findIndex = m_boneIdToIndexMap.find(boneId);
|
||||||
|
if (findIndex == m_boneIdToIndexMap.end())
|
||||||
|
return QModelIndex();
|
||||||
|
return findIndex->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
int BoneListModel::rowCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return 0;
|
||||||
|
return (int)m_document->boneIdList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BoneListModel::columnCount(const QModelIndex& parent) const
|
||||||
|
{
|
||||||
|
if (parent.isValid())
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Document::Bone* BoneListModel::modelIndexToBone(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (index.row() >= (int)m_document->boneIdList.size()) {
|
||||||
|
dust3dDebug << "Bone list row is out of range, size:" << m_document->boneIdList.size() << "row:" << index.row();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const auto& boneId = m_document->boneIdList[index.row()];
|
||||||
|
const Document::Bone* bone = m_document->findBone(boneId);
|
||||||
|
if (nullptr == bone) {
|
||||||
|
dust3dDebug << "Bone not found:" << boneId.toString();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return bone;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dust3d::Uuid BoneListModel::modelIndexToBoneId(const QModelIndex& index) const
|
||||||
|
{
|
||||||
|
if (index.row() >= (int)m_document->boneIdList.size()) {
|
||||||
|
dust3dDebug << "Bone list row is out of range, size:" << m_document->boneIdList.size() << "row:" << index.row();
|
||||||
|
return dust3d::Uuid();
|
||||||
|
}
|
||||||
|
const auto& boneId = m_document->boneIdList[index.row()];
|
||||||
|
return boneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant BoneListModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::ToolTipRole: {
|
||||||
|
const Document::Bone* bone = modelIndexToBone(index);
|
||||||
|
if (nullptr != bone) {
|
||||||
|
return bone->name;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Qt::DecorationRole: {
|
||||||
|
const Document::Bone* bone = modelIndexToBone(index);
|
||||||
|
if (nullptr != bone) {
|
||||||
|
if (0 == bone->previewPixmap.width()) {
|
||||||
|
static QPixmap s_emptyPixmap;
|
||||||
|
if (0 == s_emptyPixmap.width()) {
|
||||||
|
QImage image((int)Theme::partPreviewImageSize, (int)Theme::partPreviewImageSize, QImage::Format_ARGB32);
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
s_emptyPixmap = QPixmap::fromImage(image);
|
||||||
|
}
|
||||||
|
return s_emptyPixmap;
|
||||||
|
}
|
||||||
|
return bone->previewPixmap;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef DUST3D_APPLICATION_BONE_LIST_MODEL_H_
|
||||||
|
#define DUST3D_APPLICATION_BONE_LIST_MODEL_H_
|
||||||
|
|
||||||
|
#include "document.h"
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <dust3d/base/uuid.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class BoneListModel : public QAbstractListModel {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BoneListModel(const Document* document, QObject* parent = nullptr);
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||||
|
QVariant data(const QModelIndex& index, int role) const;
|
||||||
|
const Document::Bone* modelIndexToBone(const QModelIndex& index) const;
|
||||||
|
QModelIndex boneIdToIndex(const dust3d::Uuid& boneId) const;
|
||||||
|
const dust3d::Uuid modelIndexToBoneId(const QModelIndex& index) const;
|
||||||
|
public slots:
|
||||||
|
void reload();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Document* m_document = nullptr;
|
||||||
|
std::unordered_map<dust3d::Uuid, QModelIndex> m_boneIdToIndexMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -2855,6 +2855,7 @@ void Document::addBone(const dust3d::Uuid& boneId)
|
||||||
boneMap.emplace(boneId, bone);
|
boneMap.emplace(boneId, bone);
|
||||||
boneIdList.push_back(boneId);
|
boneIdList.push_back(boneId);
|
||||||
emit boneAdded(boneId);
|
emit boneAdded(boneId);
|
||||||
|
emit boneIdListChanged();
|
||||||
emit rigChanged();
|
emit rigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2893,6 +2894,7 @@ void Document::removeBone(const dust3d::Uuid& boneId)
|
||||||
boneIdList.erase(std::remove(boneIdList.begin(), boneIdList.end(), boneId), boneIdList.end());
|
boneIdList.erase(std::remove(boneIdList.begin(), boneIdList.end(), boneId), boneIdList.end());
|
||||||
boneMap.erase(boneId);
|
boneMap.erase(boneId);
|
||||||
emit boneRemoved(boneId);
|
emit boneRemoved(boneId);
|
||||||
|
emit boneIdListChanged();
|
||||||
emit rigChanged();
|
emit rigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2920,3 +2922,11 @@ void Document::renameBone(const dust3d::Uuid& boneId, const QString& name)
|
||||||
emit boneNameChanged(boneId);
|
emit boneNameChanged(boneId);
|
||||||
emit rigChanged();
|
emit rigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Document::Bone* Document::findBone(const dust3d::Uuid& boneId) const
|
||||||
|
{
|
||||||
|
auto boneIt = boneMap.find(boneId);
|
||||||
|
if (boneIt == boneMap.end())
|
||||||
|
return nullptr;
|
||||||
|
return &boneIt->second;
|
||||||
|
}
|
||||||
|
|
|
@ -564,6 +564,7 @@ public:
|
||||||
dust3d::Uuid attachBoneId;
|
dust3d::Uuid attachBoneId;
|
||||||
int attachBoneJointIndex = 0;
|
int attachBoneJointIndex = 0;
|
||||||
QString name;
|
QString name;
|
||||||
|
QPixmap previewPixmap;
|
||||||
|
|
||||||
Bone(const dust3d::Uuid& withId = dust3d::Uuid());
|
Bone(const dust3d::Uuid& withId = dust3d::Uuid());
|
||||||
};
|
};
|
||||||
|
@ -643,6 +644,8 @@ signals:
|
||||||
void boneAttachmentChanged(const dust3d::Uuid& boneId);
|
void boneAttachmentChanged(const dust3d::Uuid& boneId);
|
||||||
void boneNodesChanged(const dust3d::Uuid& boneId);
|
void boneNodesChanged(const dust3d::Uuid& boneId);
|
||||||
void boneNameChanged(const dust3d::Uuid& boneId);
|
void boneNameChanged(const dust3d::Uuid& boneId);
|
||||||
|
void bonePreviewPixmapChanged(const dust3d::Uuid& boneId);
|
||||||
|
void boneIdListChanged();
|
||||||
void rigChanged();
|
void rigChanged();
|
||||||
|
|
||||||
public: // need initialize
|
public: // need initialize
|
||||||
|
@ -769,6 +772,7 @@ public:
|
||||||
void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image);
|
void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image);
|
||||||
void resetDirtyFlags();
|
void resetDirtyFlags();
|
||||||
void markAllDirty();
|
void markAllDirty();
|
||||||
|
const Bone* findBone(const dust3d::Uuid& boneId) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void undo();
|
void undo();
|
||||||
|
|
Loading…
Reference in New Issue