refactor(qbz-qt): phase 23 part 1 — QML module layout + first five domain bridges

Two fronts of the modularization, both gated green before this commit.

QML leaves the flat qml/ directory for seven modules: cards, controls,
rows, settings, shell, theme, views. Only Main.qml and LoginScreen.qml
stay at the root. build.rs matches the tree exactly (55 files), relative
imports and asset paths were re-anchored for the new depth.

The QbzBridge God-object starts breaking up: QbzSession, QbzShell,
QbzPlayer, QbzQueue and QbzHome are now their own #[cxx_qt::bridge]
singletons, each with its own OnceLock<CxxQtThread> and ui() hop, booted
in order from Main.qml. Bridge files stay directly under src/ because
cxx-qt-build only accepts rust_files from one directory (QTBUG-93443).

bridge.rs keeps 5.5 domains (library, album/artist, settings,
integrations, search, playlist) and dies once they are split out.

cc
This commit is contained in:
vicrodh committed 2026-07-28 11:08:20 -06:00
1 parent 580b72084f
commit 9a4fec6b70
72 files changed
+2152 -1690

No files matched your search

+75
View File
@@ -0,0 +1,75 @@
// QbzSlider (primitives/QbzSlider.slint) — extracted from SettingsView.qml
// in phase 19. 200x22, 4px r2 track, accent fill, 16px thumb; integer
// steps. Like the Slint original the thumb follows the pointer during a
// drag (local dragValue) and commits each step via changed(int).
import QtQuick
import com.blitzfc.qbz
import "../theme"
Item {
property int minimum: 0
property int maximum: 10
property int value: 0
signal changed(int newValue)
QbzTheme { id: theme }
width: 200
height: 22
readonly property int thumbSize: 16
readonly property real travel: width - thumbSize
readonly property real fraction: maximum > minimum
? Math.max(0, Math.min(1, (value - minimum) / (maximum - minimum))) : 0
property bool dragging: false
property real dragFraction: fraction
readonly property real shownFraction: dragging ? dragFraction : fraction
onFractionChanged: if (!dragging) dragFraction = fraction
function commit(frac) {
const v = Math.round(minimum + Math.max(0, Math.min(1, frac)) * (maximum - minimum))
if (v !== value) changed(v)
}
Rectangle { // track
x: 0
y: Math.round((parent.height - height) / 2)
width: parent.width
height: 4
radius: 2
color: theme.surfaceElevated
}
Rectangle { // accent fill
x: 0
y: Math.round((parent.height - height) / 2)
width: parent.thumbSize / 2 + parent.shownFraction * parent.travel
height: 4
radius: 2
color: theme.accent
}
Rectangle { // thumb
width: parent.thumbSize
height: parent.thumbSize
radius: parent.thumbSize / 2
x: parent.shownFraction * parent.travel
anchors.verticalCenter: parent.verticalCenter
color: theme.textPrimary
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onPressed: {
parent.dragging = true
parent.dragFraction = Math.max(0, Math.min(1, (mouse.x - parent.thumbSize / 2) / parent.travel))
parent.commit(parent.dragFraction)
}
onPositionChanged: {
if (pressed) {
parent.dragFraction = Math.max(0, Math.min(1, (mouse.x - parent.thumbSize / 2) / parent.travel))
parent.commit(parent.dragFraction)
}
}
onReleased: parent.dragging = false
}
}