diff --git a/plugins/builtin/include/content/views/view_data_processor.hpp b/plugins/builtin/include/content/views/view_data_processor.hpp index 0de86aa73..6ea7ab04e 100644 --- a/plugins/builtin/include/content/views/view_data_processor.hpp +++ b/plugins/builtin/include/content/views/view_data_processor.hpp @@ -50,6 +50,7 @@ namespace hex::plugin::builtin { static void processNodes(Workspace &workspace); void reloadCustomNodes(); + void updateNodePositions(); std::vector &getWorkspaceStack() { return *m_workspaceStack; } diff --git a/plugins/builtin/source/content/views/view_data_processor.cpp b/plugins/builtin/source/content/views/view_data_processor.cpp index 29eb8ea75..d014719a0 100644 --- a/plugins/builtin/source/content/views/view_data_processor.cpp +++ b/plugins/builtin/source/content/views/view_data_processor.cpp @@ -194,6 +194,7 @@ namespace hex::plugin::builtin { m_dataProcessor->getWorkspaceStack().push_back(&m_workspace); m_requiresAttributeUpdate = true; + m_dataProcessor->updateNodePositions(); } } else { this->setUnlocalizedTitle(m_name); @@ -588,6 +589,11 @@ namespace hex::plugin::builtin { } } + void ViewDataProcessor::updateNodePositions() { + m_updateNodePositions = true; + } + + void ViewDataProcessor::drawContextMenus(ViewDataProcessor::Workspace &workspace) { // Handle the right click context menus if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows)) { @@ -696,6 +702,8 @@ namespace hex::plugin::builtin { // Set the position of the node to the position where the user right-clicked ImNodes::SetNodeScreenSpacePos(node->getId(), m_rightClickedCoords); + node->setPosition(m_rightClickedCoords); + workspace.nodes.push_back(std::move(node)); ImHexApi::Provider::markDirty(); @@ -865,6 +873,7 @@ namespace hex::plugin::builtin { ImNodes::BeginNodeEditor(); // Loop over all nodes that have been placed in the workspace + bool stillUpdating = m_updateNodePositions; for (auto &node : workspace.nodes) { ImNodes::SnapNodeToGrid(node->getId()); @@ -880,7 +889,8 @@ namespace hex::plugin::builtin { ImNodes::PopColorStyle(); } - m_updateNodePositions = false; + if (stillUpdating) + m_updateNodePositions = false; // Handle removing links that are connected to attributes that don't exist anymore { @@ -1093,7 +1103,11 @@ namespace hex::plugin::builtin { u32 attrIndex = 0; for (auto &attr : newNode->getAttributes()) { - attr.setId(data["attrs"][attrIndex]); + if (attrIndex < data["attrs"].size()) + attr.setId(data["attrs"][attrIndex]); + else + attr.setId(-1); + attrIndex++; } @@ -1118,8 +1132,6 @@ namespace hex::plugin::builtin { if (newNode == nullptr) continue; - newNode->setPosition(ImVec2(node["pos"]["x"], node["pos"]["y"])); - if (!node["data"].is_null()) newNode->load(node["data"]); @@ -1133,13 +1145,19 @@ namespace hex::plugin::builtin { if (attr.getIOType() == dp::Attribute::IOType::In) hasInput = true; - attr.setId(node["attrs"][attrIndex]); + if (attrIndex < node["attrs"].size()) + attr.setId(node["attrs"][attrIndex]); + else + attr.setId(-1); + attrIndex++; } if (hasInput && !hasOutput) workspace.endNodes.push_back(newNode.get()); + newNode->setPosition(ImVec2(node["pos"]["x"], node["pos"]["y"])); + workspace.nodes.push_back(std::move(newNode)); } @@ -1164,16 +1182,16 @@ namespace hex::plugin::builtin { } if (fromAttr == nullptr || toAttr == nullptr) - break; + continue; if (fromAttr->getType() != toAttr->getType()) - break; + continue; if (fromAttr->getIOType() == toAttr->getIOType()) - break; + continue; if (!toAttr->getConnectedAttributes().empty()) - break; + continue; fromAttr->addConnectedAttribute(newLink.getId(), toAttr); toAttr->addConnectedAttribute(newLink.getId(), fromAttr); @@ -1189,6 +1207,13 @@ namespace hex::plugin::builtin { } } + for (auto &node : workspace.nodes) { + if (node->getId() == -1) { + maxNodeId += 1; + node->setId(maxNodeId); + } + } + dp::Node::setIdCounter(maxNodeId + 1); dp::Attribute::setIdCounter(maxAttrId + 1); dp::Link::setIdCounter(maxLinkId + 1);