From 637aa7a5504f45c05ed39122917c714db84242ea Mon Sep 17 00:00:00 2001 From: sysadmin Date: Thu, 5 Feb 2026 18:32:44 -0700 Subject: [PATCH] Shadcn-style command row: pill chips, chevron breadcrumbs, left-elide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- src/controller.cpp | 12 +++++++++-- src/editor.cpp | 52 +++++++++++++++++++++++++++++++++++----------- src/editor.h | 1 + 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 2901526..79dedaf 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -24,6 +24,12 @@ static QString elide(QString s, int max) { 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) { QStringList parts; QSet seen; @@ -37,7 +43,9 @@ static QString crumbFor(const rcx::NodeTree& t, uint64_t nodeId) { cur = n.parentId; } 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 ── @@ -814,7 +822,7 @@ void RcxController::updateCommandRow() { } 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) ed->setCommandRowText(row); diff --git a/src/editor.cpp b/src/editor.cpp index 0458b14..17bf4e5 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -25,6 +25,7 @@ static constexpr int IND_EDITABLE = 8; static constexpr int IND_HEX_DIM = 9; 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_CMD_PILL = 12; // Rounded chip behind command row spans // Footer selection ID: set high bit to distinguish footer-only selections from node selections static constexpr uint64_t kFooterIdBit = 0x8000000000000000ULL; @@ -151,6 +152,16 @@ void RcxEditor::setupScintilla() { m_sci->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE, 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() { @@ -301,6 +312,7 @@ void RcxEditor::applyDocument(const ComposeResult& result) { applyFoldLevels(result.meta); applyHexDimming(result.meta); applyBaseAddressColoring(result.meta); + applyCommandRowPills(); // Reset hint line - applySelectionOverlay will repaint indicators m_hintLine = -1; @@ -517,18 +529,32 @@ static QString getLineText(QsciScintilla* sci, int line) { } void RcxEditor::applyBaseAddressColoring(const QVector& meta) { - m_sci->SendScintilla(QsciScintillaBase::SCI_SETINDICATORCURRENT, IND_BASE_ADDR); - // Color the ADDR span on CommandRow (line 0) - if (!meta.isEmpty() && meta[0].lineKind == LineKind::CommandRow) { - QString lineText = getLineText(m_sci, 0); - ColumnSpan span = commandRowAddrSpan(lineText); - if (span.valid) { - long posA = posFromCol(m_sci, 0, span.start); - long posB = posFromCol(m_sci, 0, span.end); - if (posB > posA) - m_sci->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, posA, posB - posA); - } - } + if (meta.isEmpty() || meta[0].lineKind != LineKind::CommandRow) return; + + clearIndicatorLine(IND_BASE_ADDR, 0); + QString lineText = getLineText(m_sci, 0); + ColumnSpan span = commandRowAddrSpan(lineText); + if (span.valid) + fillIndicatorCols(IND_BASE_ADDR, 0, span.start, span.end); +} + +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 ── @@ -1563,6 +1589,8 @@ void RcxEditor::setCommandRowText(const QString& line) { m_sci->SendScintilla(QsciScintillaBase::SCI_SETCURRENTPOS, savedPos); m_sci->SendScintilla(QsciScintillaBase::SCI_SETANCHOR, savedAnchor); m_sci->SendScintilla(QsciScintillaBase::SCI_COLOURISE, start, start + utf8.size()); + applyBaseAddressColoring(m_meta); + applyCommandRowPills(); } void RcxEditor::setEditorFont(const QString& fontName) { diff --git a/src/editor.h b/src/editor.h index 03f7b76..80be962 100644 --- a/src/editor.h +++ b/src/editor.h @@ -115,6 +115,7 @@ private: void applyFoldLevels(const QVector& meta); void applyHexDimming(const QVector& meta); void applyBaseAddressColoring(const QVector& meta); + void applyCommandRowPills(); void commitInlineEdit(); int editEndCol() const;