Files
qbz/crates/qbz-slint/ui/shell/NavButtons.slint
T
vicrodh 12ed5a7c4a feat(slint): browser-like back/forward navigation history
Add a navigation history so pages can be walked back and forward.

- nav.rs: a back/forward stack of NavEntry (home, album, artist,
  settings); record() on fresh navigation, go_back/go_forward to walk it
- NavButtons: a [<] [>] pair styled like the Discover tab group; inline
  beside the Discover tabs and in place of the per-page Back button on
  album, artist and settings views
- All navigation routes through Rust (open-album/-artist record entries;
  the gear and header menu use NavState.request-settings) so the history
  stays accurate; back/forward re-apply entries, re-loading entity pages
- AppShell listens for the mouse back/forward buttons
- can-back / can-forward drive the buttons' enabled state

Also in this round:

- Album header description: render a pre-truncated short string so it
  wraps to a couple of lines instead of overflowing the header; the full
  text stays in the Read-more modal
- Header queue button uses an ordered-list icon (the previous one read
  as a playlist)

cc
2026-05-18 20:17:54 -06:00

67 lines
1.8 KiB
Plaintext

// Browser-like back / forward navigation pair.
//
// Same visual format as the Discover tab pill group (an elevated rounded
// container). Used inline beside the Discover tabs and in place of the
// per-page Back button. Both buttons drive the NavState global, so the
// Rust nav history records every move.
import { Theme } from "../foundation/semantic-colors.slint";
import { NavState } from "../state.slint";
import { QbzIcon } from "../primitives/QbzIcon.slint";
component NavBtn inherits Rectangle {
in property <image> icon;
in property <bool> enabled: true;
callback clicked();
width: 32px;
height: 28px;
border-radius: 4px;
background: ta.has-hover && root.enabled ? Theme.surface-hover : transparent;
opacity: root.enabled ? 1.0 : 0.3;
QbzIcon {
source: root.icon;
width: 15px;
height: 15px;
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
tint: Theme.text-secondary;
}
ta := TouchArea {
mouse-cursor: root.enabled ? pointer : default;
clicked => {
if (root.enabled) {
root.clicked();
}
}
}
}
export component NavButtons inherits Rectangle {
background: Theme.surface-elevated;
border-radius: 6px;
width: btn-row.preferred-width;
height: 34px;
btn-row := HorizontalLayout {
padding: 3px;
spacing: 4px;
NavBtn {
icon: @image-url("../assets/icons/chevron-left.svg");
enabled: NavState.can-back;
clicked => {
NavState.request-back();
}
}
NavBtn {
icon: @image-url("../assets/icons/chevron-right.svg");
enabled: NavState.can-forward;
clicked => {
NavState.request-forward();
}
}
}
}