Files
qbz/crates/qbz-qt/qml/shell/ViewModeMenu.qml
T
vicrodh 9a4fec6b70 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
2026-07-28 11:08:20 -06:00

115 lines
4.1 KiB
QML

// Now-Playing-view mode menu (PlayerBar.slint layout-menu, phase 18) —
// one QbzContextMenu shared by the full PlayerBar and the Small bar:
// New / Classic / Small / Large (with the current mode checked), then the
// inert window-mode rows (Miniplayer / Immersive / Kiosk — the Slint has
// them; the POC has no such surfaces, POC-NOTE).
import QtQuick
import QtQuick.Controls
import com.blitzfc.qbz
import "../controls"
import "../theme"
QbzContextMenu {
id: root
menuWidth: 196
Repeater {
model: [
{ "label": QbzSession.tr("New", QbzSession.trRev), "icon": "panel-left", "mode": 0 },
{ "label": QbzSession.tr("Classic", QbzSession.trRev), "icon": "panel-right-close", "mode": 1 },
{ "label": QbzSession.tr("Small", QbzSession.trRev), "icon": "rows-3", "mode": 2 },
{ "label": QbzSession.tr("Large", QbzSession.trRev), "icon": "layout-grid", "mode": 3 },
]
delegate: Rectangle {
required property var modelData
width: parent ? parent.width : 0
height: 33
radius: 5
color: miArea.containsMouse ? theme.surfaceHover : "transparent"
Row {
anchors.fill: parent
anchors.leftMargin: 8
spacing: 8
QbzIcon {
name: modelData.icon
width: 15
height: 15
anchors.verticalCenter: parent.verticalCenter
tintName: "secondary"
}
Text {
height: parent.height
width: parent.width - 23 - 22
text: modelData.label
color: theme.textSecondary
font.pixelSize: 13
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
QbzIcon {
visible: QbzShell.npbMode === modelData.mode
name: "check"
width: 13
height: 13
anchors.verticalCenter: parent.verticalCenter
tintName: "accent"
}
}
MouseArea {
id: miArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.close()
QbzShell.npbSetMode(modelData.mode)
}
}
}
}
// Divider + the window-mode rows (Miniplayer / Immersive / Kiosk —
// present in the Slint menu; inert in the POC (no such surfaces).
Item {
width: parent ? parent.width : 0
height: 7
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
height: 1
color: theme.borderSubtle
}
}
Repeater {
model: [
{ "label": QbzSession.tr("Miniplayer", QbzSession.trRev), "icon": "picture-in-picture-2" },
{ "label": QbzSession.tr("Immersive", QbzSession.trRev), "icon": "maximize-2" },
{ "label": QbzSession.tr("Kiosk mode", QbzSession.trRev), "icon": "hard-drive" },
]
delegate: Rectangle {
required property var modelData
width: parent ? parent.width : 0
height: 33
radius: 5
opacity: 0.45
color: "transparent"
Row {
anchors.fill: parent
anchors.leftMargin: 8
spacing: 8
QbzIcon { name: modelData.icon; width: 15; height: 15; anchors.verticalCenter: parent.verticalCenter; tintName: "secondary" }
Text {
height: parent.height
text: modelData.label
color: theme.textSecondary
font.pixelSize: 13
verticalAlignment: Text.AlignVCenter
}
}
// Inert (POC-NOTE): no miniplayer/immersive/kiosk surfaces.
}
}
}