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
@@ -0,0 +1,85 @@
|
||||
// Right-side Queue panel.
|
||||
//
|
||||
// Rendered as a layout sibling of the content area (see AppShell), so it
|
||||
// shrinks the content rather than overlaying it. Closing sets
|
||||
// ShellState.right-panel = 0. The body is a structural placeholder;
|
||||
// queue contents are wired in a later milestone.
|
||||
|
||||
import { Theme } from "../foundation/semantic-colors.slint";
|
||||
import { Spacing } from "../foundation/spacing.slint";
|
||||
import { Typography } from "../foundation/typography.slint";
|
||||
import { Radius } from "../foundation/radius.slint";
|
||||
import { QbzIcon } from "../primitives/QbzIcon.slint";
|
||||
import { ShellState } from "../state.slint";
|
||||
|
||||
component CloseButton inherits Rectangle {
|
||||
callback clicked();
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: Radius.sm;
|
||||
background: ta.has-hover ? Theme.surface-hover : transparent;
|
||||
|
||||
QbzIcon {
|
||||
source: @image-url("../assets/icons/x.svg");
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
tint: ta.has-hover ? Theme.text-primary : Theme.text-secondary;
|
||||
}
|
||||
|
||||
ta := TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
clicked => {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export component QueueSidebar inherits Rectangle {
|
||||
width: 320px;
|
||||
background: Theme.surface-card;
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 0px;
|
||||
|
||||
// Header row — title + close button.
|
||||
HorizontalLayout {
|
||||
padding-left: Spacing.md;
|
||||
padding-right: Spacing.sm;
|
||||
padding-top: Spacing.sm;
|
||||
padding-bottom: Spacing.sm;
|
||||
height: 44px;
|
||||
Text {
|
||||
text: @tr("Queue");
|
||||
color: Theme.text-primary;
|
||||
font-size: Typography.heading;
|
||||
font-weight: Typography.semibold;
|
||||
vertical-alignment: center;
|
||||
horizontal-stretch: 1;
|
||||
}
|
||||
VerticalLayout {
|
||||
alignment: center;
|
||||
CloseButton {
|
||||
clicked => {
|
||||
ShellState.right-panel = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
background: Theme.border-subtle;
|
||||
}
|
||||
|
||||
// Body — placeholder until queue contents are wired.
|
||||
Rectangle {
|
||||
vertical-stretch: 1;
|
||||
Text {
|
||||
text: @tr("Nothing queued");
|
||||
color: Theme.text-muted;
|
||||
font-size: Typography.body;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user