Header & view stack are now components, introduced Component trait

This commit is contained in:
Reinout Meliesie 2024-11-27 15:22:55 +01:00
parent 64fc8ba425
commit 4778d879f4
Signed by: zedfrigg
GPG key ID: 3AFCC06481308BC6
8 changed files with 184 additions and 100 deletions

View file

@ -0,0 +1,29 @@
use libadwaita :: { * , ViewSwitcherPolicy :: * } ;
use crate :: ui :: { collection_view_stack :: * , component :: * } ;
pub struct ApplicationHeaderBar { widget : HeaderBar }
impl ApplicationHeaderBar {
pub fn new ( collection_view_stack : & CollectionViewStack ) -> Self {
let widget = HeaderBar :: builder ()
. title_widget ( & create_collection_view_switcher (
collection_view_stack . get_widget () ) )
. build () ;
Self { widget }
}
}
impl Component <HeaderBar> for ApplicationHeaderBar {
fn get_widget ( & self ) -> & HeaderBar { & self . widget }
}
fn create_collection_view_switcher ( stack : & ViewStack ) -> ViewSwitcher {
ViewSwitcher :: builder ()
. policy (Wide)
. stack (stack)
. build ()
}

View file

@ -2,7 +2,12 @@ use gtk4 :: { * , prelude :: * } ;
use crate :: {
collection :: * ,
ui :: { collated_grid :: * , collation_menu :: * , utility :: * } ,
ui :: {
collated_grid :: * ,
collation_menu :: * ,
component :: * ,
utility :: * ,
} ,
utility :: * ,
} ;
@ -10,20 +15,23 @@ use crate :: {
pub struct CollatableFilmsContainer {
collated_grid : & 'static CollatedFilmsGrid ,
widget : gtk4 :: Box ,
widget : Box ,
}
pub struct CollatableSeriesContainer {
collated_grid : & 'static CollatedSeriesGrid ,
widget : gtk4 :: Box ,
widget : Box ,
}
impl CollatableFilmsContainer {
pub fn new ( films : Vec <Film> ) -> Self {
let collated_grid = leak ( CollatedFilmsGrid :: new ( films , FilmsSortedBy :: Name ) ) ;
let collated_grid = leak (
CollatedFilmsGrid :: new ( films , FilmsSortedBy :: Name ) ) ;
let film_collation_menu = FilmCollationMenu :: new ( |sorted_by| {
collated_grid . set_sorting (sorted_by) ;
} ) ;
let widget = create_vertical_box ! (
& create_film_collection_menu ( |sorted_by| {
collated_grid . set_sorting (sorted_by) ;
} ) ,
film_collation_menu . get_widget () ,
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
) ;
@ -33,16 +41,17 @@ impl CollatableFilmsContainer {
pub fn set_films ( & self , films : Vec <Film> ) {
self . collated_grid . set_films ( films , FilmsSortedBy :: Name ) ;
}
pub fn get_widget ( & self ) -> & gtk4 :: Box { & self . widget }
}
impl CollatableSeriesContainer {
pub fn new ( series : Vec <Series> ) -> Self {
let collated_grid = leak ( CollatedSeriesGrid :: new ( series , SeriesSortedBy :: Name ) ) ;
let collated_grid = leak (
CollatedSeriesGrid :: new ( series , SeriesSortedBy :: Name ) ) ;
let series_collation_menu = SeriesCollationMenu :: new ( |sorted_by| {
collated_grid . set_sorting (sorted_by) ;
} ) ;
let widget = create_vertical_box ! (
& create_series_collection_menu ( |sorted_by| {
collated_grid . set_sorting (sorted_by) ;
} ) ,
series_collation_menu . get_widget () ,
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
) ;
@ -52,8 +61,13 @@ impl CollatableSeriesContainer {
pub fn set_series ( & self , series : Vec <Series> ) {
self . collated_grid . set_series ( series , SeriesSortedBy :: Name ) ;
}
}
pub fn get_widget ( & self ) -> & gtk4 :: Box { & self . widget }
impl Component <Box> for CollatableFilmsContainer {
fn get_widget ( & self ) -> & Box { & self . widget }
}
impl Component <Box> for CollatableSeriesContainer {
fn get_widget ( & self ) -> & Box { & self . widget }
}
fn create_collection_scrolled_window ( child : & FlowBox ) -> ScrolledWindow {

View file

@ -6,10 +6,10 @@ use {
gdk :: Texture ,
prelude :: * ,
} ,
std :: { cell :: * , iter :: * , path :: * } ,
std :: { cell :: * , iter :: * , path :: Path } ,
} ;
use crate :: collection :: * ;
use crate :: { collection :: * , ui :: component :: * } ;
@ -66,8 +66,6 @@ impl CollatedFilmsGrid {
self . grid_widget . append (film_widget) ;
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
}
impl CollatedSeriesGrid {
pub fn new ( series : Vec <Series> , sorting : SeriesSortedBy ) -> Self {
@ -110,8 +108,13 @@ impl CollatedSeriesGrid {
self . grid_widget . append (series_widget) ;
}
}
}
pub fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
impl Component <FlowBox> for CollatedFilmsGrid {
fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
}
impl Component <FlowBox> for CollatedSeriesGrid {
fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
}
fn sort_film_widget_pairs (

View file

@ -1,6 +1,6 @@
use {
gtk4 :: {
Image , Label , ListBox , ListBoxRow , Popover ,
Box , Image , Label , ListBox , ListBoxRow , Popover ,
Align :: * ,
Orientation :: * ,
prelude :: * ,
@ -8,37 +8,51 @@ use {
libadwaita :: * ,
} ;
use crate :: ui :: { collated_grid :: * , utility :: * } ;
use crate :: ui :: { collated_grid :: * , component :: * , utility :: * } ;
pub fn create_film_collection_menu < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F )
-> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. css_classes ( ["toolbar"] )
. build () ;
pub struct FilmCollationMenu { widget : Box }
pub struct SeriesCollationMenu { widget : Box }
container . append ( & create_sort_button ( & create_films_sort_menu (on_sort) ) ) ;
container . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
impl FilmCollationMenu {
pub fn new <F> ( on_sort : F ) -> Self
where F : Fn (FilmsSortedBy) + 'static {
let widget = Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. css_classes ( ["toolbar"] )
. build () ;
container
widget . append ( & create_sort_button ( & create_films_sort_menu (on_sort) ) ) ;
widget . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
Self { widget }
}
}
pub fn create_series_collection_menu < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F )
-> gtk4 :: Box {
let container = gtk4 :: Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. css_classes ( ["toolbar"] )
. build () ;
impl SeriesCollationMenu {
pub fn new <F> ( on_sort : F ) -> Self
where F : Fn (SeriesSortedBy) + 'static {
let widget = Box :: builder ()
. orientation (Horizontal)
. halign (Center)
. spacing (20)
. css_classes ( ["toolbar"] )
. build () ;
container . append ( & create_sort_button ( & create_series_sort_menu (on_sort) ) ) ;
container . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
widget . append ( & create_sort_button ( & create_series_sort_menu (on_sort) ) ) ;
widget . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
container
Self { widget }
}
}
impl Component <Box> for FilmCollationMenu {
fn get_widget ( & self ) -> & Box { & self . widget }
}
impl Component <Box> for SeriesCollationMenu {
fn get_widget ( & self ) -> & Box { & self . widget }
}
fn create_sort_button ( sort_menu : & Popover ) -> SplitButton {
@ -48,8 +62,8 @@ 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> ( on_sort : F ) -> Popover
where F : Fn (FilmsSortedBy) + 'static {
let container = ListBox :: new () ;
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;
@ -70,8 +84,8 @@ fn create_films_sort_menu < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F )
. css_classes ( ["menu"] )
. build ()
}
fn create_series_sort_menu < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F )
-> Popover {
fn create_series_sort_menu <F> ( on_sort : F ) -> Popover
where F : Fn (SeriesSortedBy) + 'static {
let container = ListBox :: new () ;
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;

View file

@ -0,0 +1,25 @@
use libadwaita :: * ;
use crate :: ui :: { collatable_container :: * , component :: * , utility :: * } ;
pub struct CollectionViewStack { widget : ViewStack }
impl CollectionViewStack {
pub fn new (
films_container : & CollatableFilmsContainer ,
series_container : & CollatableSeriesContainer ,
) -> Self {
let widget = create_view_stack ! (
"Films" , "camera-video-symbolic" , films_container . get_widget () ,
"Series" , "video-display-symbolic" , series_container . get_widget () ,
) ;
Self { widget }
}
}
impl Component <ViewStack> for CollectionViewStack {
fn get_widget ( & self ) -> & ViewStack { & self . widget }
}

7
src/ui/component.rs Normal file
View file

@ -0,0 +1,7 @@
use gtk4 :: { * , prelude :: * } ;
pub trait Component < W : IsA <Widget> > {
fn get_widget ( & self ) -> & W ;
}

View file

@ -1,37 +0,0 @@
use {
gtk4 :: { HeaderBar , Orientation :: * , prelude :: * } ,
libadwaita :: { * , ViewSwitcherPolicy :: * } ,
} ;
pub fn create_window (
application : & Application ,
header_bar : & HeaderBar ,
collection_view_stack : & ViewStack ,
) -> ApplicationWindow {
let content = gtk4 :: Box :: builder () . orientation (Vertical) . build () ;
content . append (header_bar) ;
content . append (collection_view_stack) ;
ApplicationWindow :: builder ()
. application (application)
. content ( & content )
. title ("Zoödex")
. build ()
}
pub fn create_header_bar ( collection_view_stack : & ViewStack ) -> HeaderBar {
HeaderBar :: builder ()
. title_widget (
& create_collection_view_switcher ( collection_view_stack ) ,
)
. build ()
}
pub fn create_collection_view_switcher ( stack : & ViewStack ) -> ViewSwitcher {
ViewSwitcher :: builder ()
. policy (Wide)
. stack (stack)
. build ()
}

View file

@ -1,42 +1,71 @@
mod application_header_bar ;
mod collatable_container ;
mod collated_grid ;
mod collation_menu ;
mod internal ;
mod collection_view_stack ;
mod component ;
mod utility ;
use { gtk4 :: prelude :: * , libadwaita :: * } ;
use {
gtk4 :: { Orientation :: * , prelude :: * } ,
libadwaita :: * ,
} ;
use crate :: {
collection :: * ,
ui :: { collatable_container :: * , internal :: * , utility :: * } ,
ui :: {
application_header_bar :: * ,
collatable_container :: * ,
collection_view_stack :: * ,
component :: * ,
} ,
} ;
pub struct UI {
window : ApplicationWindow ,
films_container : CollatableFilmsContainer ,
series_container : CollatableSeriesContainer ,
films_component : CollatableFilmsContainer ,
series_component : CollatableSeriesContainer ,
}
impl UI {
pub fn new ( application : & Application ) -> UI {
let films_container = CollatableFilmsContainer :: new ( vec ! () ) ;
let series_container = CollatableSeriesContainer :: new ( vec ! () ) ;
let collection_view_stack = create_view_stack ! (
"Films" , "camera-video-symbolic" , films_container . get_widget () ,
"Series" , "video-display-symbolic" , series_container . get_widget () ,
) ;
let header_bar = create_header_bar ( & collection_view_stack ) ;
let window = create_window ( application , & header_bar , & collection_view_stack ) ;
let films_component = CollatableFilmsContainer :: new ( vec ! () ) ;
let series_component = CollatableSeriesContainer :: new ( vec ! () ) ;
let switch_component = CollectionViewStack :: new (
& films_component , & series_component ) ;
let header_bar = ApplicationHeaderBar :: new ( & switch_component ) ;
UI { window , films_container , series_container }
let window = create_window (
application ,
header_bar . get_widget () ,
switch_component . get_widget () ,
) ;
UI { window , films_component , series_component }
}
pub fn show_window ( & self ) { self . window . set_visible (true) }
pub fn render_collection ( & self , collection : Collection ) {
self . films_container . set_films ( collection . films ) ;
self . series_container . set_series ( collection . series ) ;
self . films_component . set_films ( collection . films ) ;
self . series_component . set_series ( collection . series ) ;
}
}
fn create_window (
application : & Application ,
header_bar : & HeaderBar ,
collection_view_stack : & ViewStack ,
) -> ApplicationWindow {
let content = gtk4 :: Box :: builder () . orientation (Vertical) . build () ;
content . append (header_bar) ;
content . append (collection_view_stack) ;
ApplicationWindow :: builder ()
. application (application)
. content ( & content )
. title ("Zoödex")
. build ()
}