Header & view stack are now components, introduced Component trait
This commit is contained in:
parent
64fc8ba425
commit
4778d879f4
8 changed files with 184 additions and 100 deletions
29
src/ui/application_header_bar.rs
Normal file
29
src/ui/application_header_bar.rs
Normal 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 ()
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 ) ) ;
|
||||
|
|
25
src/ui/collection_view_stack.rs
Normal file
25
src/ui/collection_view_stack.rs
Normal 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
7
src/ui/component.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use gtk4 :: { * , prelude :: * } ;
|
||||
|
||||
|
||||
|
||||
pub trait Component < W : IsA <Widget> > {
|
||||
fn get_widget ( & self ) -> & W ;
|
||||
}
|
|
@ -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 ()
|
||||
}
|
|
@ -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 ()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue