use iced::{ alignment, widget::{column, row, Container}, Length, }; use schist_models::Bucket; use crate::{ gui::components::{navigation, BucketNavigationEntry, Navigation, Text}, style::SPACING_LG, traits::{Component, Viewable}, }; #[derive(Clone, Debug)] pub struct BucketsView { greeting: String, navigation: Navigation, } #[derive(Clone, Debug)] pub enum Message { NavigationMessage(navigation::Message), SelectNext, SelectPrev, SetBuckets(Vec), } pub enum Action { None, } impl BucketsView { pub fn new(groups: Vec, greeting: &str) -> Self { Self { greeting: greeting.to_owned(), navigation: Navigation::new( groups .first() .map(String::as_str) .map(BucketNavigationEntry::from_group_closed), groups .iter() .map(String::as_str) .map(BucketNavigationEntry::from_group_closed) .collect(), ), } } pub fn active_group(&self) -> Option { self.navigation .active_option .as_ref() .map(|active_option| active_option.group()) } fn update_greeting(&mut self, active_entry: &str) { self.greeting = format!("Hello, {}!", active_entry); } } impl<'a> Viewable<'a, Message> for BucketsView { fn view(&'a self) -> iced::Element<'a, Message> where Message: 'a, { let navigation = self.navigation.view().map(Message::NavigationMessage); let main_content = column![Text::default(&self.greeting).as_element()]; row![ Container::new(navigation).width(Length::FillPortion(1)), Container::new(main_content).width(Length::FillPortion(3)), ] .align_y(alignment::Vertical::Center) .height(Length::Fill) .spacing(SPACING_LG) .into() } } impl<'a> Component<'a, Message, Action> for BucketsView { fn update(&mut self, message: Message) -> Action { match message { Message::SetBuckets(buckets) => { let groups: Vec = buckets .iter() .map(|bucket| bucket.group.as_str()) .unique() .map(BucketNavigationEntry::from_group_closed) .collect(); match self .navigation .update(navigation::Message::SetOptions(groups)) { navigation::Action::SelectOption(bucket_navigation_entry) => { self.update_greeting(&bucket_navigation_entry.to_string()); Action::None } navigation::Action::None => Action::None, } } Message::NavigationMessage(message) => match self.navigation.update(message) { navigation::Action::SelectOption(bucket_navigation_entry) => { self.update_greeting(&bucket_navigation_entry.to_string()); Action::None } navigation::Action::None => Action::None, }, Message::SelectNext => match self.navigation.update(navigation::Message::SelectNext) { navigation::Action::SelectOption(bucket_navigation_entry) => { self.update_greeting(&bucket_navigation_entry.to_string()); Action::None } navigation::Action::None => Action::None, }, Message::SelectPrev => match self.navigation.update(navigation::Message::SelectPrev) { navigation::Action::SelectOption(bucket_navigation_entry) => { self.update_greeting(&bucket_navigation_entry.to_string()); Action::None } navigation::Action::None => Action::None, }, } } }