From de24bbcf99ba16900193429b2d9d9b3a6fc8e628 Mon Sep 17 00:00:00 2001 From: Reinout Meliesie Date: Sun, 19 Jan 2025 19:03:30 +0100 Subject: [PATCH] Style active sorting in menu, logic for sorting direction --- src/application.css | 8 +++++ src/ui/collatable_container.rs | 2 +- src/ui/collated_grid.rs | 1 + src/ui/collation_menu.rs | 54 ++++++++++++++++++++-------------- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/application.css b/src/application.css index e69de29..7bfb3b9 100644 --- a/src/application.css +++ b/src/application.css @@ -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 ; +} diff --git a/src/ui/collatable_container.rs b/src/ui/collatable_container.rs index c20a850..91911fa 100644 --- a/src/ui/collatable_container.rs +++ b/src/ui/collatable_container.rs @@ -26,7 +26,7 @@ impl CollatableFilmsContainer { pub fn new ( films : Vec ) -> 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) ; } ) ; diff --git a/src/ui/collated_grid.rs b/src/ui/collated_grid.rs index c03ad39..e787ea3 100644 --- a/src/ui/collated_grid.rs +++ b/src/ui/collated_grid.rs @@ -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 ) > > , diff --git a/src/ui/collation_menu.rs b/src/ui/collation_menu.rs index dfe3c36..e259316 100644 --- a/src/ui/collation_menu.rs +++ b/src/ui/collation_menu.rs @@ -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 ( 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 () { - 0 => FilmsSortedBy :: Name , - 1 => FilmsSortedBy :: ReleaseDate , - 2 => FilmsSortedBy :: Runtime , - _ => panic ! () , - } ) ) ; + 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 () +}