Fully deduplicate shared logic between films and series
This commit is contained in:
parent
c3dfa5b459
commit
c3e2bd0f69
10 changed files with 275 additions and 452 deletions
|
|
@ -1,9 +1,11 @@
|
|||
mod collated_grid ;
|
||||
mod collation_menu ;
|
||||
|
||||
use gtk4 :: * ;
|
||||
use gtk4 :: Box ;
|
||||
use gtk4 :: Orientation :: * ;
|
||||
use gtk4 :: prelude :: * ;
|
||||
use std :: cmp :: * ;
|
||||
use std :: fmt :: * ;
|
||||
|
||||
use crate :: data_manager :: * ;
|
||||
use crate :: ui :: component :: * ;
|
||||
|
|
@ -14,28 +16,40 @@ use crate :: utility :: * ;
|
|||
|
||||
|
||||
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum FilmProperty { Name , ReleaseDate , Runtime }
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum SeriesProperty { Name , FirstReleaseDate }
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum SortingDirection { Ascending , Descending }
|
||||
pub trait MediaSorting < P : MediaProperty > : Clone + Copy + Debug + Default {
|
||||
fn new ( property : P , direction : SortingDirection ) -> Self ;
|
||||
fn get_property ( & self ) -> P ;
|
||||
fn get_direction ( & self ) -> SortingDirection ;
|
||||
}
|
||||
|
||||
# [ derive ( Clone , Copy ) ] pub struct FilmsSorting {
|
||||
pub trait MediaProperty : Clone + Copy + Debug + PartialEq {}
|
||||
|
||||
# [ derive ( Clone , Copy , Debug , PartialEq ) ] pub enum FilmProperty { Name , ReleaseDate , Runtime }
|
||||
# [ derive ( Clone , Copy , Debug , PartialEq ) ] pub enum SeriesProperty { Name , FirstReleaseDate }
|
||||
# [ derive ( Clone , Copy , Debug , PartialEq ) ] pub enum SortingDirection { Ascending , Descending }
|
||||
|
||||
# [ derive ( Clone , Copy , Debug ) ] pub struct FilmsSorting {
|
||||
property : FilmProperty ,
|
||||
direction : SortingDirection ,
|
||||
}
|
||||
# [ derive ( Clone , Copy ) ] pub struct SeriesSorting {
|
||||
# [ derive ( Clone , Copy , Debug ) ] pub struct SeriesSorting {
|
||||
property : SeriesProperty ,
|
||||
direction : SortingDirection ,
|
||||
}
|
||||
|
||||
impl FilmsSorting {
|
||||
pub fn new ( property : FilmProperty , direction : SortingDirection ) -> Self {
|
||||
impl MediaSorting <FilmProperty> for FilmsSorting {
|
||||
fn new ( property : FilmProperty , direction : SortingDirection ) -> Self {
|
||||
Self { property , direction }
|
||||
}
|
||||
fn get_property ( & self ) -> FilmProperty { self . property }
|
||||
fn get_direction ( & self ) -> SortingDirection { self . direction }
|
||||
}
|
||||
impl SeriesSorting {
|
||||
pub fn new ( property : SeriesProperty , direction : SortingDirection ) -> Self {
|
||||
impl MediaSorting <SeriesProperty> for SeriesSorting {
|
||||
fn new ( property : SeriesProperty , direction : SortingDirection ) -> Self {
|
||||
Self { property , direction }
|
||||
}
|
||||
fn get_property ( & self ) -> SeriesProperty { self . property }
|
||||
fn get_direction ( & self ) -> SortingDirection { self . direction }
|
||||
}
|
||||
|
||||
impl Default for FilmsSorting {
|
||||
|
|
@ -51,65 +65,110 @@ impl Default for SeriesSorting {
|
|||
} }
|
||||
}
|
||||
|
||||
impl MediaProperty for FilmProperty {}
|
||||
impl MediaProperty for SeriesProperty {}
|
||||
|
||||
|
||||
pub struct CollatableFilmsContainer {
|
||||
collated_grid : & 'static CollatedFilmsGrid ,
|
||||
widget : Box ,
|
||||
}
|
||||
pub struct CollatableSeriesContainer {
|
||||
collated_grid : & 'static CollatedSeriesGrid ,
|
||||
pub struct CollatableMediaContainer < A : MediaAdapter + 'static > {
|
||||
collated_grid : & 'static CollatedMediaGrid <A> ,
|
||||
widget : Box ,
|
||||
}
|
||||
|
||||
impl CollatableFilmsContainer {
|
||||
impl < A : MediaAdapter > CollatableMediaContainer <A> {
|
||||
pub fn new () -> Self {
|
||||
let collated_grid = leak ( CollatedFilmsGrid :: new () ) ;
|
||||
let film_collation_menu = FilmCollationMenu :: new ( |sorting|
|
||||
collated_grid . set_sorting (sorting) ) ;
|
||||
let collated_grid = leak ( CollatedMediaGrid :: new () ) ;
|
||||
let collation_menu = MediaCollationMenu :: new :: <A> ( |sorting|
|
||||
collated_grid . set_sorting (sorting) ,
|
||||
) ;
|
||||
|
||||
let widget = g_box ! (
|
||||
@ orientation : Vertical ;
|
||||
film_collation_menu . get_widget () ,
|
||||
collation_menu . get_widget () ,
|
||||
& scrolled_window ! (
|
||||
@ propagate_natural_height : true ;
|
||||
& vertically_filling ! ( collated_grid . get_widget () ) ,
|
||||
) ,
|
||||
) ;
|
||||
|
||||
Self { collated_grid , widget }
|
||||
Self { collated_grid, widget }
|
||||
}
|
||||
|
||||
pub async fn set_films ( & self , films : Vec <FilmOverview> ) {
|
||||
self . collated_grid . set_films ( films , FilmsSorting :: default () ) . await ;
|
||||
}
|
||||
}
|
||||
impl CollatableSeriesContainer {
|
||||
pub fn new () -> Self {
|
||||
let collated_grid = leak ( CollatedSeriesGrid :: new () ) ;
|
||||
let series_collation_menu = SeriesCollationMenu :: new ( |sorting|
|
||||
collated_grid . set_sorting (sorting) ) ;
|
||||
|
||||
let widget = g_box ! (
|
||||
@ orientation : Vertical ;
|
||||
series_collation_menu . get_widget () ,
|
||||
& scrolled_window ! (
|
||||
@ propagate_natural_height : true ;
|
||||
& vertically_filling ! ( collated_grid . get_widget () ) ,
|
||||
) ,
|
||||
) ;
|
||||
|
||||
Self { collated_grid , widget }
|
||||
}
|
||||
|
||||
pub async fn set_series ( & self , series : Vec <SeriesOverview> ) {
|
||||
self . collated_grid . set_series ( series , SeriesSorting :: default () ) . await ;
|
||||
pub async fn set_media ( & self , media : Vec < A :: Overview > ) {
|
||||
self . collated_grid . set_media ( media , A :: Sorting :: default () ) . await ;
|
||||
}
|
||||
}
|
||||
|
||||
impl Component <Box> for CollatableFilmsContainer {
|
||||
pub trait MediaAdapter {
|
||||
type Overview : MediaOverview ;
|
||||
type Sorting : MediaSorting < Self :: Property > ;
|
||||
type Property : MediaProperty ;
|
||||
fn compare_by (
|
||||
media_1 : & Self :: Overview ,
|
||||
media_2 : & Self :: Overview ,
|
||||
sorting : Self :: Sorting ,
|
||||
) -> Ordering ;
|
||||
fn get_property_descriptions () -> & 'static [ ( Self :: Property , & 'static str ) ] ;
|
||||
}
|
||||
|
||||
impl < A : MediaAdapter > Component for CollatableMediaContainer <A> {
|
||||
fn get_widget ( & self ) -> & Box { & self . widget }
|
||||
}
|
||||
impl Component <Box> for CollatableSeriesContainer {
|
||||
fn get_widget ( & self ) -> & Box { & self . widget }
|
||||
|
||||
pub struct FilmsAdapter {}
|
||||
pub struct SeriesAdapter {}
|
||||
|
||||
impl MediaAdapter for FilmsAdapter {
|
||||
type Overview = FilmOverview ;
|
||||
type Sorting = FilmsSorting ;
|
||||
type Property = FilmProperty ;
|
||||
|
||||
fn compare_by (
|
||||
film_1 : & FilmOverview ,
|
||||
film_2 : & FilmOverview ,
|
||||
sorting : FilmsSorting ,
|
||||
) -> Ordering {
|
||||
let ordering = match sorting . property {
|
||||
FilmProperty :: Name => film_1 . name . cmp ( & film_2 . name ) ,
|
||||
FilmProperty :: ReleaseDate => film_1 . release_date . cmp ( & film_2 . release_date ) ,
|
||||
FilmProperty :: Runtime => film_1 . runtime_minutes . cmp ( & film_2 . runtime_minutes ) ,
|
||||
} ;
|
||||
match sorting . direction {
|
||||
SortingDirection :: Ascending => ordering ,
|
||||
SortingDirection :: Descending => ordering . reverse () ,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property_descriptions () -> & 'static [ ( FilmProperty , & 'static str ) ] {
|
||||
leak ( [
|
||||
( FilmProperty :: Name , "Name" ) ,
|
||||
( FilmProperty :: ReleaseDate , "Release date" ) ,
|
||||
( FilmProperty :: Runtime , "Runtime" ) ,
|
||||
] )
|
||||
}
|
||||
}
|
||||
impl MediaAdapter for SeriesAdapter {
|
||||
type Overview = SeriesOverview ;
|
||||
type Sorting = SeriesSorting ;
|
||||
type Property = SeriesProperty ;
|
||||
|
||||
fn compare_by (
|
||||
series_1 : & SeriesOverview ,
|
||||
series_2 : & SeriesOverview ,
|
||||
sorting : SeriesSorting ,
|
||||
) -> Ordering {
|
||||
let ordering = match sorting . property {
|
||||
SeriesProperty :: Name => series_1 . name . cmp ( & series_2 . name ) ,
|
||||
SeriesProperty :: FirstReleaseDate => series_1 . first_release_date . cmp ( & series_2 . first_release_date ) ,
|
||||
} ;
|
||||
match sorting . direction {
|
||||
SortingDirection :: Ascending => ordering ,
|
||||
SortingDirection :: Descending => ordering . reverse () ,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property_descriptions () -> & 'static [ ( SeriesProperty , & 'static str ) ] {
|
||||
leak ( [
|
||||
( SeriesProperty :: Name , "Name" ) ,
|
||||
( SeriesProperty :: FirstReleaseDate , "First release date" ) ,
|
||||
] )
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue