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 :: {
|
use crate :: {
|
||||||
collection :: * ,
|
collection :: * ,
|
||||||
ui :: { collated_grid :: * , collation_menu :: * , utility :: * } ,
|
ui :: {
|
||||||
|
collated_grid :: * ,
|
||||||
|
collation_menu :: * ,
|
||||||
|
component :: * ,
|
||||||
|
utility :: * ,
|
||||||
|
} ,
|
||||||
utility :: * ,
|
utility :: * ,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
@ -10,20 +15,23 @@ use crate :: {
|
||||||
|
|
||||||
pub struct CollatableFilmsContainer {
|
pub struct CollatableFilmsContainer {
|
||||||
collated_grid : & 'static CollatedFilmsGrid ,
|
collated_grid : & 'static CollatedFilmsGrid ,
|
||||||
widget : gtk4 :: Box ,
|
widget : Box ,
|
||||||
}
|
}
|
||||||
pub struct CollatableSeriesContainer {
|
pub struct CollatableSeriesContainer {
|
||||||
collated_grid : & 'static CollatedSeriesGrid ,
|
collated_grid : & 'static CollatedSeriesGrid ,
|
||||||
widget : gtk4 :: Box ,
|
widget : Box ,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CollatableFilmsContainer {
|
impl CollatableFilmsContainer {
|
||||||
pub fn new ( films : Vec <Film> ) -> Self {
|
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 ! (
|
let widget = create_vertical_box ! (
|
||||||
& create_film_collection_menu ( |sorted_by| {
|
film_collation_menu . get_widget () ,
|
||||||
collated_grid . set_sorting (sorted_by) ;
|
|
||||||
} ) ,
|
|
||||||
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
|
@ -33,16 +41,17 @@ impl CollatableFilmsContainer {
|
||||||
pub fn set_films ( & self , films : Vec <Film> ) {
|
pub fn set_films ( & self , films : Vec <Film> ) {
|
||||||
self . collated_grid . set_films ( films , FilmsSortedBy :: Name ) ;
|
self . collated_grid . set_films ( films , FilmsSortedBy :: Name ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget ( & self ) -> & gtk4 :: Box { & self . widget }
|
|
||||||
}
|
}
|
||||||
impl CollatableSeriesContainer {
|
impl CollatableSeriesContainer {
|
||||||
pub fn new ( series : Vec <Series> ) -> Self {
|
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 ! (
|
let widget = create_vertical_box ! (
|
||||||
& create_series_collection_menu ( |sorted_by| {
|
series_collation_menu . get_widget () ,
|
||||||
collated_grid . set_sorting (sorted_by) ;
|
|
||||||
} ) ,
|
|
||||||
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
|
@ -52,8 +61,13 @@ impl CollatableSeriesContainer {
|
||||||
pub fn set_series ( & self , series : Vec <Series> ) {
|
pub fn set_series ( & self , series : Vec <Series> ) {
|
||||||
self . collated_grid . set_series ( series , SeriesSortedBy :: Name ) ;
|
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 {
|
fn create_collection_scrolled_window ( child : & FlowBox ) -> ScrolledWindow {
|
||||||
|
|
|
@ -6,10 +6,10 @@ use {
|
||||||
gdk :: Texture ,
|
gdk :: Texture ,
|
||||||
prelude :: * ,
|
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) ;
|
self . grid_widget . append (film_widget) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_widget ( & self ) -> & FlowBox { & self . grid_widget }
|
|
||||||
}
|
}
|
||||||
impl CollatedSeriesGrid {
|
impl CollatedSeriesGrid {
|
||||||
pub fn new ( series : Vec <Series> , sorting : SeriesSortedBy ) -> Self {
|
pub fn new ( series : Vec <Series> , sorting : SeriesSortedBy ) -> Self {
|
||||||
|
@ -110,8 +108,13 @@ impl CollatedSeriesGrid {
|
||||||
self . grid_widget . append (series_widget) ;
|
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 (
|
fn sort_film_widget_pairs (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
gtk4 :: {
|
gtk4 :: {
|
||||||
Image , Label , ListBox , ListBoxRow , Popover ,
|
Box , Image , Label , ListBox , ListBoxRow , Popover ,
|
||||||
Align :: * ,
|
Align :: * ,
|
||||||
Orientation :: * ,
|
Orientation :: * ,
|
||||||
prelude :: * ,
|
prelude :: * ,
|
||||||
|
@ -8,37 +8,51 @@ use {
|
||||||
libadwaita :: * ,
|
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 )
|
pub struct FilmCollationMenu { widget : Box }
|
||||||
-> gtk4 :: Box {
|
pub struct SeriesCollationMenu { widget : Box }
|
||||||
let container = gtk4 :: Box :: builder ()
|
|
||||||
. orientation (Horizontal)
|
|
||||||
. halign (Center)
|
|
||||||
. spacing (20)
|
|
||||||
. css_classes ( ["toolbar"] )
|
|
||||||
. build () ;
|
|
||||||
|
|
||||||
container . append ( & create_sort_button ( & create_films_sort_menu (on_sort) ) ) ;
|
impl FilmCollationMenu {
|
||||||
container . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
|
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 )
|
impl SeriesCollationMenu {
|
||||||
-> gtk4 :: Box {
|
pub fn new <F> ( on_sort : F ) -> Self
|
||||||
let container = gtk4 :: Box :: builder ()
|
where F : Fn (SeriesSortedBy) + 'static {
|
||||||
. orientation (Horizontal)
|
let widget = Box :: builder ()
|
||||||
. halign (Center)
|
. orientation (Horizontal)
|
||||||
. spacing (20)
|
. halign (Center)
|
||||||
. css_classes ( ["toolbar"] )
|
. spacing (20)
|
||||||
. build () ;
|
. css_classes ( ["toolbar"] )
|
||||||
|
. build () ;
|
||||||
|
|
||||||
container . append ( & create_sort_button ( & create_series_sort_menu (on_sort) ) ) ;
|
widget . append ( & create_sort_button ( & create_series_sort_menu (on_sort) ) ) ;
|
||||||
container . append ( & SplitButton :: builder () . label ("Filter") . build () ) ;
|
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 {
|
fn create_sort_button ( sort_menu : & Popover ) -> SplitButton {
|
||||||
|
@ -48,8 +62,8 @@ fn create_sort_button ( sort_menu : & Popover ) -> SplitButton {
|
||||||
. build ()
|
. build ()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_films_sort_menu < F : Fn (FilmsSortedBy) + 'static > ( on_sort : F )
|
fn create_films_sort_menu <F> ( on_sort : F ) -> Popover
|
||||||
-> Popover {
|
where F : Fn (FilmsSortedBy) + 'static {
|
||||||
let container = ListBox :: new () ;
|
let container = ListBox :: new () ;
|
||||||
|
|
||||||
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;
|
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"] )
|
. css_classes ( ["menu"] )
|
||||||
. build ()
|
. build ()
|
||||||
}
|
}
|
||||||
fn create_series_sort_menu < F : Fn (SeriesSortedBy) + 'static > ( on_sort : F )
|
fn create_series_sort_menu <F> ( on_sort : F ) -> Popover
|
||||||
-> Popover {
|
where F : Fn (SeriesSortedBy) + 'static {
|
||||||
let container = ListBox :: new () ;
|
let container = ListBox :: new () ;
|
||||||
|
|
||||||
container . append ( & create_sort_menu_entry ( "Name" , false , true ) ) ;
|
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 collatable_container ;
|
||||||
mod collated_grid ;
|
mod collated_grid ;
|
||||||
mod collation_menu ;
|
mod collation_menu ;
|
||||||
mod internal ;
|
mod collection_view_stack ;
|
||||||
|
mod component ;
|
||||||
mod utility ;
|
mod utility ;
|
||||||
|
|
||||||
use { gtk4 :: prelude :: * , libadwaita :: * } ;
|
use {
|
||||||
|
gtk4 :: { Orientation :: * , prelude :: * } ,
|
||||||
|
libadwaita :: * ,
|
||||||
|
} ;
|
||||||
|
|
||||||
use crate :: {
|
use crate :: {
|
||||||
collection :: * ,
|
collection :: * ,
|
||||||
ui :: { collatable_container :: * , internal :: * , utility :: * } ,
|
ui :: {
|
||||||
|
application_header_bar :: * ,
|
||||||
|
collatable_container :: * ,
|
||||||
|
collection_view_stack :: * ,
|
||||||
|
component :: * ,
|
||||||
|
} ,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub struct UI {
|
pub struct UI {
|
||||||
window : ApplicationWindow ,
|
window : ApplicationWindow ,
|
||||||
films_container : CollatableFilmsContainer ,
|
films_component : CollatableFilmsContainer ,
|
||||||
series_container : CollatableSeriesContainer ,
|
series_component : CollatableSeriesContainer ,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UI {
|
impl UI {
|
||||||
pub fn new ( application : & Application ) -> UI {
|
pub fn new ( application : & Application ) -> UI {
|
||||||
let films_container = CollatableFilmsContainer :: new ( vec ! () ) ;
|
let films_component = CollatableFilmsContainer :: new ( vec ! () ) ;
|
||||||
let series_container = CollatableSeriesContainer :: new ( vec ! () ) ;
|
let series_component = CollatableSeriesContainer :: new ( vec ! () ) ;
|
||||||
let collection_view_stack = create_view_stack ! (
|
let switch_component = CollectionViewStack :: new (
|
||||||
"Films" , "camera-video-symbolic" , films_container . get_widget () ,
|
& films_component , & series_component ) ;
|
||||||
"Series" , "video-display-symbolic" , series_container . get_widget () ,
|
let header_bar = ApplicationHeaderBar :: new ( & switch_component ) ;
|
||||||
) ;
|
|
||||||
let header_bar = create_header_bar ( & collection_view_stack ) ;
|
|
||||||
let window = create_window ( application , & header_bar , & collection_view_stack ) ;
|
|
||||||
|
|
||||||
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 show_window ( & self ) { self . window . set_visible (true) }
|
||||||
|
|
||||||
pub fn render_collection ( & self , collection : Collection ) {
|
pub fn render_collection ( & self , collection : Collection ) {
|
||||||
self . films_container . set_films ( collection . films ) ;
|
self . films_component . set_films ( collection . films ) ;
|
||||||
self . series_container . set_series ( collection . series ) ;
|
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