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");
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()
@ -33,8 +33,8 @@ bool LogBrowser::isDialogVisible()
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());
emit sendMessage( type, msg );
emit sendMessage(type, msg, source, line);
}

View File

@ -13,13 +13,13 @@ public:
~LogBrowser();
public slots:
void outputMessage(QtMsgType type, const QString &msg);
void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line);
void showDialog();
void hideDialog();
bool isDialogVisible();
signals:
void sendMessage(QtMsgType type, const QString &msg);
void sendMessage(QtMsgType type, const QString &msg, const QString &source, int line);
private:
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) {
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;
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;
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;
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;
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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1600,6 +1600,28 @@ void SkeletonGraphicsWidget::selectPartAllById(QUuid partId)
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()
{
unselectAll();

View File

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

View File

@ -754,7 +754,7 @@ void SkeletonPartListWidget::partUnchecked(QUuid 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);