diff --git a/src/ui/components/collatable_media_grid/collatable_film_grid.rs b/src/ui/components/collatable_media_grid/collatable_film_grid.rs index 763d2ff..bca8f53 100644 --- a/src/ui/components/collatable_media_grid/collatable_film_grid.rs +++ b/src/ui/components/collatable_media_grid/collatable_film_grid.rs @@ -44,6 +44,9 @@ impl SimpleComponent for CollatableFilmGrid { FilmCollationMenuOutput::ApplyWatchedFilter(watched_filter) => { FilmGridInput::ApplyWatchedFilter(watched_filter) } + FilmCollationMenuOutput::ApplyNameFilter(name_filter) => { + FilmGridInput::ApplyNameFilter(name_filter) + } }, ); diff --git a/src/ui/components/media_collation_menu/film_collation_menu.rs b/src/ui/components/media_collation_menu/film_collation_menu.rs index fa8ef9a..cd77847 100644 --- a/src/ui/components/media_collation_menu/film_collation_menu.rs +++ b/src/ui/components/media_collation_menu/film_collation_menu.rs @@ -1,5 +1,5 @@ use gtk4::prelude::{ - BoxExt, ButtonExt, EntryExt, ListBoxRowExt, ObjectExt, OrientableExt, PopoverExt, + BoxExt, ButtonExt, EditableExt, EntryExt, ListBoxRowExt, ObjectExt, OrientableExt, PopoverExt, ToggleButtonExt, WidgetExt, }; use gtk4::{Align, Button, Entry, Label, ListBox, MenuButton, Orientation, Popover, ToggleButton}; @@ -24,12 +24,14 @@ pub enum FilmCollationMenuInput { ToggleSortOrder, ToggleWatchedFilter, ToggleUnwatchedFilter, + NameFilterSet(String), } #[derive(Debug)] pub enum FilmCollationMenuOutput { SortBy(FilmsSorting, SortingDirection), ApplyWatchedFilter(Option), + ApplyNameFilter(Option), } #[component(pub)] @@ -102,6 +104,10 @@ impl SimpleComponent for FilmCollationMenu { set_placeholder_text: Some("Search"), set_secondary_icon_name: Some("system-search-symbolic"), set_secondary_icon_sensitive: false, + + connect_changed[sender] => move |entry| { + sender.input(FilmCollationMenuInput::NameFilterSet(entry.text().to_string())); + }, }, gtk4::Box { @@ -194,6 +200,13 @@ impl SimpleComponent for FilmCollationMenu { self.watched_filter, )); } + FilmCollationMenuInput::NameFilterSet(name_filter) => { + if name_filter.is_empty() { + sender.emit_output(FilmCollationMenuOutput::ApplyNameFilter(None)); + } else { + sender.emit_output(FilmCollationMenuOutput::ApplyNameFilter(Some(name_filter))); + } + } } } } diff --git a/src/ui/components/media_grid/film_grid.rs b/src/ui/components/media_grid/film_grid.rs index ed3653d..5c7b52d 100644 --- a/src/ui/components/media_grid/film_grid.rs +++ b/src/ui/components/media_grid/film_grid.rs @@ -22,6 +22,7 @@ pub struct FilmGrid { pub enum FilmGridInput { SortBy(FilmsSorting, SortingDirection), ApplyWatchedFilter(Option), + ApplyNameFilter(Option), } #[derive(Debug)] @@ -82,6 +83,8 @@ impl Component for FilmGrid { _sender: ComponentSender, _root: &ScrolledWindow, ) { + // TODO: Make combining filters work properly or, indeed, at all. + match message { FilmGridInput::SortBy(sorting, direction) => { let mut items = self.items.guard(); @@ -121,6 +124,26 @@ impl Component for FilmGrid { self.items.broadcast(FilmGridItemInput::SetVisible(true)); } }, + FilmGridInput::ApplyNameFilter(name_filter) => match name_filter { + Some(name_filter) => { + let name_filter = name_filter.to_lowercase(); + for (index, item) in self.items.iter().enumerate() { + let name = item.film().name.to_lowercase(); + let name_matches = name.contains(name_filter.as_str()); + let orig_name = item.film().original_name.as_deref().map(str::to_lowercase); + let orig_name_matches = + orig_name.is_some_and(|orig_name| orig_name.contains(name_filter.as_str())); + if name_matches || orig_name_matches { + self.items.send(index, FilmGridItemInput::SetVisible(true)); + } else { + self.items.send(index, FilmGridItemInput::SetVisible(false)); + } + } + } + None => { + self.items.broadcast(FilmGridItemInput::SetVisible(true)); + } + }, } }