minorfixes

This commit is contained in:
batallion caputa
2026-02-07 16:41:01 -07:00
parent 9962e55820
commit 18475d0570
7 changed files with 146 additions and 72 deletions

View File

@@ -222,6 +222,7 @@ void composeParent(ComposeState& state, const NodeTree& tree,
state.baseEmitted = true;
// Header line (skip for array element structs and root struct)
// Root struct header is on CommandRow2 (type + name + {)
if (!isArrayChild && !isRootHeader) {
// Get per-scope widths for this header's parent scope
int typeW = state.effectiveTypeW(scopeId);
@@ -263,8 +264,7 @@ void composeParent(ComposeState& state, const NodeTree& tree,
return tree.nodes[a].offset < tree.nodes[b].offset;
});
// Root struct children compose at same depth (no header to indent from)
int childDepth = isRootHeader ? depth : depth + 1;
int childDepth = depth + 1;
// For arrays, render children as condensed (no header/footer for struct elements)
bool childrenAreArrayElements = (node.kind == NodeKind::Array);
@@ -278,8 +278,8 @@ void composeParent(ComposeState& state, const NodeTree& tree,
}
}
// Footer line: skip when collapsed, for array element structs, or for root struct
if (!isArrayChild && !isRootHeader && !node.collapsed) {
// Footer line: skip when collapsed or for array element structs
if (!isArrayChild && (!node.collapsed || isRootHeader)) {
LineMeta lm;
lm.nodeIdx = nodeIdx;
lm.nodeId = node.id;
@@ -501,7 +501,7 @@ ComposeResult compose(const NodeTree& tree, const Provider& prov, uint64_t viewR
lm.markerMask = 0;
lm.effectiveTypeW = state.typeW;
lm.effectiveNameW = state.nameW;
state.emitLine(QStringLiteral("struct <no class>"), lm);
state.emitLine(QStringLiteral("struct <no class> {"), lm);
}
QVector<int> roots = state.childMap.value(0);

View File

@@ -1408,13 +1408,13 @@ void RcxController::updateCommandRow() {
if (n.parentId == 0 && n.kind == NodeKind::Struct) {
QString keyword = n.resolvedClassKeyword();
QString className = n.structTypeName.isEmpty() ? n.name : n.structTypeName;
row2 = QStringLiteral("%1 %2")
row2 = QStringLiteral("%1 %2 {")
.arg(keyword, className);
break;
}
}
if (row2.isEmpty())
row2 = QStringLiteral("struct <no class>");
row2 = QStringLiteral("struct <no class> {");
for (auto* ed : m_editors) {
ed->setCommandRowText(row);

View File

@@ -603,6 +603,7 @@ inline ColumnSpan commandRow2TypeSpan(const QString& lineText) {
}
inline ColumnSpan commandRow2NameSpan(const QString& lineText) {
// Format: "keyword name {" — extract just the name part (before " {")
int start = 0;
while (start < lineText.size() && lineText[start].isSpace()) start++;
int space = lineText.indexOf(' ', start);
@@ -610,7 +611,9 @@ inline ColumnSpan commandRow2NameSpan(const QString& lineText) {
int nameStart = space + 1;
while (nameStart < lineText.size() && lineText[nameStart].isSpace()) nameStart++;
if (nameStart >= lineText.size()) return {};
int nameEnd = lineText.size();
// Stop before trailing " {"
int nameEnd = lineText.indexOf(QStringLiteral(" {"), nameStart);
if (nameEnd < 0) nameEnd = lineText.size();
while (nameEnd > nameStart && lineText[nameEnd - 1].isSpace()) nameEnd--;
if (nameEnd <= nameStart) return {};
return {nameStart, nameEnd, true};

View File

@@ -677,6 +677,8 @@ void RcxEditor::applyCommandRowPills() {
// ── Shared inline-edit shutdown ──
RcxEditor::EndEditInfo RcxEditor::endInlineEdit() {
// Dismiss any open user list / autocomplete popup
m_sci->SendScintilla(QsciScintillaBase::SCI_AUTOCCANCEL);
// Clear edit comment and error marker before deactivating
if (m_editState.target == EditTarget::Value) {
setEditComment({}); // Clear to spaces

View File

@@ -201,9 +201,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
m_mdiArea->setTabsMovable(true);
setCentralWidget(m_mdiArea);
createWorkspaceDock();
createMenus();
createStatusBar();
createWorkspaceDock();
connect(m_mdiArea, &QMdiArea::subWindowActivated,
this, [this](QMdiSubWindow*) {
@@ -279,6 +279,8 @@ void MainWindow::createMenus() {
view->addSeparator();
m_actViewRendered = view->addAction(makeIcon(":/vsicons/code.svg"), "&C/C++", this, [this]() { setViewMode(VM_Rendered); });
m_actViewReclass = view->addAction(makeIcon(":/vsicons/eye.svg"), "&Reclass View", this, [this]() { setViewMode(VM_Reclass); });
view->addSeparator();
view->addAction(m_workspaceDock->toggleViewAction());
// Node
auto* node = menuBar()->addMenu("&Node");
@@ -395,12 +397,48 @@ void MainWindow::newFile() {
}
void MainWindow::selfTest() {
// Load demo.rcx if it exists, otherwise create a blank project
QString demoPath = QCoreApplication::applicationDirPath() + "/demo.rcx";
if (QFile::exists(demoPath)) {
project_open(demoPath);
} else {
project_new();
// Create default demo with a single Ball struct
auto* doc = new RcxDocument(this);
doc->tree.baseAddress = 0x00400000;
Node ball;
ball.kind = NodeKind::Struct;
ball.name = "aBall";
ball.structTypeName = "Ball";
ball.parentId = 0;
ball.offset = 0;
int bi = doc->tree.addNode(ball);
uint64_t ballId = doc->tree.nodes[bi].id;
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_00"; n.parentId = ballId; n.offset = 0; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_08"; n.parentId = ballId; n.offset = 8; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Vec4; n.name = "position"; n.parentId = ballId; n.offset = 16; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Vec3; n.name = "velocity"; n.parentId = ballId; n.offset = 32; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex32; n.name = "field_2C"; n.parentId = ballId; n.offset = 44; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Float; n.name = "speed"; n.parentId = ballId; n.offset = 48; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex32; n.name = "field_34"; n.parentId = ballId; n.offset = 52; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::UInt32; n.name = "color"; n.parentId = ballId; n.offset = 56; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex32; n.name = "field_3C"; n.parentId = ballId; n.offset = 60; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Float; n.name = "radius"; n.parentId = ballId; n.offset = 64; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex32; n.name = "field_44"; n.parentId = ballId; n.offset = 68; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Double; n.name = "mass"; n.parentId = ballId; n.offset = 72; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_50"; n.parentId = ballId; n.offset = 80; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Bool; n.name = "bouncy"; n.parentId = ballId; n.offset = 88; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex8; n.name = "field_59"; n.parentId = ballId; n.offset = 89; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex16; n.name = "field_5A"; n.parentId = ballId; n.offset = 90; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::UInt32; n.name = "bounceCount"; n.parentId = ballId; n.offset = 92; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex32; n.name = "field_60"; n.parentId = ballId; n.offset = 96; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_68"; n.parentId = ballId; n.offset = 100; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_70"; n.parentId = ballId; n.offset = 108; doc->tree.addNode(n); }
{ Node n; n.kind = NodeKind::Hex64; n.name = "field_78"; n.parentId = ballId; n.offset = 116; doc->tree.addNode(n); }
doc->save(demoPath);
doc->load(demoPath);
createTab(doc);
}
}
@@ -886,6 +924,7 @@ void MainWindow::createWorkspaceDock() {
m_workspaceDock->setWidget(m_workspaceTree);
addDockWidget(Qt::LeftDockWidgetArea, m_workspaceDock);
m_workspaceDock->hide();
connect(m_workspaceTree, &QTreeView::doubleClicked, this, [this](const QModelIndex& index) {
// Data roles: UserRole=QMdiSubWindow*, UserRole+1=structId, UserRole+2=nodeId