Files
qbz/crates/qbz-qt/qml/views/local/SelectCheck.qml
T
vicrodh 81c43a114e fix(qt): glyph colours follow the theme, on light palettes and on accent fills
Two defects with one cause: a tint name that means a frozen hex.

"primary" is the legacy alias of literal #ffffff, not Theme.text-primary,
so every control passing it drew a white glyph. On the eleven light
themes that is white-on-light -- the header back/forward chevrons, the
sidebar toggle and the carousel arrows the owner marked. They now pass
the theme-following names, which icon_tint_qt bakes at runtime.

The stale `hslLightness > 0.5 ? "primary" : "black"` workarounds that
predate the runtime tinter collapse into those names, and the qrc floor
underneath them becomes polarity-aware: dir_for() returns "" whenever
the cache dir is unavailable, a bake fails or the theme document has not
been published, and that path used to resolve textPrimary straight back
to the white bake -- reproducing the bug it was fixing, app-wide, in the
degraded state.

On accent fills the fix is a deviation from Slint, approved by the owner
after measurement. A fixed white glyph on Theme.accent falls under 2.6:1
on 16 of the 35 shipped palettes, including high-contrast at 1.70:1 and
wcag-dark at 1.82:1 -- the two themes whose reason to exist is contrast.
Slint hardcodes #ffffff there (CircleAction.slint:72 and three others),
so the bug is upstream. accentText alone is not the answer either: it is
picked for the theme's text ramp and gives 2.56:1 on Rose Pine Dawn,
worse than the black it replaces. So QbzTheme picks the best-contrast
tint by real sRGB luminance against the live accent, and the labels
beside those glyphs use its colour twin -- BrowseGenreButton and
LibraryView were drawing a white glyph next to an accentText label
inside the same pill.

Rounds out the two parity items the same files owe: QbzNavButton gains
the ambient arm from Carousel.slint (wired at the six carousel sites,
not left dead), and QbzCircleAction rounds its glyph to whole pixels the
way CircleAction.slint does.

cc
2026-07-29 10:30:43 -06:00

58 lines
2.2 KiB
QML

// The app-wide selection checkbox (LocalLibraryView.slint:486-515): a 13px
// circle, accent-filled when on, 1.5px muted ring when off, 8px white check
// glyph — or a minus glyph for the folder tri-state "partial".
//
// Slint declares this inline inside TreeRow; the Qt port also needs it on
// the album cards and the track rows in multi-select, so it is its own file
// (three call sites, one shape).
import QtQuick
import com.blitzfc.qbz
import "../../theme"
Rectangle {
id: root
property bool on: false
property bool partial: false
property int diameter: 13
signal toggled()
QbzTheme { id: theme }
width: diameter
height: diameter
radius: diameter / 2
color: (on || partial) ? theme.accent : "transparent"
border.width: (on || partial) ? 0 : 1.5
border.color: checkArea.containsMouse ? theme.textPrimary : theme.textMuted
QbzIcon {
visible: root.on || root.partial
name: root.partial ? "minus" : "check"
width: Math.round(root.diameter * 0.62)
height: Math.round(root.diameter * 0.62)
anchors.centerIn: parent
// DELIBERATE DIVERGENCE from primitives/SelectionCheckbox.slint:37,
// which hardcodes `tint: #ffffff` on this same accent fill. That
// white is under 2.6:1 on 16 of the 35 palettes, worst on
// high-contrast at 1.70:1, then ikari 1.74 and wcag-dark 1.82 —
// i.e. the two ACCESSIBILITY themes bracket the top of the list.
// (This site used to claim ikari 1.74 was "the worst case in the
// app"; it is second. The 8px glyph here does make it the smallest
// thing painted at those ratios, which is a different argument and
// the one worth keeping.) Slint's own QbzCheckbox.slint:24 uses
// accent-text for the equivalent glyph, so upstream contradicts
// ITSELF here; the selector settles it by measurement instead of by
// picking a side. See theme/QbzTheme.qml, "ON AN ACCENT FILL".
tintName: theme.accentGlyphTint
}
MouseArea {
id: checkArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.toggled()
}
}