diff --git a/src/application.css b/src/application.css index 7bfb3b9..09ba739 100644 --- a/src/application.css +++ b/src/application.css @@ -2,7 +2,13 @@ #film-collation-menu row:selected { background-color : rgb( 0 0 0 / 0.08 ) ; } +#series-collation-menu row:selected { + background-color : rgb( 0 0 0 / 0.08 ) ; +} #film-collation-menu row:not(:selected) image { opacity : 0 ; } +#series-collation-menu row:not(:selected) image { + opacity : 0 ; +} diff --git a/src/ui/collatable_container/collated_grid.rs b/src/ui/collatable_container/collated_grid.rs index 1584b8f..3cc49c4 100644 --- a/src/ui/collatable_container/collated_grid.rs +++ b/src/ui/collatable_container/collated_grid.rs @@ -107,10 +107,14 @@ impl CollatedSeriesGrid { self . series_widget_pairs . borrow () . as_slice () ) ; sorted . sort_by ( | ( series_1 , _ ) , ( series_2 , _ ) | match sorting . property { - SeriesProperty :: Name => series_1 . name . cmp ( & series_2 . name ) , - SeriesProperty :: FirstReleaseDate => todo ! () , + SeriesProperty :: Name => + series_1 . name . cmp ( & series_2 . name ) , + SeriesProperty :: FirstReleaseDate => + todo ! () , } ) ; + if sorting . direction == SortingDirection :: Descending { sorted . reverse () } + // See it, say it, ... sorted } } diff --git a/src/ui/collatable_container/collation_menu/mod.rs b/src/ui/collatable_container/collation_menu/mod.rs index 1107928..6673be3 100644 --- a/src/ui/collatable_container/collation_menu/mod.rs +++ b/src/ui/collatable_container/collation_menu/mod.rs @@ -1,12 +1,7 @@ mod sort_button ; use { - gtk4 :: { - Box , Image , Label , ListBox , ListBoxRow , Popover , - Align :: * , Orientation :: * , - prelude :: * , - } , - libadwaita :: * , + gtk4 :: { Box , Align :: * , Orientation :: * , prelude :: * } , std :: ops :: * , } ; @@ -38,15 +33,16 @@ impl FilmCollationMenu { } impl SeriesCollationMenu { pub fn new < F : Fn (SeriesSorting) + 'static > ( on_sort : F ) -> Self { - let widget = Box :: builder () - . orientation (Horizontal) - . halign (Center) - . spacing (20) - . css_classes ( ["toolbar"] ) - . build () ; + let series_sort_button = SeriesSortButton :: new (on_sort) ; - widget . append ( & create_sort_button ( & create_series_sort_menu (on_sort) ) ) ; - widget . append ( & SplitButton :: builder () . label ("Filter") . build () ) ; + let widget = g_box ! ( + @ orientation : Horizontal , + @ halign : Center , + @ spacing : 20 , + @ widget_name : "series-collation-menu" , + @ css_classes : [ "toolbar" ] , + * series_sort_button . get_widget () , + ) ; Self { widget } } @@ -58,81 +54,3 @@ impl Component for FilmCollationMenu { impl Component for SeriesCollationMenu { fn get_widget ( & self ) -> & Box { & self . widget } } - -fn create_sort_button ( sort_menu : & Popover ) -> SplitButton { - SplitButton :: builder () - . child ( & label ! ("Sort") ) - . popover (sort_menu) - . build () -} - -fn create_films_sort_menu < F : Fn (FilmsSorting) + 'static > ( on_sort : F ) -> Popover { - let container = ListBox :: new () ; - - 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 | { - let sorting_property = match row . index () { - 0 => FilmProperty :: Name , - 1 => FilmProperty :: ReleaseDate , - 2 => FilmProperty :: Runtime , - _ => panic ! () , - } ; - on_sort ( FilmsSorting :: new ( sorting_property , SortingDirection :: Ascending ) ) ; - } ) ; - - Popover :: builder () - . child ( & container ) - . css_classes ( ["menu"] ) - . build () -} -fn create_series_sort_menu < F : Fn (SeriesSorting) + 'static > ( on_sort : F ) -> Popover { - let container = ListBox :: new () ; - - 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 () ) ; - - container . connect_row_activated ( move | _ , row | { - let sorting_property = match row . index () { - 0 => SeriesProperty :: Name , - 1 => SeriesProperty :: FirstReleaseDate , - _ => panic ! () , - } ; - on_sort ( SeriesSorting :: new ( sorting_property , SortingDirection :: Ascending ) ) ; - } ) ; - - Popover :: builder () - . child ( & container ) - . css_classes ( ["menu"] ) - . build () -} - -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") , - } ; - - let container = g_box ! ( - @ orientation : Horizontal , - Label :: builder () - . label (label) - . hexpand (true) - . halign (Start) - . build () , - icon , - ) ; - container . set_spacing (20) ; - - ListBoxRow :: builder () . child ( & container ) . build () -} - -fn create_filter_button () -> SplitButton { - SplitButton :: builder () . label ("Filter") . build () -} diff --git a/src/ui/collatable_container/collation_menu/sort_button.rs b/src/ui/collatable_container/collation_menu/sort_button.rs index 602b882..90d3d3e 100644 --- a/src/ui/collatable_container/collation_menu/sort_button.rs +++ b/src/ui/collatable_container/collation_menu/sort_button.rs @@ -11,6 +11,10 @@ pub struct FilmSortButton { widget : SplitButton , previous_sorting : & 'static RefCell , } +pub struct SeriesSortButton { + widget : SplitButton , + previous_sorting : & 'static RefCell , +} impl FilmSortButton { pub fn new < F : Fn (FilmsSorting) + 'static > ( on_sort : F ) -> Self { @@ -21,7 +25,7 @@ impl FilmSortButton { @ css_classes : [ "menu" ] , list_box ! ( @ connect_row_activated : move | _ , row | { - on_row_activated ( row , previous_sorting , & on_sort ) ; + on_film_sort_activated ( row , previous_sorting , & on_sort ) ; } , g_box ! ( @ orientation : Horizontal , @ spacing : 20 , @@ -46,12 +50,44 @@ impl FilmSortButton { Self { widget , previous_sorting } } } +impl SeriesSortButton { + pub fn new < F : Fn (SeriesSorting) + 'static > ( on_sort : F ) -> Self { + let previous_sorting = leak ( RefCell :: new ( SeriesSorting :: default () ) ) ; + + let widget = split_button ! ( + @ popover : popover ! ( + @ css_classes : [ "menu" ] , + list_box ! ( + @ connect_row_activated : move | _ , row | { + on_series_sort_activated ( row , previous_sorting , & on_sort ) ; + } , + g_box ! ( + @ orientation : Horizontal , @ spacing : 20 , + label ! ( @ hexpand : true , @ halign : Start , "Name" ) , + icon ! ("view-sort-ascending-symbolic") , + ) , + g_box ! ( + @ orientation : Horizontal , @ spacing : 20 , + label ! ( @ hexpand : true , @ halign : Start , "First release date" ) , + icon ! ("view-sort-ascending-symbolic") , + ) , + ) , + ) , + label ! ("Sort") , + ) ; + + Self { widget , previous_sorting } + } +} impl Component for FilmSortButton { fn get_widget ( & self ) -> & SplitButton { & self . widget } } +impl Component for SeriesSortButton { + fn get_widget ( & self ) -> & SplitButton { & self . widget } +} -fn on_row_activated < F : Fn (FilmsSorting) > ( +fn on_film_sort_activated < F : Fn (FilmsSorting) > ( row : & ListBoxRow , previous_sorting : & RefCell , on_sort : & F , @@ -80,3 +116,31 @@ fn on_row_activated < F : Fn (FilmsSorting) > ( on_sort ( FilmsSorting :: new ( sorting_property , Ascending ) ) ; } } +fn on_series_sort_activated < F : Fn (SeriesSorting) > ( + row : & ListBoxRow , + previous_sorting : & RefCell , + on_sort : & F , +) { + let sorting_property = match row . index () { + 0 => SeriesProperty :: Name , + 1 => SeriesProperty :: FirstReleaseDate , + _ => panic ! () , + } ; + + if sorting_property == previous_sorting . borrow () . property { + let previous_sorting_direction = previous_sorting . borrow () . direction ; + match previous_sorting_direction { + Ascending => { + previous_sorting . replace ( SeriesSorting :: new ( sorting_property , Descending ) ) ; + on_sort ( SeriesSorting :: new ( sorting_property , Descending ) ) ; + } , + Descending => { + previous_sorting . replace ( SeriesSorting :: new ( sorting_property , Ascending ) ) ; + on_sort ( SeriesSorting :: new ( sorting_property , Ascending ) ) ; + } , + } + } else { + previous_sorting . replace ( SeriesSorting :: new ( sorting_property , Ascending ) ) ; + on_sort ( SeriesSorting :: new ( sorting_property , Ascending ) ) ; + } +} diff --git a/src/ui/collatable_container/mod.rs b/src/ui/collatable_container/mod.rs index 24e3abd..4021729 100644 --- a/src/ui/collatable_container/mod.rs +++ b/src/ui/collatable_container/mod.rs @@ -79,14 +79,17 @@ impl CollatableSeriesContainer { pub fn new ( series : Vec ) -> Self { let collated_grid = leak ( CollatedSeriesGrid :: new ( series , SeriesSorting :: default () ) ) ; - let series_collation_menu = SeriesCollationMenu :: new ( |sorted_by| { - collated_grid . set_sorting (sorted_by) ; + let series_collation_menu = SeriesCollationMenu :: new ( |sorting| { + collated_grid . set_sorting (sorting) ; } ) ; let widget = g_box ! ( @ orientation : Vertical , * series_collation_menu . get_widget () , - create_collection_scrolled_window ( collated_grid . get_widget () ) , + scrolled_window ! ( + @ propagate_natural_height : true , + vertically_filling ! ( * collated_grid . get_widget () ) , + ) , ) ; Self { collated_grid , widget } @@ -103,10 +106,3 @@ impl Component for CollatableFilmsContainer { impl Component for CollatableSeriesContainer { fn get_widget ( & self ) -> & Box { & self . widget } } - -fn create_collection_scrolled_window ( child : & FlowBox ) -> ScrolledWindow { - ScrolledWindow :: builder () - . child ( & vertically_filling ! ( * child ) ) - . propagate_natural_height (true) - . build () -}