Introduce "collation" naming, move collated_grid into own module

This commit is contained in:
Reinout Meliesie 2024-11-26 17:20:53 +01:00
parent 988d4016ea
commit 60c367beb7
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
5 changed files with 187 additions and 184 deletions

View file

@ -1,11 +1,8 @@
use { use { gtk4 :: { * , prelude :: * } , std :: cell :: * } ;
gtk4 :: { ScrolledWindow, Widget, prelude :: * } ,
std :: cell :: * ,
} ;
use crate :: { use crate :: {
collection :: * , collection :: * ,
ui :: { collection_menu :: * , internal :: * , utility :: * } , ui :: { collated_grid :: * , collation_menu :: * , utility :: * } ,
utility :: * , utility :: * ,
} ; } ;
@ -14,21 +11,21 @@ use crate :: {
pub enum FilmsSortedBy { Name , ReleaseDate , Runtime } pub enum FilmsSortedBy { Name , ReleaseDate , Runtime }
pub enum SeriesSortedBy { Name , FirstReleaseDate } pub enum SeriesSortedBy { Name , FirstReleaseDate }
pub struct FilmsContainer { pub struct CollatableFilmsContainer {
films : & 'static RefCell < Vec <Film> > , films : & 'static RefCell < Vec <Film> > ,
flow_box : & 'static FilmsFlowBox , flow_box : & 'static CollatedFilmsGrid ,
widget : gtk4 :: Box , widget : gtk4 :: Box ,
} }
pub struct SeriesContainer { pub struct CollatableSeriesContainer {
series : Vec <Series> , series : Vec <Series> ,
flow_box : SeriesFlowBox , flow_box : CollatedSeriesGrid ,
widget : gtk4 :: Box , widget : gtk4 :: Box ,
} }
impl FilmsContainer { impl CollatableFilmsContainer {
pub fn new ( films : Vec <Film> ) -> Self { pub fn new ( films : Vec <Film> ) -> Self {
let films = leak ( RefCell :: new (films) ) ; let films = leak ( RefCell :: new (films) ) ;
let flow_box = leak ( FilmsFlowBox :: new ( films . borrow () . as_slice () ) ) ; let flow_box = leak ( CollatedFilmsGrid :: new ( films . borrow () . as_slice () ) ) ;
let widget = create_vertical_box ! ( let widget = create_vertical_box ! (
& create_film_collection_menu ( |sorted_by| { & create_film_collection_menu ( |sorted_by| {
flow_box . set_films ( films . borrow () . as_slice () ) ; flow_box . set_films ( films . borrow () . as_slice () ) ;
@ -46,9 +43,9 @@ impl FilmsContainer {
pub fn get_widget ( & self ) -> & gtk4 :: Box { & self . widget } pub fn get_widget ( & self ) -> & gtk4 :: Box { & self . widget }
} }
impl SeriesContainer { impl CollatableSeriesContainer {
pub fn new ( series : Vec <Series> ) -> Self { pub fn new ( series : Vec <Series> ) -> Self {
let flow_box = SeriesFlowBox :: new ( series . as_slice () ) ; let flow_box = CollatedSeriesGrid :: new ( series . as_slice () ) ;
let widget = create_vertical_box ! ( let widget = create_vertical_box ! (
& create_series_collection_menu ( |sorted_by| { & create_series_collection_menu ( |sorted_by| {
// TODO // TODO

167
src/ui/collated_grid.rs Normal file
View file

@ -0,0 +1,167 @@
use {
gtk4 :: {
* ,
Align :: * ,
Orientation :: * ,
gdk :: Texture ,
glib :: * ,
prelude :: * ,
} ,
std :: path :: * ,
} ;
use crate :: collection :: * ;
pub struct CollatedFilmsGrid { widget : FlowBox }
pub struct CollatedSeriesGrid { widget : FlowBox }
impl CollatedFilmsGrid {
pub fn new ( films : & [Film] ) -> Self {
let widget = create_collection_flow_box () ;
for film in films {
widget . append ( & create_film_item (film) ) ;
}
Self { widget }
}
pub fn set_films ( & self , films : & [Film] ) {
self . widget . remove_all () ;
for film in films {
let widget = self . widget . clone () ;
let film = film . clone () ;
spawn_future_local ( async move {
widget . append ( & create_film_item ( & film ) ) ;
} ) ;
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . widget }
}
impl CollatedSeriesGrid {
pub fn new ( series : & [Series] ) -> Self {
let widget = create_collection_flow_box () ;
for series in series {
widget . append ( & create_series_item (series) ) ;
}
Self { widget }
}
pub fn set_series ( & self , series : & [Series] ) {
self . widget . remove_all () ;
for series in series {
self . widget . append ( & create_series_item (series) ) ;
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . widget }
}
fn create_collection_flow_box () -> FlowBox {
FlowBox :: builder ()
. orientation (Horizontal)
. homogeneous (true)
. selection_mode ( SelectionMode :: None )
. build ()
}
pub fn create_film_item ( film : & Film ) -> gtk4 :: Box {
create_collection_item (
film . name . as_str () ,
film . original_name . as_deref () ,
film . poster_file_path . as_deref () ,
& create_film_details (film) ,
)
}
pub fn create_series_item ( series : & Series ) -> gtk4 :: Box {
create_collection_item (
series . name . as_str () ,
series . original_name . as_deref () ,
series . poster_file_path . as_deref () ,
& create_series_details (series) ,
)
}
fn create_collection_item (
name : & str ,
original_name : Option < & str > ,
poster_file_path : Option < & Path > ,
details_widget : & gtk4 :: Box ,
) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Vertical)
. margin_top (20)
. margin_bottom (20)
. build () ;
if let Some (poster_file_path) = poster_file_path {
let poster_texture = Texture :: from_filename (poster_file_path) . unwrap () ;
container . append (
& Image :: builder ()
. paintable ( & poster_texture )
. width_request (300)
. height_request (300)
. margin_bottom (10)
. build ()
) ;
}
container . append (
& Label :: builder ()
. label ( format ! ( "<span size='large' weight='bold'>{}</span>" , name ) )
. use_markup (true)
. justify ( Justification :: Center )
. wrap (true)
. max_width_chars (1) // Not the actual limit, used instead to wrap more aggressively
. build ()
) ;
if let Some (original_name) = original_name {
container . append (
& Label :: builder ()
. label (original_name)
. justify ( Justification :: Center )
. wrap (true)
. max_width_chars (1) // Not the actual limit, used instead to wrap more aggressively
. build ()
) ;
}
container . append (details_widget) ;
container
}
fn create_film_details ( film : & Film ) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. build () ;
container . append (
& Label :: builder () . label ( & film . release_date ) . build ()
) ;
container . append (
& Label :: builder () . label ( format ! ( "{}m" , film . runtime_minutes ) ) . build ()
) ;
container
}
fn create_series_details ( series : & Series ) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. build () ;
// TODO
container
}

View file

@ -8,7 +8,7 @@ use {
libadwaita :: * , libadwaita :: * ,
} ; } ;
use crate :: ui :: { dynamic_container :: * , utility :: * } ; use crate :: ui :: { collatable_container :: * , utility :: * } ;

View file

@ -1,18 +1,8 @@
use { use {
gtk4 :: { gtk4 :: { HeaderBar , Orientation :: * , prelude :: * } ,
FlowBox, HeaderBar, Image, Justification, Label, SelectionMode,
Align :: * ,
Orientation :: * ,
gdk :: Texture ,
glib :: * ,
prelude :: * ,
} ,
libadwaita :: { * , ViewSwitcherPolicy :: * } , libadwaita :: { * , ViewSwitcherPolicy :: * } ,
std :: path :: * ,
} ; } ;
use crate :: collection :: * ;
pub fn create_window ( pub fn create_window (
@ -45,155 +35,3 @@ pub fn create_collection_view_switcher ( stack : & ViewStack ) -> ViewSwitcher {
. stack (stack) . stack (stack)
. build () . build ()
} }
pub struct FilmsFlowBox { widget : FlowBox }
pub struct SeriesFlowBox { widget : FlowBox }
impl FilmsFlowBox {
pub fn new ( films : & [Film] ) -> Self {
let widget = create_collection_flow_box () ;
for film in films {
widget . append ( & create_film_item (film) ) ;
}
Self { widget }
}
pub fn set_films ( & self , films : & [Film] ) {
self . widget . remove_all () ;
for film in films {
let widget = self . widget . clone () ;
let film = film . clone () ;
spawn_future_local ( async move {
widget . append ( & create_film_item ( & film ) ) ;
} ) ;
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . widget }
}
impl SeriesFlowBox {
pub fn new ( series : & [Series] ) -> Self {
let widget = create_collection_flow_box () ;
for series in series {
widget . append ( & create_series_item (series) ) ;
}
Self { widget }
}
pub fn set_series ( & self , series : & [Series] ) {
self . widget . remove_all () ;
for series in series {
self . widget . append ( & create_series_item (series) ) ;
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . widget }
}
fn create_collection_flow_box () -> FlowBox {
FlowBox :: builder ()
. orientation (Horizontal)
. homogeneous (true)
. selection_mode ( SelectionMode :: None )
. build ()
}
pub fn create_film_item ( film : & Film ) -> gtk4 :: Box {
create_collection_item (
film . name . as_str () ,
film . original_name . as_deref () ,
film . poster_file_path . as_deref () ,
& create_film_details (film) ,
)
}
pub fn create_series_item ( series : & Series ) -> gtk4 :: Box {
create_collection_item (
series . name . as_str () ,
series . original_name . as_deref () ,
series . poster_file_path . as_deref () ,
& create_series_details (series) ,
)
}
fn create_film_details ( film : & Film ) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. build () ;
container . append (
& Label :: builder () . label ( & film . release_date ) . build ()
) ;
container . append (
& Label :: builder () . label ( format ! ( "{}m" , film . runtime_minutes ) ) . build ()
) ;
container
}
fn create_series_details ( series : & Series ) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. build () ;
// TODO
container
}
fn create_collection_item (
name : & str ,
original_name : Option < & str > ,
poster_file_path : Option < & Path > ,
details_widget : & gtk4 :: Box ,
) -> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Vertical)
. margin_top (20)
. margin_bottom (20)
. build () ;
if let Some (poster_file_path) = poster_file_path {
let poster_texture = Texture :: from_filename (poster_file_path) . unwrap () ;
container . append (
& Image :: builder ()
. paintable ( & poster_texture )
. width_request (300)
. height_request (300)
. margin_bottom (10)
. build ()
) ;
}
container . append (
& Label :: builder ()
. label ( format ! ( "<span size='large' weight='bold'>{}</span>" , name ) )
. use_markup (true)
. justify ( Justification :: Center )
. wrap (true)
. max_width_chars (1) // Not the actual limit, used instead to wrap more aggressively
. build ()
) ;
if let Some (original_name) = original_name {
container . append (
& Label :: builder ()
. label (original_name)
. justify ( Justification :: Center )
. wrap (true)
. max_width_chars (1) // Not the actual limit, used instead to wrap more aggressively
. build ()
) ;
}
container . append (details_widget) ;
container
}

View file

@ -1,5 +1,6 @@
mod collection_menu ; mod collatable_container ;
mod dynamic_container ; mod collated_grid ;
mod collation_menu ;
mod internal ; mod internal ;
mod utility ; mod utility ;
@ -7,21 +8,21 @@ use { gtk4 :: prelude :: * , libadwaita :: * } ;
use crate :: { use crate :: {
collection :: * , collection :: * ,
ui :: { dynamic_container :: * , internal :: * , utility :: * } , ui :: { collatable_container :: * , internal :: * , utility :: * } ,
} ; } ;
pub struct UI { pub struct UI {
window : ApplicationWindow , window : ApplicationWindow ,
films_container : FilmsContainer , films_container : CollatableFilmsContainer ,
series_container : SeriesContainer , series_container : CollatableSeriesContainer ,
} }
impl UI { impl UI {
pub fn new ( application : & Application ) -> UI { pub fn new ( application : & Application ) -> UI {
let films_container = FilmsContainer :: new ( vec ! () ) ; let films_container = CollatableFilmsContainer :: new ( vec ! () ) ;
let series_container = SeriesContainer :: new ( vec ! () ) ; let series_container = CollatableSeriesContainer :: new ( vec ! () ) ;
let collection_view_stack = create_view_stack ! ( let collection_view_stack = create_view_stack ! (
"Films" , "camera-video-symbolic" , films_container . get_widget () , "Films" , "camera-video-symbolic" , films_container . get_widget () ,
"Series" , "video-display-symbolic" , series_container . get_widget () , "Series" , "video-display-symbolic" , series_container . get_widget () ,