Shadcn-style command row: pill chips, chevron breadcrumbs, left-elide

- Add ROUNDBOX pill indicators behind editable SRC and ADDR spans
- Switch breadcrumb separator from > to › (U+203A)
- Collapse deep paths (>4 parts) with ellipsis
- Left-elide breadcrumb path to keep current selection visible
- Clear base-addr indicator before repainting (prevents smear)
- Wire pill + addr decorators into setCommandRowText refresh
This commit is contained in:
sysadmin
2026-02-05 18:32:44 -07:00
parent 82e1520ded
commit 637aa7a550
3 changed files with 51 additions and 14 deletions

View File

@@ -24,6 +24,12 @@ static QString elide(QString s, int max) {
return s.left(max - 1) + QChar(0x2026); return s.left(max - 1) + QChar(0x2026);
} }
static QString elideLeft(const QString& s, int max) {
if (s.size() <= max) return s;
if (max <= 1) return QStringLiteral("\u2026").left(max);
return QStringLiteral("\u2026") + s.right(max - 1);
}
static QString crumbFor(const rcx::NodeTree& t, uint64_t nodeId) { static QString crumbFor(const rcx::NodeTree& t, uint64_t nodeId) {
QStringList parts; QStringList parts;
QSet<uint64_t> seen; QSet<uint64_t> seen;
@@ -37,7 +43,9 @@ static QString crumbFor(const rcx::NodeTree& t, uint64_t nodeId) {
cur = n.parentId; cur = n.parentId;
} }
std::reverse(parts.begin(), parts.end()); std::reverse(parts.begin(), parts.end());
return parts.join(QStringLiteral(" > ")); if (parts.size() > 4)
parts = {parts.front(), QStringLiteral("\u2026"), parts[parts.size() - 2], parts.back()};
return parts.join(QStringLiteral(" \u203A "));
} }
// ── RcxDocument ── // ── RcxDocument ──
@@ -814,7 +822,7 @@ void RcxController::updateCommandRow() {
} }
QString row = QStringLiteral(" * SRC: %1 : %2 %3") QString row = QStringLiteral(" * SRC: %1 : %2 %3")
.arg(elide(src, 40), elide(addr, 24), elide(path, 120)); .arg(elide(src, 40), elide(addr, 24), elideLeft(path, 120));
for (auto* ed : m_editors) for (auto* ed : m_editors)
ed->setCommandRowText(row); ed->setCommandRowText(row);

View File

@@ -25,6 +25,7 @@ static constexpr int IND_EDITABLE = 8;
static constexpr int IND_HEX_DIM = 9; static constexpr int IND_HEX_DIM = 9;
static constexpr int IND_BASE_ADDR = 10; // Green color for base address static constexpr int IND_BASE_ADDR = 10; // Green color for base address
static constexpr int IND_HOVER_SPAN = 11; // Blue text on hover (link-like) static constexpr int IND_HOVER_SPAN = 11; // Blue text on hover (link-like)
static constexpr int IND_CMD_PILL = 12; // Rounded chip behind command row spans
// Footer selection ID: set high bit to distinguish footer-only selections from node selections // Footer selection ID: set high bit to distinguish footer-only selections from node selections
static constexpr uint64_t kFooterIdBit = 0x8000000000000000ULL; static constexpr uint64_t kFooterIdBit = 0x8000000000000000ULL;
@@ -151,6 +152,16 @@ void RcxEditor::setupScintilla() {
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE, m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
IND_HOVER_SPAN, QColor("#3d9c8a")); IND_HOVER_SPAN, QColor("#3d9c8a"));
// Command-row pill background (shadcn-ish chip)
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE,
IND_CMD_PILL, 7 /*INDIC_ROUNDBOX*/);
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,
IND_CMD_PILL, QColor("#2a2a2a"));
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETALPHA,
IND_CMD_PILL, (long)90);
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETUNDER,
IND_CMD_PILL, (long)1);
} }
void RcxEditor::setupLexer() { void RcxEditor::setupLexer() {
@@ -301,6 +312,7 @@ void RcxEditor::applyDocument(const ComposeResult& result) {
applyFoldLevels(result.meta); applyFoldLevels(result.meta);
applyHexDimming(result.meta); applyHexDimming(result.meta);
applyBaseAddressColoring(result.meta); applyBaseAddressColoring(result.meta);
applyCommandRowPills();
// Reset hint line - applySelectionOverlay will repaint indicators // Reset hint line - applySelectionOverlay will repaint indicators
m_hintLine = -1; m_hintLine = -1;
@@ -517,18 +529,32 @@ static QString getLineText(QsciScintilla* sci, int line) {
} }
void RcxEditor::applyBaseAddressColoring(const QVector<LineMeta>& meta) { void RcxEditor::applyBaseAddressColoring(const QVector<LineMeta>& meta) {
m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_BASE_ADDR); if (meta.isEmpty() || meta[0].lineKind != LineKind::CommandRow) return;
// Color the ADDR span on CommandRow (line 0)
if (!meta.isEmpty() && meta[0].lineKind == LineKind::CommandRow) { clearIndicatorLine(IND_BASE_ADDR, 0);
QString lineText = getLineText(m_sci, 0); QString lineText = getLineText(m_sci, 0);
ColumnSpan span = commandRowAddrSpan(lineText); ColumnSpan span = commandRowAddrSpan(lineText);
if (span.valid) { if (span.valid)
long posA = posFromCol(m_sci, 0, span.start); fillIndicatorCols(IND_BASE_ADDR, 0, span.start, span.end);
long posB = posFromCol(m_sci, 0, span.end); }
if (posB > posA)
m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, posA, posB - posA); void RcxEditor::applyCommandRowPills() {
} if (m_meta.isEmpty() || m_meta[0].lineKind != LineKind::CommandRow) return;
}
constexpr int line = 0;
QString t = getLineText(m_sci, line);
clearIndicatorLine(IND_CMD_PILL, line);
auto fillPadded = [&](ColumnSpan s) {
if (!s.valid) return;
int a = qMax(0, s.start - 1);
int b = qMin(t.size(), s.end + 1);
fillIndicatorCols(IND_CMD_PILL, line, a, b);
};
fillPadded(commandRowSrcSpan(t));
fillPadded(commandRowAddrSpan(t));
} }
// ── Shared inline-edit shutdown ── // ── Shared inline-edit shutdown ──
@@ -1563,6 +1589,8 @@ void RcxEditor::setCommandRowText(const QString& line) {
m_sci->SendScintilla(QsciScintillaBase::SCI_SETCURRENTPOS, savedPos); m_sci->SendScintilla(QsciScintillaBase::SCI_SETCURRENTPOS, savedPos);
m_sci->SendScintilla(QsciScintillaBase::SCI_SETANCHOR, savedAnchor); m_sci->SendScintilla(QsciScintillaBase::SCI_SETANCHOR, savedAnchor);
m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, start, start + utf8.size()); m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, start, start + utf8.size());
applyBaseAddressColoring(m_meta);
applyCommandRowPills();
} }
void RcxEditor::setEditorFont(const QString& fontName) { void RcxEditor::setEditorFont(const QString& fontName) {

View File

@@ -115,6 +115,7 @@ private:
void applyFoldLevels(const QVector<LineMeta>& meta); void applyFoldLevels(const QVector<LineMeta>& meta);
void applyHexDimming(const QVector<LineMeta>& meta); void applyHexDimming(const QVector<LineMeta>& meta);
void applyBaseAddressColoring(const QVector<LineMeta>& meta); void applyBaseAddressColoring(const QVector<LineMeta>& meta);
void applyCommandRowPills();
void commitInlineEdit(); void commitInlineEdit();
int editEndCol() const; int editEndCol() const;