Fix copy/paste selection state.

In the previous version, the nodes get selected and copied, without lost selection after new nodes pasted.
This commit fix this problem. Now, the old nodes lose selection while new pasted nodes gettting selected.
This feature will make the following use case much easier:

Extrude:
Select some nodes, copy, paste then scale.
master
Jeremy Hu 2018-05-12 18:07:46 +08:00
parent bdbac96c00
commit 6268852e59
11 changed files with 80 additions and 23 deletions

View File

@ -8,7 +8,7 @@ LogBrowser::LogBrowser(QObject *parent) :
{ {
qRegisterMetaType<QtMsgType>("QtMsgType"); qRegisterMetaType<QtMsgType>("QtMsgType");
m_browserDialog = new LogBrowserDialog; m_browserDialog = new LogBrowserDialog;
connect(this, SIGNAL(sendMessage(QtMsgType,QString)), m_browserDialog, SLOT(outputMessage(QtMsgType,QString)), Qt::QueuedConnection); connect(this, &LogBrowser::sendMessage, m_browserDialog, &LogBrowserDialog::outputMessage, Qt::QueuedConnection);
} }
LogBrowser::~LogBrowser() LogBrowser::~LogBrowser()
@ -33,8 +33,8 @@ bool LogBrowser::isDialogVisible()
return m_browserDialog->isVisible(); return m_browserDialog->isVisible();
} }
void LogBrowser::outputMessage(QtMsgType type, const QString &msg) void LogBrowser::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line)
{ {
printf("%s\n", msg.toUtf8().constData()); printf("%s\n", msg.toUtf8().constData());
emit sendMessage( type, msg ); emit sendMessage(type, msg, source, line);
} }

View File

@ -13,13 +13,13 @@ public:
~LogBrowser(); ~LogBrowser();
public slots: public slots:
void outputMessage(QtMsgType type, const QString &msg); void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line);
void showDialog(); void showDialog();
void hideDialog(); void hideDialog();
bool isDialogVisible(); bool isDialogVisible();
signals: signals:
void sendMessage(QtMsgType type, const QString &msg); void sendMessage(QtMsgType type, const QString &msg, const QString &source, int line);
private: private:
LogBrowserDialog *m_browserDialog; LogBrowserDialog *m_browserDialog;

View File

@ -49,27 +49,27 @@ LogBrowserDialog::~LogBrowserDialog()
} }
void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg) void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line)
{ {
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
m_browser->append(tr("— DEBUG: %1").arg(msg)); m_browser->append(tr("— DEBUG: %1 - %2:%3").arg(msg).arg(source).arg(QString::number(line)));
break; break;
case QtWarningMsg: case QtWarningMsg:
m_browser->append(tr("— WARNING: %1").arg(msg)); m_browser->append(tr("— WARNING: %1 - %2:%3").arg(msg).arg(source).arg(QString::number(line)));
break; break;
case QtCriticalMsg: case QtCriticalMsg:
m_browser->append(tr("— CRITICAL: %1").arg(msg)); m_browser->append(tr("— CRITICAL: %1 - %2:%3").arg(msg).arg(source).arg(QString::number(line)));
break; break;
case QtInfoMsg: case QtInfoMsg:
m_browser->append(tr("— INFO: %1").arg(msg)); m_browser->append(tr("— INFO: %1 - %2:%3").arg(msg).arg(source).arg(QString::number(line)));
break; break;
case QtFatalMsg: case QtFatalMsg:
m_browser->append(tr("— FATAL: %1").arg(msg)); m_browser->append(tr("— FATAL: %1 - %2:%3").arg(msg).arg(source).arg(QString::number(line)));
break; break;
} }
} }

View File

@ -14,7 +14,7 @@ public:
~LogBrowserDialog(); ~LogBrowserDialog();
public slots: public slots:
void outputMessage(QtMsgType type, const QString &msg); void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line);
protected slots: protected slots:
void save(); void save();
@ -28,4 +28,4 @@ protected:
QPushButton *m_saveButton; QPushButton *m_saveButton;
}; };
#endif // DIALOG_H #endif // DIALOG_H

View File

@ -199,6 +199,8 @@ void ModelMeshBinder::cleanup()
m_vboTriangle.destroy(); m_vboTriangle.destroy();
if (m_vboEdge.isCreated()) if (m_vboEdge.isCreated())
m_vboEdge.destroy(); m_vboEdge.destroy();
delete m_texture;
m_texture = nullptr;
} }
void ModelMeshBinder::showWireframes() void ModelMeshBinder::showWireframes()

View File

@ -687,6 +687,10 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
originZ = originZit->second.toFloat(); originZ = originZit->second.toFloat();
} }
std::set<QUuid> newAddedNodeIds;
std::set<QUuid> newAddedEdgeIds;
std::set<QUuid> newAddedPartIds;
std::map<QUuid, QUuid> oldNewIdMap; std::map<QUuid, QUuid> oldNewIdMap;
for (const auto &partKv : snapshot.parts) { for (const auto &partKv : snapshot.parts) {
SkeletonPart part; SkeletonPart part;
@ -711,6 +715,7 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
if (deformWidthIt != partKv.second.end()) if (deformWidthIt != partKv.second.end())
part.setDeformWidth(deformWidthIt->second.toFloat()); part.setDeformWidth(deformWidthIt->second.toFloat());
partMap[part.id] = part; partMap[part.id] = part;
newAddedPartIds.insert(part.id);
} }
for (const auto &nodeKv : snapshot.nodes) { for (const auto &nodeKv : snapshot.nodes) {
if (nodeKv.second.find("radius") == nodeKv.second.end() || if (nodeKv.second.find("radius") == nodeKv.second.end() ||
@ -728,6 +733,7 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
node.z = valueOfKeyInMapOrEmpty(nodeKv.second, "z").toFloat(); node.z = valueOfKeyInMapOrEmpty(nodeKv.second, "z").toFloat();
node.partId = oldNewIdMap[QUuid(valueOfKeyInMapOrEmpty(nodeKv.second, "partId"))]; node.partId = oldNewIdMap[QUuid(valueOfKeyInMapOrEmpty(nodeKv.second, "partId"))];
nodeMap[node.id] = node; nodeMap[node.id] = node;
newAddedNodeIds.insert(node.id);
} }
for (const auto &edgeKv : snapshot.edges) { for (const auto &edgeKv : snapshot.edges) {
if (edgeKv.second.find("from") == edgeKv.second.end() || if (edgeKv.second.find("from") == edgeKv.second.end() ||
@ -751,28 +757,45 @@ void SkeletonDocument::addFromSnapshot(const SkeletonSnapshot &snapshot)
nodeMap[toId].edgeIds.push_back(edge.id); nodeMap[toId].edgeIds.push_back(edge.id);
} }
edgeMap[edge.id] = edge; edgeMap[edge.id] = edge;
newAddedEdgeIds.insert(edge.id);
} }
for (const auto &nodeIt: nodeMap) { for (const auto &nodeIt: nodeMap) {
if (newAddedNodeIds.find(nodeIt.first) == newAddedNodeIds.end())
continue;
partMap[nodeIt.second.partId].nodeIds.push_back(nodeIt.first); partMap[nodeIt.second.partId].nodeIds.push_back(nodeIt.first);
} }
for (const auto &partIdIt: snapshot.partIdList) { for (const auto &partIdIt: snapshot.partIdList) {
partIds.push_back(oldNewIdMap[QUuid(partIdIt)]); const auto partId = oldNewIdMap[QUuid(partIdIt)];
if (newAddedPartIds.find(partId) == newAddedPartIds.end())
continue;
partIds.push_back(partId);
} }
for (const auto &nodeIt: nodeMap) { for (const auto &nodeIt: newAddedNodeIds) {
emit nodeAdded(nodeIt.first); emit nodeAdded(nodeIt);
} }
for (const auto &edgeIt: edgeMap) { for (const auto &edgeIt: newAddedEdgeIds) {
emit edgeAdded(edgeIt.first); emit edgeAdded(edgeIt);
} }
for (const auto &partIt : partMap) { for (const auto &partIt : newAddedPartIds) {
emit partAdded(partIt.first); emit partAdded(partIt);
emit partVisibleStateChanged(partIt.first);
} }
emit partListChanged(); emit partListChanged();
emit originChanged(); emit originChanged();
emit skeletonChanged(); emit skeletonChanged();
for (const auto &partIt : newAddedPartIds) {
emit partVisibleStateChanged(partIt);
}
emit uncheckAll();
for (const auto &nodeIt: newAddedNodeIds) {
emit checkNode(nodeIt);
}
for (const auto &edgeIt: newAddedEdgeIds) {
emit checkEdge(edgeIt);
}
} }
void SkeletonDocument::reset() void SkeletonDocument::reset()
@ -792,6 +815,7 @@ void SkeletonDocument::fromSnapshot(const SkeletonSnapshot &snapshot)
{ {
reset(); reset();
addFromSnapshot(snapshot); addFromSnapshot(snapshot);
emit uncheckAll();
} }
MeshLoader *SkeletonDocument::takeResultMesh() MeshLoader *SkeletonDocument::takeResultMesh()

View File

@ -213,6 +213,9 @@ signals:
void enableBackgroundBlur(); void enableBackgroundBlur();
void disableBackgroundBlur(); void disableBackgroundBlur();
void exportReady(); void exportReady();
void uncheckAll();
void checkNode(QUuid nodeId);
void checkEdge(QUuid edgeId);
public: // need initialize public: // need initialize
float originX; float originX;
float originY; float originY;

View File

@ -43,7 +43,7 @@ AboutWidget *g_aboutWidget = nullptr;
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
if (g_logBrowser) if (g_logBrowser)
g_logBrowser->outputMessage(type, msg); g_logBrowser->outputMessage(type, msg, context.file, context.line);
} }
void SkeletonDocumentWindow::showAcknowlegements() void SkeletonDocumentWindow::showAcknowlegements()
@ -497,6 +497,9 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(m_document, &SkeletonDocument::checkPart, graphicsWidget, &SkeletonGraphicsWidget::selectPartAllById); connect(m_document, &SkeletonDocument::checkPart, graphicsWidget, &SkeletonGraphicsWidget::selectPartAllById);
connect(m_document, &SkeletonDocument::enableBackgroundBlur, graphicsWidget, &SkeletonGraphicsWidget::enableBackgroundBlur); connect(m_document, &SkeletonDocument::enableBackgroundBlur, graphicsWidget, &SkeletonGraphicsWidget::enableBackgroundBlur);
connect(m_document, &SkeletonDocument::disableBackgroundBlur, graphicsWidget, &SkeletonGraphicsWidget::disableBackgroundBlur); connect(m_document, &SkeletonDocument::disableBackgroundBlur, graphicsWidget, &SkeletonGraphicsWidget::disableBackgroundBlur);
connect(m_document, &SkeletonDocument::uncheckAll, graphicsWidget, &SkeletonGraphicsWidget::unselectAll);
connect(m_document, &SkeletonDocument::checkNode, graphicsWidget, &SkeletonGraphicsWidget::addSelectNode);
connect(m_document, &SkeletonDocument::checkEdge, graphicsWidget, &SkeletonGraphicsWidget::addSelectEdge);
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);
@ -789,6 +792,7 @@ void SkeletonDocumentWindow::open()
SkeletonSnapshot snapshot; SkeletonSnapshot snapshot;
loadSkeletonFromXmlStream(&snapshot, stream); loadSkeletonFromXmlStream(&snapshot, stream);
m_document->fromSnapshot(snapshot); m_document->fromSnapshot(snapshot);
m_document->saveSnapshot();
} else if (item.type == "asset") { } else if (item.type == "asset") {
if (item.name == "canvas.png") { if (item.name == "canvas.png") {
QByteArray data; QByteArray data;

View File

@ -1600,6 +1600,28 @@ void SkeletonGraphicsWidget::selectPartAllById(QUuid partId)
hoverPart(QUuid()); hoverPart(QUuid());
} }
void SkeletonGraphicsWidget::addSelectNode(QUuid nodeId)
{
const auto &findResult = nodeItemMap.find(nodeId);
if (findResult == nodeItemMap.end()) {
qDebug() << "addSelectNode failed because of node id not exists:<<" << nodeId;
return;
}
addItemToRangeSelection(findResult->second.first);
hoverPart(QUuid());
}
void SkeletonGraphicsWidget::addSelectEdge(QUuid edgeId)
{
const auto &findResult = edgeItemMap.find(edgeId);
if (findResult == edgeItemMap.end()) {
qDebug() << "addSelectEdge failed because of edge id not exists:<<" << edgeId;
return;
}
addItemToRangeSelection(findResult->second.first);
hoverPart(QUuid());
}
void SkeletonGraphicsWidget::selectPartAll() void SkeletonGraphicsWidget::selectPartAll()
{ {
unselectAll(); unselectAll();

View File

@ -427,6 +427,8 @@ public slots:
void originChanged(); void originChanged();
void alignSelectedToCenter(); void alignSelectedToCenter();
void selectPartAllById(QUuid partId); void selectPartAllById(QUuid partId);
void addSelectNode(QUuid nodeId);
void addSelectEdge(QUuid edgeId);
void enableBackgroundBlur(); void enableBackgroundBlur();
void disableBackgroundBlur(); void disableBackgroundBlur();
private slots: private slots:

View File

@ -754,7 +754,7 @@ void SkeletonPartListWidget::partUnchecked(QUuid partId)
{ {
auto item = m_itemMap.find(partId); 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);