feat(slint): collapsible sidebar, Queue/Lyrics panels, nav menus
Shell chrome (steps 1-3): - Left sidebar is collapsible — a toggle in the nav cluster (left of the [<] [>] pair) and a draggable right edge that resizes 200-420px and collapses below 160px. ShellState global drives it. - Queue and Lyrics right sidebars: 320px panels rendered as layout siblings, so opening one pushes the content area narrower rather than overlaying it. The header captions/queue buttons toggle them (mutually exclusive) and light up when active. - The four nav tabs (Discover/Library/Local Library/My QBZ) open dropdown menus listing their sub-sections; Discover -> Home is wired. Detail views (steps 4-5): - Track rows: the even-row tint is now clearly fainter than the hover tint so the two states no longer look identical. - The favorite and offline-cache glyphs in album track rows are real buttons (hover state, emit media-action). - Album header artist link uses the metadata text color, bold, instead of the accent blue. - Album description and artist biography span the full content width below the header block. cc
This commit is contained in:
10 files changed
+461
-80
No files matched your search
@@ -3,18 +3,31 @@
|
||||
// The playlist list is empty until real playlist data is wired (the
|
||||
// sidebar is a later milestone). The user element now lives in the
|
||||
// header, not at the bottom of the sidebar.
|
||||
//
|
||||
// The sidebar is collapsible: its rendered width is driven by
|
||||
// ShellState (0px when collapsed, otherwise the user-set width). A thin
|
||||
// drag handle on the right edge resizes it, clamped to [200px, 420px];
|
||||
// dragging below ~160px collapses it entirely.
|
||||
|
||||
import { Theme } from "../foundation/semantic-colors.slint";
|
||||
import { Spacing } from "../foundation/spacing.slint";
|
||||
import { Layout } from "../foundation/layout.slint";
|
||||
import { QbzIcon } from "../primitives/QbzIcon.slint";
|
||||
import { ShellState } from "../state.slint";
|
||||
import { ScrollView } from "std-widgets.slint";
|
||||
|
||||
export component Sidebar inherits Rectangle {
|
||||
width: Layout.sidebar-width;
|
||||
// Rendered width — 0 when collapsed, otherwise the user-set width.
|
||||
width: ShellState.sidebar-collapsed ? 0px : ShellState.sidebar-width;
|
||||
// The sidebar sits one surface above the content area, matching the
|
||||
// QBZ dark theme (--bg-secondary sidebar over --bg-primary content).
|
||||
background: Theme.surface-card;
|
||||
// Clip so content doesn't spill while the width animates to 0.
|
||||
clip: true;
|
||||
animate width { duration: 160ms; easing: ease-in-out; }
|
||||
|
||||
// Captured sidebar width at pointer-down, so drag deltas are
|
||||
// measured from a stable origin.
|
||||
property <length> drag-start-width: ShellState.sidebar-width;
|
||||
|
||||
VerticalLayout {
|
||||
padding: Spacing.md;
|
||||
@@ -22,7 +35,7 @@ export component Sidebar inherits Rectangle {
|
||||
|
||||
HorizontalLayout {
|
||||
Text {
|
||||
text: "PLAYLISTS";
|
||||
text: @tr("PLAYLISTS");
|
||||
color: Theme.text-muted;
|
||||
font-size: 11px;
|
||||
letter-spacing: 1.5px;
|
||||
@@ -50,4 +63,30 @@ export component Sidebar inherits Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drag handle — a thin strip pinned to the right edge. Resizes the
|
||||
// sidebar; below ~160px it collapses instead of resizing.
|
||||
drag-handle := TouchArea {
|
||||
x: parent.width - self.width;
|
||||
width: 6px;
|
||||
height: parent.height;
|
||||
mouse-cursor: ew-resize;
|
||||
|
||||
pointer-event(e) => {
|
||||
if (e.kind == PointerEventKind.down) {
|
||||
root.drag-start-width = ShellState.sidebar-width;
|
||||
}
|
||||
}
|
||||
moved => {
|
||||
if (self.pressed) {
|
||||
if (root.drag-start-width + (self.mouse-x - self.pressed-x) < 160px) {
|
||||
ShellState.sidebar-collapsed = true;
|
||||
} else {
|
||||
ShellState.sidebar-width = Math.min(Math.max(
|
||||
root.drag-start-width + (self.mouse-x - self.pressed-x),
|
||||
200px), 420px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user