Reimplement collation menu as component
This commit is contained in:
parent
ebc8bc0d2f
commit
04755fabb7
4 changed files with 133 additions and 45 deletions
|
@ -3,8 +3,7 @@ mod sort_button ;
|
|||
use {
|
||||
gtk4 :: {
|
||||
Box , Image , Label , ListBox , ListBoxRow , Popover ,
|
||||
Align :: * ,
|
||||
Orientation :: * ,
|
||||
Align :: * , Orientation :: * ,
|
||||
prelude :: * ,
|
||||
} ,
|
||||
libadwaita :: * ,
|
||||
|
@ -12,33 +11,31 @@ use {
|
|||
} ;
|
||||
|
||||
use crate :: {
|
||||
ui :: { collatable_container :: * , component :: * , utility :: * } ,
|
||||
ui :: {
|
||||
component :: * , utility :: * ,
|
||||
collatable_container :: { * , collation_menu :: sort_button :: * } } ,
|
||||
utility :: * ,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
pub struct FilmCollationMenu {
|
||||
widget : Box ,
|
||||
sorting : & 'static RefCell < ( FilmsSortedBy , SortingDirection ) > ,
|
||||
}
|
||||
pub struct FilmCollationMenu { widget : Box }
|
||||
pub struct SeriesCollationMenu { widget : Box }
|
||||
|
||||
impl FilmCollationMenu {
|
||||
pub fn new < F : Fn ( FilmsSortedBy , SortingDirection ) + 'static > ( on_sort : F ) -> Self {
|
||||
let widget = Box :: builder ()
|
||||
. orientation (Horizontal)
|
||||
. halign (Center)
|
||||
. spacing (20)
|
||||
. name ("film-collation-menu")
|
||||
. css_classes ( ["toolbar"] )
|
||||
. build () ;
|
||||
let sorting = leak ( RefCell :: new ( ( FilmsSortedBy :: Name , SortingDirection :: Ascending ) ) ) ;
|
||||
let film_sort_button = FilmSortButton :: new (on_sort) ;
|
||||
|
||||
widget . append ( & create_sort_button ( & create_films_sort_menu ( sorting , on_sort ) ) ) ;
|
||||
widget . append ( & create_filter_button () ) ;
|
||||
let widget = g_box ! (
|
||||
@ orientation : Horizontal ,
|
||||
@ halign : Center ,
|
||||
@ spacing : 20 ,
|
||||
@ widget_name : "film-collation-menu" ,
|
||||
@ css_classes : [ "toolbar" ] ,
|
||||
* film_sort_button . get_widget ()
|
||||
) ;
|
||||
|
||||
Self { widget , sorting }
|
||||
Self { widget }
|
||||
}
|
||||
}
|
||||
impl SeriesCollationMenu {
|
||||
|
@ -126,12 +123,12 @@ fn create_sort_menu_entry ( label : & str , reverse : bool ) -> ListBoxRow {
|
|||
|
||||
let container = g_box ! (
|
||||
@ orientation : Horizontal ,
|
||||
& Label :: builder ()
|
||||
Label :: builder ()
|
||||
. label (label)
|
||||
. hexpand (true)
|
||||
. halign (Start)
|
||||
. build () ,
|
||||
& icon ,
|
||||
icon ,
|
||||
) ;
|
||||
container . set_spacing (20) ;
|
||||
|
||||
|
|
|
@ -1,18 +1,71 @@
|
|||
use libadwaita :: * ;
|
||||
use { gtk4 :: Align :: * , libadwaita :: * , std :: cell :: * } ;
|
||||
|
||||
use crate :: ui :: { * , utility :: * } ;
|
||||
use crate :: { utility :: * , ui :: { * , utility :: * } } ;
|
||||
|
||||
|
||||
|
||||
pub struct FilmSortButton { widget : SplitButton }
|
||||
pub struct FilmSortButton {
|
||||
widget : SplitButton ,
|
||||
previous_sorting : & 'static RefCell < ( FilmsSortedBy , SortingDirection ) > ,
|
||||
}
|
||||
|
||||
impl FilmSortButton {
|
||||
pub fn new () -> Self {
|
||||
let widget = SplitButton :: builder ()
|
||||
. child ( & label ! ("Sort") )
|
||||
. build () ;
|
||||
pub fn new < F : Fn ( FilmsSortedBy , SortingDirection ) + 'static > ( on_sort : F ) -> Self {
|
||||
let list_box = list_box ! (
|
||||
g_box ! (
|
||||
@ orientation : Horizontal , @ spacing : 20 ,
|
||||
label ! ( @ hexpand : true , @ halign : Start , "Name" ) ,
|
||||
icon ! ("view-sort-ascending-symbolic") ,
|
||||
) ,
|
||||
g_box ! (
|
||||
@ orientation : Horizontal , @ spacing : 20 ,
|
||||
label ! ( @ hexpand : true , @ halign : Start , "Release date" ) ,
|
||||
icon ! ("view-sort-ascending-symbolic") ,
|
||||
) ,
|
||||
g_box ! (
|
||||
@ orientation : Horizontal , @ spacing : 20 ,
|
||||
label ! ( @ hexpand : true , @ halign : Start , "Runtime" ) ,
|
||||
icon ! ("view-sort-ascending-symbolic") ,
|
||||
) ,
|
||||
) ;
|
||||
|
||||
Self { widget }
|
||||
let widget = split_button ! (
|
||||
@ popover : popover ! ( @ css_classes : [ "menu" ] , list_box ) ,
|
||||
label ! ("Sort") ,
|
||||
) ;
|
||||
|
||||
let previous_sorting = leak ( RefCell :: new (
|
||||
( FilmsSortedBy :: Name , SortingDirection :: Ascending )
|
||||
) ) ;
|
||||
|
||||
list_box . connect_row_activated ( move | _ , row | {
|
||||
let sorting_property = match row . index () {
|
||||
0 => FilmsSortedBy :: Name ,
|
||||
1 => FilmsSortedBy :: ReleaseDate ,
|
||||
2 => FilmsSortedBy :: Runtime ,
|
||||
_ => panic ! () ,
|
||||
} ;
|
||||
|
||||
let previous_sorting_property = previous_sorting . borrow () . 0 ;
|
||||
if sorting_property == previous_sorting_property {
|
||||
let previous_sorting_direction = previous_sorting . borrow () . 1 ;
|
||||
match previous_sorting_direction {
|
||||
SortingDirection :: Ascending => {
|
||||
previous_sorting . replace ( ( sorting_property , SortingDirection :: Descending ) ) ;
|
||||
on_sort ( sorting_property , SortingDirection :: Descending ) ;
|
||||
} ,
|
||||
SortingDirection :: Descending => {
|
||||
previous_sorting . replace ( ( sorting_property , SortingDirection :: Ascending ) ) ;
|
||||
on_sort ( sorting_property , SortingDirection :: Ascending ) ;
|
||||
} ,
|
||||
}
|
||||
} else {
|
||||
previous_sorting . replace ( ( sorting_property , SortingDirection :: Ascending ) ) ;
|
||||
on_sort ( sorting_property , SortingDirection :: Ascending ) ;
|
||||
}
|
||||
} ) ;
|
||||
|
||||
Self { widget , previous_sorting }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,18 +6,19 @@ use gtk4 :: { * , Orientation :: * , prelude :: * } ;
|
|||
use crate :: {
|
||||
collection :: * ,
|
||||
ui :: {
|
||||
component :: * , utility :: * ,
|
||||
collatable_container :: { collated_grid :: * , collation_menu :: * } ,
|
||||
component :: * ,
|
||||
utility :: * ,
|
||||
} ,
|
||||
utility :: * ,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
# [ derive (PartialEq) ] pub enum FilmsSortedBy { Name , ReleaseDate , Runtime }
|
||||
# [ derive (PartialEq) ] pub enum SeriesSortedBy { Name , FirstReleaseDate }
|
||||
# [ derive (PartialEq) ] pub enum SortingDirection { Ascending , Descending }
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum FilmsSortedBy { Name , ReleaseDate , Runtime }
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum SeriesSortedBy { Name , FirstReleaseDate }
|
||||
# [ derive ( Clone , Copy , PartialEq ) ] pub enum SortingDirection { Ascending , Descending }
|
||||
|
||||
pub struct FilmSorting { property : FilmsSortedBy , direction : SortingDirection }
|
||||
|
||||
pub struct CollatableFilmsContainer {
|
||||
collated_grid : & 'static CollatedFilmsGrid ,
|
||||
|
@ -37,8 +38,8 @@ impl CollatableFilmsContainer {
|
|||
|
||||
let widget = g_box ! (
|
||||
@ orientation : Vertical ,
|
||||
film_collation_menu . get_widget () ,
|
||||
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||
* film_collation_menu . get_widget () ,
|
||||
create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||
) ;
|
||||
|
||||
Self { collated_grid , widget }
|
||||
|
@ -58,8 +59,8 @@ impl CollatableSeriesContainer {
|
|||
|
||||
let widget = g_box ! (
|
||||
@ orientation : Vertical ,
|
||||
series_collation_menu . get_widget () ,
|
||||
& create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||
* series_collation_menu . get_widget () ,
|
||||
create_collection_scrolled_window ( collated_grid . get_widget () ) ,
|
||||
) ;
|
||||
|
||||
Self { collated_grid , widget }
|
||||
|
@ -79,7 +80,7 @@ impl Component <Box> for CollatableSeriesContainer {
|
|||
|
||||
fn create_collection_scrolled_window ( child : & FlowBox ) -> ScrolledWindow {
|
||||
ScrolledWindow :: builder ()
|
||||
. child ( & vertically_filling ! (child) )
|
||||
. child ( & vertically_filling ! ( * child ) )
|
||||
. propagate_natural_height (true)
|
||||
. build ()
|
||||
}
|
||||
|
|
|
@ -3,24 +3,34 @@ macro_rules ! label { (
|
|||
$ ( @ vexpand : $ vexpand : expr , ) ?
|
||||
$ ( @ halign : $ halign : expr , ) ?
|
||||
$ ( @ valign : $ valign : expr , ) ?
|
||||
$ ( $ label : expr ) ? $ (,) ?
|
||||
$ label : expr $ (,) ?
|
||||
) => { {
|
||||
let label = gtk4 :: Label :: builder () . build () ;
|
||||
$ ( label . set_hexpand ( $ hexpand ) ; ) ?
|
||||
$ ( label . set_vexpand ( $ vexpand ) ; ) ?
|
||||
$ ( label . set_halign ( $ halign ) ; ) ?
|
||||
$ ( label . set_valign ( $ valign ) ; ) ?
|
||||
$ ( label . set_label ( $ label ) ; ) ?
|
||||
label . set_label ( $ label ) ;
|
||||
label
|
||||
} } }
|
||||
|
||||
macro_rules ! g_box { (
|
||||
$ ( @ orientation : $ orientation : expr , ) ?
|
||||
$ ( $ child : expr ) , * $ (,) ?
|
||||
$ ( @ halign : $ halign : expr , ) ?
|
||||
$ ( @ valign : $ valign : expr , ) ?
|
||||
$ ( @ spacing : $ spacing : expr , ) ?
|
||||
$ ( @ widget_name : $ widget_name : expr , ) ?
|
||||
$ ( @ css_classes : $ css_classes : expr , ) ?
|
||||
$ ( $ child : expr ) , + $ (,) ?
|
||||
) => { {
|
||||
let container = gtk4 :: Box :: builder () . build () ;
|
||||
$ ( container . set_orientation ( $ orientation ) ; ) ?
|
||||
$ ( container . append ( $ child ) ; ) *
|
||||
$ ( container . set_halign ( $ halign ) ; ) ?
|
||||
$ ( container . set_valign ( $ valign ) ; ) ?
|
||||
$ ( container . set_spacing ( $ spacing ) ; ) ?
|
||||
$ ( container . set_widget_name ( & $ widget_name ) ; ) ?
|
||||
$ ( container . set_css_classes ( & $ css_classes ) ; ) ?
|
||||
$ ( container . append ( & $ child ) ; ) *
|
||||
container
|
||||
} } }
|
||||
|
||||
|
@ -32,17 +42,41 @@ macro_rules ! view_stack { (
|
|||
container
|
||||
} } }
|
||||
|
||||
macro_rules ! list_box { ( $ ( $ child : expr , ) * ) => { {
|
||||
macro_rules ! list_box { ( $ ( $ child : expr ) , * $ (,) ? ) => { {
|
||||
let container = gtk4 :: ListBox :: new () ;
|
||||
$ ( container . append ( $ child ) ; ) *
|
||||
$ ( container . append ( & $ child ) ; ) *
|
||||
container
|
||||
} } }
|
||||
|
||||
macro_rules ! split_button { (
|
||||
$ ( @ popover : $ popover : expr , ) ?
|
||||
$ child : expr $ (,) ?
|
||||
) => { {
|
||||
let widget = libadwaita :: SplitButton :: new () ;
|
||||
$ ( widget . set_popover ( Some ( & $ popover ) ) ; ) ?
|
||||
widget . set_child ( Some ( & $ child ) ) ;
|
||||
widget
|
||||
} } }
|
||||
|
||||
macro_rules ! popover { (
|
||||
$ ( @ css_classes : $ css_classes : expr , ) ?
|
||||
$ child : expr $ (,) ?
|
||||
) => { {
|
||||
let widget = gtk4 :: Popover :: new () ;
|
||||
$ ( widget . set_css_classes ( & $ css_classes ) ; ) ?
|
||||
widget . set_child ( Some ( & $ child ) ) ;
|
||||
widget
|
||||
} } }
|
||||
|
||||
macro_rules ! icon { ( $ icon_name : expr ) => {
|
||||
gtk4 :: Image :: from_icon_name ( $ icon_name )
|
||||
} }
|
||||
|
||||
macro_rules ! vertically_filling { ( $ child : expr ) => {
|
||||
g_box ! (
|
||||
@ orientation : gtk4 :: Orientation :: Vertical ,
|
||||
$ child ,
|
||||
& libadwaita :: Bin :: builder ()
|
||||
libadwaita :: Bin :: builder ()
|
||||
. css_name ("filler")
|
||||
. vexpand (true)
|
||||
. build () ,
|
||||
|
@ -56,5 +90,8 @@ pub (crate) use {
|
|||
g_box ,
|
||||
view_stack ,
|
||||
list_box ,
|
||||
split_button ,
|
||||
popover ,
|
||||
icon ,
|
||||
vertically_filling ,
|
||||
} ;
|
||||
|
|
Loading…
Add table
Reference in a new issue