summaryrefslogtreecommitdiffstats
path: root/src/carddelegate.cpp
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-10 08:58:48 +0200
committerDanilo M. <danix@danix.xyz>2026-08-10 08:58:48 +0200
commit8767e8d33f5065ff57d7abd5bc916dbb13ada2d5 (patch)
treefff56f2a44b8d978ad3d4793fa951e086c92e220 /src/carddelegate.cpp
parent1a96ce7d2a2ba5575502db85bce8ed0efe799665 (diff)
downloadqtmaildir-8767e8d33f5065ff57d7abd5bc916dbb13ada2d5.tar.gz
qtmaildir-8767e8d33f5065ff57d7abd5bc916dbb13ada2d5.zip
fix(view): stop clipping the date, and make the accent bar visible
Both found by rendering real cards to an image and looking at them, not by any assertion. The suite was green through both. The date lost the leading digit of its year on every UNREAD card. The layout reserves the date's width from the font it is handed, which is the view's regular font, while the delegate paints with the bold one the model supplies for unread: 154px reserved against 170px needed. CardLayout now measures the date bold whatever font it is given, so the reserved width cannot be narrower than what is drawn. A few pixels are wasted on a read card, which is the cheap side of the trade. The accent bar was painted correctly and was invisible. Blending the account colour 0.35 toward the palette's Base, as the plan specified, is a fraction OF THE ACCOUNT COLOUR, so on a dark theme it produced (0.18, 0.22, 0.26) against a Base of (0.169, 0.169, 0.169): the background. The blend is dropped entirely. An account colour is already chosen to be a chip's fill carrying legible text, so it is muted to begin with, and nothing is drawn on the bar that needs that contrast. The spine keeps a blend, at 0.55, because it runs the full height of every reply in an expansion and is a different problem from a 3px edge marker. The bar is still faint at 3px on a dark theme, since the account colours are chosen as chip fills. Whether kAccentWidth needs raising cannot be settled without the user's own accounts, screen and theme; that is Task 10's open question and it is left open.
Diffstat (limited to 'src/carddelegate.cpp')
-rw-r--r--src/carddelegate.cpp44
1 files changed, 31 insertions, 13 deletions
diff --git a/src/carddelegate.cpp b/src/carddelegate.cpp
index bc03b5a..a3a846d 100644
--- a/src/carddelegate.cpp
+++ b/src/carddelegate.cpp
@@ -53,15 +53,21 @@ QColor CardDelegate::accentLineColour(const QColor &accountColour)
if (!accountColour.isValid())
return ThreadListModel::threadLineColour();
- // The same 0.35 weight threadLineColour() uses, toward Base rather than
- // toward Text, so the two kinds of line sit at the same visual strength.
- const QColor base = QGuiApplication::palette().color(QPalette::Base);
- constexpr qreal kWeight = 0.35;
- const qreal inverse = 1.0 - kWeight;
- return QColor::fromRgbF(
- accountColour.redF() * kWeight + base.redF() * inverse,
- accountColour.greenF() * kWeight + base.greenF() * inverse,
- accountColour.blueF() * kWeight + base.blueF() * inverse);
+ // 0.35 toward Base was the first attempt and produced an INVISIBLE bar on
+ // a dark theme: rendered against a Base of (0.169, 0.169, 0.169) it landed
+ // at (0.18, 0.22, 0.26), which is the background. The weight is a fraction
+ // OF THE ACCOUNT COLOUR, so a low one keeps the background, not the hue.
+ //
+ // The bar is the account's colour, undiluted. Blending it toward Base at
+ // all was the mistake: a chip's colour is chosen to carry text on top and
+ // is therefore already muted, and three pixels of a muted colour on a dark
+ // background is nothing at all. There is no text on this bar, so nothing
+ // needs the contrast a chip's fill was picked for.
+ //
+ // What DOES step back is the spine, below: a line running the height of a
+ // whole expansion has to be followable without competing with the senders
+ // beside it, which is a different problem from a 3px edge marker.
+ return accountColour;
}
QSize CardDelegate::sizeHint(const QStyleOptionViewItem &option,
@@ -110,10 +116,22 @@ void CardDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
if (!card.accentRect.isEmpty())
painter->fillRect(card.accentRect, lineColour);
- // Spines, under everything else, in the same accent so an expanded thread
- // is bounded by one colour from its root to its last reply.
- for (const QRect &spine : card.spines)
- painter->fillRect(spine, lineColour);
+ // Spines, under everything else, in the account's hue so an expanded thread
+ // is bounded by one colour from its root to its last reply. Muted against
+ // the pane's own background, unlike the accent bar: this line runs the full
+ // height of every reply and at full strength it shouts.
+ if (!card.spines.isEmpty()) {
+ const QColor base =
+ QGuiApplication::palette().color(QPalette::Base);
+ constexpr qreal kSpineWeight = 0.55;
+ const qreal inverse = 1.0 - kSpineWeight;
+ const QColor spineColour = QColor::fromRgbF(
+ lineColour.redF() * kSpineWeight + base.redF() * inverse,
+ lineColour.greenF() * kSpineWeight + base.greenF() * inverse,
+ lineColour.blueF() * kSpineWeight + base.blueF() * inverse);
+ for (const QRect &spine : card.spines)
+ painter->fillRect(spine, spineColour);
+ }
// Selection outranks the model's foreground, and the order matters: a read
// card carries a dimmed colour blended against the UNSELECTED background,