Style active sorting in menu, logic for sorting direction

This commit is contained in:
Reinout Meliesie 2025-01-19 19:03:30 +01:00
parent 6b0be30adc
commit de24bbcf99
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
4 changed files with 42 additions and 23 deletions

View file

@ -0,0 +1,8 @@
/* TODO: Switch out CSS dynamically on `gtk-application-prefer-dark-theme` property change */
#film-collation-menu row:selected {
background-color : rgb( 0 0 0 / 0.08 ) ;
}
#film-collation-menu row:not(:selected) image {
opacity : 0 ;
}

View file

@ -26,7 +26,7 @@ impl CollatableFilmsContainer {
pub fn new ( films : Vec <Film> ) -> Self {
let collated_grid = leak (
CollatedFilmsGrid :: new ( films , FilmsSortedBy :: Name ) ) ;
let film_collation_menu = FilmCollationMenu :: new ( |sorted_by| {
let film_collation_menu = FilmCollationMenu :: new ( | sorted_by , direction | {
collated_grid . set_sorting (sorted_by) ;
} ) ;

View file

@ -15,6 +15,7 @@ use crate :: { collection :: * , ui :: component :: * } ;
pub enum FilmsSortedBy { Name , ReleaseDate , Runtime }
pub enum SeriesSortedBy { Name , FirstReleaseDate }
pub enum SortingDirection { Ascending , Descending }
pub struct CollatedFilmsGrid {
film_widget_pairs : RefCell < Vec < ( Film , Box ) > > ,

View file

@ -6,33 +6,39 @@ use {
prelude :: * ,
} ,
libadwaita :: * ,
std :: cell :: * ,
} ;
use crate :: ui :: { collated_grid :: * , component :: * , utility :: * } ;
pub struct FilmCollationMenu { widget : Box }
pub struct FilmCollationMenu {
widget : Box ,
sorting : RefCell < ( FilmsSortedBy , SortingDirection ) > ,
}
pub struct SeriesCollationMenu { widget : Box }
impl FilmCollationMenu {
pub fn new < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F ) -> Self {
pub fn new < F : Fn ( FilmsSortedBy , SortingDirection ) + 'static > ( on_sort : F ) -> Self {
let widget = Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. name ("film-collation-menu")
. css_classes ( ["toolbar"] )
. build () ;
widget . append ( & create_sort_button ( & create_films_sort_menu (on_sort) ) ) ;
widget . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
widget . append ( & create_filter_button () ) ;
Self { widget }
let sorting = RefCell :: new ( ( FilmsSortedBy :: Name , SortingDirection :: Ascending ) ) ;
Self { widget , sorting }
}
}
impl SeriesCollationMenu {
pub fn new <F> ( on_sort : F ) -> Self
where F : Fn (SeriesSortedBy) + 'static {
pub fn new < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F ) -> Self {
let widget = Box :: builder ()
. orientation (Horizontal)
. halign (Center)
@ -61,21 +67,24 @@ fn create_sort_button ( sort_menu : & Popover ) -> SplitButton {
. build ()
}
fn create_films_sort_menu < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F ) -> Popover {
fn create_films_sort_menu < F : Fn ( FilmsSortedBy , SortingDirection ) + 'static > ( on_sort : F ) -> Popover {
let container = ListBox :: new () ;
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;
container . append ( & create_sort_menu_entry ( "Release date" , false , false ) ) ;
container . append ( & create_sort_menu_entry ( "Runtime" , false , false ) ) ;
container . append ( & create_sort_menu_entry ( "Name" , false ) ) ;
container . append ( & create_sort_menu_entry ( "Release date" , false ) ) ;
container . append ( & create_sort_menu_entry ( "Runtime" , false ) ) ;
container . select_row ( container . row_at_index (0) . as_ref () ) ;
container . connect_row_activated ( move | _ , row | on_sort ( match row . index () {
container . connect_row_activated ( move | _ , row | on_sort (
match row . index () {
0 => FilmsSortedBy :: Name ,
1 => FilmsSortedBy :: ReleaseDate ,
2 => FilmsSortedBy :: Runtime ,
_ => panic ! () ,
} ) ) ;
} ,
SortingDirection :: Ascending ,
) ) ;
Popover :: builder ()
. child ( & container )
@ -85,8 +94,8 @@ fn create_films_sort_menu < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F ) -
fn create_series_sort_menu < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F ) -> Popover {
let container = ListBox :: new () ;
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;
container . append ( & create_sort_menu_entry ( "First release date" , false , false ) ) ;
container . append ( & create_sort_menu_entry ( "Name" , false ) ) ;
container . append ( & create_sort_menu_entry ( "First release date" , false ) ) ;
container . select_row ( container . row_at_index (0) . as_ref () ) ;
@ -102,12 +111,11 @@ fn create_series_sort_menu < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F )
. build ()
}
fn create_sort_menu_entry ( label : & str , reverse : bool , selected : bool ) -> ListBoxRow {
fn create_sort_menu_entry ( label : & str , reverse : bool ) -> ListBoxRow {
let icon = match reverse {
false => Image :: from_icon_name ("view-sort-ascending-symbolic") ,
true => Image :: from_icon_name ("view-sort-descending-symbolic") ,
} ;
if ! selected { icon . set_opacity (0.0) }
let container = create_horizontal_box ! (
& Label :: builder ()
@ -119,7 +127,9 @@ fn create_sort_menu_entry ( label : & str , reverse : bool , selected : bool ) -
) ;
container . set_spacing (20) ;
// TODO : Highlight `:selected` row using CSS, parent with `.menu` prevents default behaviour
ListBoxRow :: builder () . child ( & container ) . build ()
}
fn create_filter_button () -> SplitButton {
SplitButton :: builder () . label ("Filter") . build ()
}