diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-26 17:50:18 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-26 17:50:18 +0200 |
| commit | 9ae43f94f5d822efe582e79b47b2f5407161a38b (patch) | |
| tree | d9b956fb6bb0034da6ca8c923017235b89bb5926 /src/carddelegate.cpp | |
| parent | 8dec28ff4f1176b485d9de722756c677be3a4f1c (diff) | |
| download | qtmaildir-9ae43f94f5d822efe582e79b47b2f5407161a38b.tar.gz qtmaildir-9ae43f94f5d822efe582e79b47b2f5407161a38b.zip | |
fix: correct the avatar initials, the two-tone fill and the fade
Hand-testing item 169 found four defects, three of them visible on every
card.
The initials were taken from whatever the card's first line held, which is
the raw From header on a reply row and notmuch's comma-joined author
summary on a thread row. A naive space split therefore gave `T<` for
`tsujan <notifications@github.com>` and one letter each from two different
people for `Standreas, tsujan`, and a separator counted as a word, so
`INE - Expert IT Training` drew `I-`. Avatar::initialsFor() now normalises
first: the angle-addr and any quoting go, a comma takes the first entry
unless the name is quoted, a bare address is not a name, and a word has to
carry a letter or a digit. Avatar::fillFor() uses the same normalisation,
so an address in the name's place no longer reads as a person.
The two-tone fill built its gradient axis as a radius from the centre, so
the 0.5 colour stop landed on the squircle's edge and one hue filled almost
the whole face. The axis spans the diameter now.
The fade ran left to right, which put its hard stop at 60% of the card and
read as a slab rather than a wash. It runs right to left: opaque at the
card's right edge, where the only hard stop is the card's own boundary, and
gone before it reaches the accent bar that already states the account.
And the flat views hashed the user's own address on every row, so every
Sent and Drafts card shared one pattern. ThreadSummary::firstMessageRecipient
rides the recipient fold, which already parses the To header, and
SenderAddressRole prefers it, falling back to the sender when there is no
usable To.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P88Q3MCSCSQxKDy7pmXh9F
Diffstat (limited to 'src/carddelegate.cpp')
| -rw-r--r-- | src/carddelegate.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/carddelegate.cpp b/src/carddelegate.cpp index 89c3ed0..2dd29a2 100644 --- a/src/carddelegate.cpp +++ b/src/carddelegate.cpp @@ -107,12 +107,20 @@ QRect CardDelegate::fadeRectFor(const QRect &card, const QRect &innermostSpine) { // The EXCLUSIVE right edge, then a rect built from it: QRect::right() is // inclusive, which is the trap CardLayout already documents. - const int end = card.left() + int(card.width() * kFadeFraction); - const int start = innermostSpine.isEmpty() ? card.left() - : innermostSpine.left(); - if (end <= start) + // Right to left: the wash is opaque at the card's RIGHT edge, where a + // hard stop is the card's own boundary, and fades out before reaching the + // accent bar, which already states the account. Drawing it the other way + // put the hard stop mid-card and read as a slab. + // + // A reply's left limit is its own spine rather than the card's edge, so + // the wash steps right with the nesting and stays shorter. + const int left = innermostSpine.isEmpty() ? card.left() + : innermostSpine.left(); + const int start = card.right() + 1 - int(card.width() * kFadeFraction); + if (card.right() + 1 <= qMax(start, left)) return QRect(); - return QRect(start, card.top(), end - start, card.height()); + return QRect(qMax(start, left), card.top(), + card.right() + 1 - qMax(start, left), card.height()); } QColor CardDelegate::accentLineColour(const QColor &accountColour) @@ -219,7 +227,13 @@ void CardDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, // A reply's wash is weaker than its root's, so an expanded thread // reads as one block with the root leading it. from.setAlphaF(card.accentRect.isEmpty() ? 0.14 : 0.30); - QLinearGradient gradient(fade.topLeft(), fade.topRight()); + // Right to left: opaque at the fade's far end, transparent where the + // accent bar already carries the colour. Drawing it the other way put + // the strongest wash under the bar, which is the one place the account + // is already stated. + QLinearGradient gradient(fade.topRight(), fade.topLeft()); + // Opaque at the right edge, gone at the left, so the only hard stop + // is the card's own boundary. gradient.setColorAt(0.0, from); from.setAlphaF(0.0); gradient.setColorAt(1.0, from); |
