Condensed array display + per-scope column widths + MIT license

- Array element structs render without { } braces (condensed display)
- [N] separators show element indices within arrays
- Per-scope column width calculation (nested elements use tighter spacing)
- Array headers show struct[N] for struct arrays
- [N] separators are not interactive (no hover/click highlight)
- Dynamic type column width (min 8, max 14)
- PE32+ sample data with full headers, DataDirectory[16], SectionHeaders[4]
- Added MIT license

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
IChooChoose
2026-02-05 06:26:00 -07:00
committed by sysadmin
parent 04252a3c96
commit 4d35db224e
11 changed files with 727 additions and 430 deletions

View File

@@ -28,10 +28,27 @@ static TypeNameFn g_typeNameFn = nullptr;
void setTypeNameProvider(TypeNameFn fn) { g_typeNameFn = fn; }
QString typeName(NodeKind kind) {
if (g_typeNameFn) return fit(g_typeNameFn(kind), COL_TYPE);
// Unpadded type name for width calculation
QString typeNameRaw(NodeKind kind) {
if (g_typeNameFn) return g_typeNameFn(kind);
auto* m = kindMeta(kind);
return fit(m ? QString::fromLatin1(m->typeName) : QStringLiteral("???"), COL_TYPE);
return m ? QString::fromLatin1(m->typeName) : QStringLiteral("???");
}
QString typeName(NodeKind kind, int colType) {
if (g_typeNameFn) return fit(g_typeNameFn(kind), colType);
auto* m = kindMeta(kind);
return fit(m ? QString::fromLatin1(m->typeName) : QStringLiteral("???"), colType);
}
// Array type string: "uint32_t[16]" or "char[64]"
QString arrayTypeName(NodeKind elemKind, int count) {
auto* m = kindMeta(elemKind);
QString elem = m ? QString::fromLatin1(m->typeName) : QStringLiteral("???");
// char[] for UInt8, wchar_t[] for UInt16
if (elemKind == NodeKind::UInt8) elem = QStringLiteral("char");
else if (elemKind == NodeKind::UInt16) elem = QStringLiteral("wchar_t");
return elem + QStringLiteral("[") + QString::number(count) + QStringLiteral("]");
}
// ── Value formatting ──
@@ -95,12 +112,15 @@ QString fmtStructHeaderWithBase(const Node& node, int depth, uint64_t baseAddres
return header + QStringLiteral("base: ") + baseHex;
}
QString fmtStructFooter(const Node& node, int depth, int totalSize) {
QString s = indent(depth) + QStringLiteral("};");
if (totalSize > 0)
s += QStringLiteral(" // sizeof(") + node.name + QStringLiteral(")=0x")
+ QString::number(totalSize, 16).toUpper();
return s;
QString fmtStructFooter(const Node& /*node*/, int depth, int /*totalSize*/) {
return indent(depth) + QStringLiteral("};");
}
// ── Array header ──
// Format: "uint32_t[16] myArray {" (like struct header, no fixed columns)
QString fmtArrayHeader(const Node& node, int depth, int /*viewIdx*/) {
QString type = arrayTypeName(node.elementKind, node.arrayLen);
return indent(depth) + type + QStringLiteral(" ") + node.name + QStringLiteral(" {");
}
// ── Hex / ASCII preview ──
@@ -230,12 +250,12 @@ QString readValue(const Node& node, const Provider& prov,
QString fmtNodeLine(const Node& node, const Provider& prov,
uint64_t addr, int depth, int subLine,
const QString& comment, int colName) {
const QString& comment, int colType, int colName) {
QString ind = indent(depth);
QString type = typeName(node.kind);
QString type = typeName(node.kind, colType);
QString name = fit(node.name, colName);
// Blank prefix for continuation lines (same width as type+sep+name+sep)
const int prefixW = COL_TYPE + colName + 4; // 2 seps × 2 chars
const int prefixW = colType + colName + 4; // 2 seps × 2 chars
// Comment suffix (padded or empty)
QString cmtSuffix = comment.isEmpty() ? QString(COL_COMMENT, ' ')
@@ -268,7 +288,7 @@ QString fmtNodeLine(const Node& node, const Provider& prov,
QString hex = bytesToHex(b, lineBytes).leftJustified(23, ' '); // 8*3-1
if (subLine == 0)
return ind + type + SEP + ascii + SEP + hex + cmtSuffix;
return ind + QString(COL_TYPE + (int)SEP.size(), ' ') + ascii + SEP + hex + cmtSuffix;
return ind + QString(colType + (int)SEP.size(), ' ') + ascii + SEP + hex + cmtSuffix;
}
// Hex8..Hex64: single line, ASCII padded to 8 chars so hex column aligns
const int sz = sizeForKind(node.kind);