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:
72 files changed
+2152
-1690
No files matched your search
@@ -0,0 +1,102 @@
|
||||
// QbzTabBar — the segmented tab pill bar (primitives/SegmentedTabBar
|
||||
// .slint), consolidated in phase 22 from HomeView's discover tab pill and
|
||||
// LibraryView's SegTab row (+ the playlists sub-tab via `compact`).
|
||||
// Arms: `tabs` ([{id, label, count?}]), `activeId`, `counts` (11px count
|
||||
// chip), `underline` (2px accent active cue — the Slint redundant-shape
|
||||
// cue), `compact` (24px mini variant). Emits selected(id); the host owns
|
||||
// side effects (scroll resets, refetches).
|
||||
// Deliberately NOT absorbed (Slint keeps them per-surface too): the
|
||||
// SearchView underline tab strip, QueuePanel's text tabs, ArtistView's
|
||||
// scroll-spy jump links.
|
||||
|
||||
import QtQuick
|
||||
import com.blitzfc.qbz
|
||||
import "../theme"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property var tabs: []
|
||||
property string activeId: ""
|
||||
property bool counts: false
|
||||
property bool underline: false
|
||||
property bool compact: false
|
||||
signal selected(string id)
|
||||
|
||||
QbzTheme { id: theme }
|
||||
|
||||
width: segBarRow.width
|
||||
height: segBarRow.height
|
||||
color: theme.surfaceElevated
|
||||
radius: 6
|
||||
|
||||
Row {
|
||||
id: segBarRow
|
||||
padding: root.compact ? 2 : 3
|
||||
spacing: 4
|
||||
Repeater {
|
||||
model: root.tabs
|
||||
delegate: Rectangle {
|
||||
id: segRoot
|
||||
required property var modelData
|
||||
readonly property bool active: modelData.id === root.activeId
|
||||
readonly property int count: modelData.count || 0
|
||||
|
||||
width: segRow.implicitWidth
|
||||
height: segRow.implicitHeight
|
||||
radius: 4
|
||||
color: active ? theme.surfaceMain
|
||||
: segArea.containsMouse ? theme.surfaceHover : "transparent"
|
||||
|
||||
Row {
|
||||
id: segRow
|
||||
leftPadding: root.compact ? 8 : 12
|
||||
rightPadding: (root.compact ? 8 : 12) - (root.counts && segRoot.count > 0 ? 4 : 0)
|
||||
topPadding: root.compact ? 4 : 6
|
||||
bottomPadding: root.compact ? 4 : 6
|
||||
spacing: 7
|
||||
Text {
|
||||
text: segRoot.modelData.label
|
||||
color: segRoot.active ? theme.textPrimary : theme.textMuted
|
||||
font.pixelSize: root.compact ? 12 : theme.fontLegal
|
||||
font.weight: theme.weightMedium
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Rectangle {
|
||||
visible: root.counts && segRoot.count > 0
|
||||
width: Math.max(18, countText.implicitWidth + 10)
|
||||
height: 16
|
||||
radius: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: segRoot.active ? "#26ffffff" : "#14ffffff"
|
||||
Text {
|
||||
id: countText
|
||||
anchors.centerIn: parent
|
||||
text: segRoot.count
|
||||
color: segRoot.active ? theme.textPrimary : theme.textSecondary
|
||||
font.pixelSize: 11
|
||||
font.weight: theme.weightMedium
|
||||
}
|
||||
}
|
||||
}
|
||||
// Active underline (redundant shape cue, Slint Segment).
|
||||
Rectangle {
|
||||
visible: root.underline && segRoot.active
|
||||
x: 4
|
||||
width: parent.width - 8
|
||||
height: 2
|
||||
y: parent.height - 2
|
||||
radius: 1
|
||||
color: theme.accent
|
||||
}
|
||||
MouseArea {
|
||||
id: segArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.selected(segRoot.modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user