mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
feat: enum editing UI, protect enums from struct ops, New Class opens two tabs
- New Class creates two Unnamed tabs, selects the first - New Enum creates 5 placeholder members (Member0-4) - Right-click enum member: Add Member Above/Below, Remove Member - Right-click enum header: Add Member, Rename, Delete only - Enum nodes fully protected from struct operations (no Add Child, Insert, Convert)
This commit is contained in:
@@ -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) ──
|
||||
|
||||
23
src/main.cpp
23
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() {
|
||||
|
||||
Reference in New Issue
Block a user