feat(slint): A-Z alpha index for the Artists sidepanel left list
The sidepanel left artist list is now always A-Z grouped (derive_artists groups when group-enabled OR view-mode==sidepanel; the view toggle re-derives) with letter headers, and an AlphaStrip on its right edge jumps the list Flickable proportionally (same approach as the album grouping — not exact, by design). Replaces the flat ListView. cc
This commit is contained in:
3 files changed
+44
-10
No files matched your search
@@ -630,7 +630,10 @@ pub fn derive_artists(window: &AppWindow) {
|
||||
let state = window.global::<FavoritesState>();
|
||||
let query_owned = state.get_artists_search().to_lowercase();
|
||||
let query = query_owned.trim();
|
||||
let group = state.get_artists_group_enabled();
|
||||
// The sidepanel left list is ALWAYS A-Z grouped (independent of the grid
|
||||
// group toggle), so it shows letter headers + the alpha jump strip.
|
||||
let group = state.get_artists_group_enabled()
|
||||
|| state.get_artists_view_mode().as_str() == "sidepanel";
|
||||
let all = state.get_artists();
|
||||
|
||||
// Flat (search-filtered) model. Share `all` when no query so artwork
|
||||
|
||||
@@ -4403,6 +4403,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if v == "grid" {
|
||||
st.set_selected_artist_id("".into());
|
||||
}
|
||||
// Rebuild grouped/alpha for the new mode (the sidepanel
|
||||
// left list is always grouped).
|
||||
favorites::derive_artists(&w);
|
||||
favorites_prefs::save(&w);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1368,20 +1368,48 @@ export component FavoritesView inherits Rectangle {
|
||||
padding-top: 16px;
|
||||
spacing: 0px;
|
||||
|
||||
// LEFT: the favorites artist list (self-scrolling).
|
||||
// LEFT: the favorites artist list, A-Z grouped, with a
|
||||
// proportional alpha jump strip (like the album grouping).
|
||||
Rectangle {
|
||||
width: 300px;
|
||||
ListView {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
for artist[i] in FavoritesState.artists-visible: SidepanelArtistRow {
|
||||
item: artist;
|
||||
selected: FavoritesState.selected-artist-id == artist.id;
|
||||
clicked(id, name) => {
|
||||
FavoritesActions.select-artist(id, name);
|
||||
clip: true;
|
||||
left-flick := Flickable {
|
||||
viewport-width: self.width;
|
||||
viewport-height: left-col.preferred-height;
|
||||
left-col := VerticalLayout {
|
||||
width: parent.width;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 40px;
|
||||
padding-right: 22px;
|
||||
spacing: 4px;
|
||||
alignment: start;
|
||||
for section[s] in FavoritesState.artists-grouped: VerticalLayout {
|
||||
spacing: 2px;
|
||||
Text {
|
||||
text: section.title;
|
||||
color: Theme.text-secondary;
|
||||
font-size: Typography.legal;
|
||||
font-weight: Typography.semibold;
|
||||
}
|
||||
for artist[i] in section.artists: SidepanelArtistRow {
|
||||
item: artist;
|
||||
selected: FavoritesState.selected-artist-id == artist.id;
|
||||
clicked(id, name) => {
|
||||
FavoritesActions.select-artist(id, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if FavoritesState.artists-alpha.length > 0: AlphaStrip {
|
||||
x: parent.width - self.width - 2px;
|
||||
height: 100%;
|
||||
jumps: FavoritesState.artists-alpha;
|
||||
jump(ord, idx) => {
|
||||
left-flick.viewport-y = -(ord / Math.max(1, FavoritesState.artists-alpha.length - 1))
|
||||
* Math.max(0, (left-flick.viewport-height - left-flick.height) / 1px) * 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: 1px;
|
||||
|
||||
Reference in new issue
Block a user