Files
qbz/crates/qbz-slint/ui/shell/NavMenuItem.slint
T
vicrodh 682719cab0 feat(slint): library/sidebar UX overhaul + theme switching + fixes
Shell & navigation:
- Three-state sidebar (open/mini/closed); collapse cycles via header button.
- Section nav as right-flyouts (sidebar) + compact header nav (closed) +
  full header tabs (nav-in-sidebar off), via a shared HeaderMenuOverlay.
- Collapsed-folder right-flyout popup (max 4 + scrollbar), Rust-populated.
- Thin auto-hiding sidebar scrollbar pinned to the edge (Flickable, drag-safe).
- Slack-style bezel: rounded inset content panel over surface-card chrome.
- Header restructure: nav buttons, window-centered search, app menu.

Themes & components:
- Live theme switching: Dark / OLED Black / Tokyo Night / System (std-widgets).
- SegmentedTabBar (Discovery-style) with count badges for Library + Local Library.
- MP3 quality-badge tier (format-first classification) across badges.
- QbzSelect (Group/Sort) trimmed 20px.

Behavior fixes:
- Artist + Local Library Folder cover art now reach the rendered (visible/
  grouped) models, not just the source set.
- Favorites Playlists/Labels random buttons.
- Playlist track click plays from the clicked track in visible order.
- Dropdown idle-close pauses while the cursor rests on the menu.

cc
2026-05-30 15:40:35 -06:00

61 lines
1.8 KiB
Plaintext

// A single row of a header nav-tab dropdown, with an optional leading
// glyph. Shared by HeaderBar (tab definitions) and HeaderMenuOverlay
// (the in-window menu panel that actually renders the rows).
import { Theme } from "../foundation/semantic-colors.slint";
import { QbzIcon } from "../primitives/QbzIcon.slint";
export component NavMenuItem inherits Rectangle {
in property <string> label;
in property <image> icon;
in property <bool> has-glyph: false;
callback clicked();
// Fires whenever the pointer is over the row — drives the dropdown's
// idle-close timer reset.
callback hovered();
// Fires on hover enter/leave so the host keeps the menu open while the
// pointer rests on a row (the idle timer must not close it then).
callback hover-changed(bool);
height: 32px;
background: ta.has-hover ? Theme.surface-hover : transparent;
HorizontalLayout {
padding-left: 14px;
padding-right: 22px;
spacing: 9px;
if root.has-glyph: VerticalLayout {
alignment: center;
QbzIcon {
source: root.icon;
width: 14px;
height: 14px;
tint: Theme.text-secondary;
}
}
Text {
text: root.label;
color: Theme.text-secondary;
font-size: 13px;
vertical-alignment: center;
horizontal-stretch: 1;
}
}
ta := TouchArea {
mouse-cursor: pointer;
clicked => {
root.clicked();
}
changed has-hover => {
root.hover-changed(self.has-hover);
if (self.has-hover) {
root.hovered();
}
}
moved => {
root.hovered();
}
}
}