diff --git a/src/controller.cpp b/src/controller.cpp index 14a6e54..73e07b7 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -1777,7 +1777,41 @@ void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, && !node.bitfieldMembers.isEmpty() && subLine >= 0 && subLine < node.bitfieldMembers.size(); + bool isEnumNode = node.resolvedClassKeyword() == QStringLiteral("enum"); + if (isEnumMember || isBitfieldMember) { + if (isEnumMember) { + menu.addAction(icon("diff-added.svg"), "Add Member Above", [this, nodeId, subLine]() { + int ni = m_doc->tree.indexOfId(nodeId); + if (ni < 0) return; + auto members = m_doc->tree.nodes[ni].enumMembers; + int64_t val = (subLine > 0) ? members[subLine - 1].second + 1 : 0; + auto oldMembers = members; + members.insert(subLine, {QStringLiteral("NewMember"), val}); + m_doc->undoStack.push(new RcxCommand(this, + cmd::ChangeEnumMembers{nodeId, oldMembers, members})); + }); + menu.addAction(icon("diff-added.svg"), "Add Member Below", [this, nodeId, subLine]() { + int ni = m_doc->tree.indexOfId(nodeId); + if (ni < 0) return; + auto members = m_doc->tree.nodes[ni].enumMembers; + int64_t val = members[subLine].second + 1; + auto oldMembers = members; + members.insert(subLine + 1, {QStringLiteral("NewMember"), val}); + m_doc->undoStack.push(new RcxCommand(this, + cmd::ChangeEnumMembers{nodeId, oldMembers, members})); + }); + menu.addAction(icon("trash.svg"), "Remove Member", [this, nodeId, subLine]() { + int ni = m_doc->tree.indexOfId(nodeId); + if (ni < 0) return; + auto members = m_doc->tree.nodes[ni].enumMembers; + auto oldMembers = members; + members.remove(subLine); + m_doc->undoStack.push(new RcxCommand(this, + cmd::ChangeEnumMembers{nodeId, oldMembers, members})); + }); + menu.addSeparator(); + } if (isBitfieldMember) { const auto& bm = node.bitfieldMembers[subLine]; if (bm.bitWidth == 1) { @@ -1792,6 +1826,28 @@ void RcxController::showContextMenu(RcxEditor* editor, int line, int nodeIdx, menu.addSeparator(); } // Fall through to always-available actions + } else if (isEnumNode) { + // Enum header line — enum-specific actions only (no struct ops) + menu.addAction(icon("diff-added.svg"), "Add Member", [this, nodeId]() { + int ni = m_doc->tree.indexOfId(nodeId); + if (ni < 0) return; + auto members = m_doc->tree.nodes[ni].enumMembers; + int64_t nextVal = members.isEmpty() ? 0 : members.last().second + 1; + auto oldMembers = members; + members.append({QStringLiteral("NewMember"), nextVal}); + m_doc->undoStack.push(new RcxCommand(this, + cmd::ChangeEnumMembers{nodeId, oldMembers, members})); + }); + menu.addAction(icon("edit.svg"), "&Rename...", [this, editor, line]() { + editor->beginInlineEdit(EditTarget::Name, line); + }); + menu.addSeparator(); + menu.addAction(icon("trash.svg"), "&Delete", [this, nodeId]() { + int ni = m_doc->tree.indexOfId(nodeId); + if (ni >= 0) removeNode(ni); + }); + menu.addSeparator(); + // Fall through to always-available actions } else { // ── Quick-convert suggestions (top-level for fast access) ── diff --git a/src/main.cpp b/src/main.cpp index 7509157..41db826 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1920,6 +1920,26 @@ void MainWindow::setupDockTabBars() { // Build a minimal empty struct for new documents static void buildEmptyStruct(NodeTree& tree, const QString& classKeyword = QString()) { + // ── Enum: bare node with empty enumMembers, no hex children ── + if (classKeyword == QStringLiteral("enum")) { + Node root; + root.kind = NodeKind::Struct; + root.name = "Unnamed"; + root.structTypeName = "Unnamed"; + root.classKeyword = classKeyword; + root.parentId = 0; + root.offset = 0; + root.enumMembers = { + {QStringLiteral("Member0"), 0}, + {QStringLiteral("Member1"), 1}, + {QStringLiteral("Member2"), 2}, + {QStringLiteral("Member3"), 3}, + {QStringLiteral("Member4"), 4}, + }; + tree.addNode(root); + return; + } + Node root; root.kind = NodeKind::Struct; root.name = "instance"; @@ -1988,7 +2008,10 @@ MainWindow::~MainWindow() { } void MainWindow::newClass() { + auto* first = project_new(QStringLiteral("class")); project_new(QStringLiteral("class")); + // Select the first tab + if (first) first->raise(); } void MainWindow::newStruct() {