improv(calendar): simplify message handling

This commit is contained in:
Eduardo Flores 2024-03-15 05:39:03 -07:00 committed by Michael Murphy
parent ccb0dbed65
commit 5d600c70c2
2 changed files with 28 additions and 42 deletions

View file

@ -18,9 +18,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
/// Messages that are used specifically by our [`App`]. /// Messages that are used specifically by our [`App`].
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Message { pub enum Message {
PrevMonth, DateSelected(NaiveDate),
NextMonth,
DaySelected(u32),
} }
/// The [`App`] stores application-specific state. /// The [`App`] stores application-specific state.
@ -68,17 +66,13 @@ impl cosmic::Application for App {
/// Handle application events here. /// Handle application events here.
fn update(&mut self, message: Self::Message) -> Command<Self::Message> { fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
match message { match message {
Message::DaySelected(day) => { Message::DateSelected(date) => {
cosmic::widget::calendar::set_day(&mut self.date_selected, day); self.date_selected = date;
}
Message::PrevMonth => {
cosmic::widget::calendar::set_prev_month(&mut self.date_selected);
}
Message::NextMonth => {
cosmic::widget::calendar::set_next_month(&mut self.date_selected);
} }
} }
println!("Date selected: {:?}", self.date_selected);
Command::none() Command::none()
} }
@ -86,12 +80,8 @@ impl cosmic::Application for App {
fn view(&self) -> Element<Self::Message> { fn view(&self) -> Element<Self::Message> {
let mut content = cosmic::widget::column().spacing(12); let mut content = cosmic::widget::column().spacing(12);
let calendar = cosmic::widget::calendar( let calendar =
&self.date_selected, cosmic::widget::calendar(&self.date_selected, |date| Message::DateSelected(date));
Message::PrevMonth,
Message::NextMonth,
|day| Message::DaySelected(day),
);
content = content.push(calendar); content = content.push(calendar);

View file

@ -10,19 +10,15 @@ use iced::alignment::{Horizontal, Vertical};
pub fn calendar<M>( pub fn calendar<M>(
selected: &NaiveDate, selected: &NaiveDate,
on_prev_month: M, on_select: impl Fn(NaiveDate) -> M + 'static,
on_next_month: M,
on_select: impl Fn(u32) -> M + 'static,
) -> Calendar<M> { ) -> Calendar<M> {
Calendar { Calendar {
selected, selected,
on_prev_month,
on_next_month,
on_select: Box::new(on_select), on_select: Box::new(on_select),
} }
} }
pub fn set_day(date_selected: &mut NaiveDate, day: u32) { pub fn set_day(date_selected: NaiveDate, day: u32) -> NaiveDate {
let current = date_selected.day(); let current = date_selected.day();
let new_date = match current.cmp(&day) { let new_date = match current.cmp(&day) {
@ -34,27 +30,27 @@ pub fn set_day(date_selected: &mut NaiveDate, day: u32) {
}; };
if let Some(new) = new_date { if let Some(new) = new_date {
*date_selected = new; new
} else {
date_selected
} }
} }
pub fn set_prev_month(date_selected: &mut NaiveDate) { pub fn set_prev_month(date_selected: NaiveDate) -> NaiveDate {
*date_selected = date_selected date_selected
.checked_sub_months(Months::new(1)) .checked_sub_months(Months::new(1))
.expect("valid naivedate"); .expect("valid naivedate")
} }
pub fn set_next_month(date_selected: &mut NaiveDate) { pub fn set_next_month(date_selected: NaiveDate) -> NaiveDate {
*date_selected = date_selected date_selected
.checked_add_months(Months::new(1)) .checked_add_months(Months::new(1))
.expect("valid naivedate"); .expect("valid naivedate")
} }
pub struct Calendar<'a, M> { pub struct Calendar<'a, M> {
selected: &'a NaiveDate, selected: &'a NaiveDate,
on_prev_month: M, on_select: Box<dyn Fn(NaiveDate) -> M>,
on_next_month: M,
on_select: Box<dyn Fn(u32) -> M>,
} }
impl<'a, Message> From<Calendar<'a, Message>> for crate::Element<'a, Message> impl<'a, Message> From<Calendar<'a, Message>> for crate::Element<'a, Message>
@ -69,12 +65,12 @@ where
.push( .push(
button::icon(icon::from_name("go-previous-symbolic")) button::icon(icon::from_name("go-previous-symbolic"))
.padding([0, 12]) .padding([0, 12])
.on_press(this.on_prev_month), .on_press((this.on_select)(set_prev_month(this.selected.clone()))),
) )
.push( .push(
button::icon(icon::from_name("go-next-symbolic")) button::icon(icon::from_name("go-next-symbolic"))
.padding([0, 12]) .padding([0, 12])
.on_press(this.on_next_month), .on_press((this.on_select)(set_next_month(this.selected.clone()))),
); );
// Calender // Calender
@ -111,7 +107,7 @@ where
let is_day = date.day() == this.selected.day() && is_month; let is_day = date.day() == this.selected.day() && is_month;
calendar_grid = calendar_grid =
calendar_grid.push(date_button(date.day(), is_month, is_day, &this.on_select)); calendar_grid.push(date_button(date, is_month, is_day, &this.on_select));
} }
let content_list = column::with_children(vec![ let content_list = column::with_children(vec![
@ -133,19 +129,19 @@ where
} }
fn date_button<Message>( fn date_button<Message>(
day: u32, date: NaiveDate,
is_month: bool, is_month: bool,
is_day: bool, is_day: bool,
on_select: &dyn Fn(u32) -> Message, on_select: &dyn Fn(NaiveDate) -> Message,
) -> crate::widget::Button<'static, Message, crate::Theme, crate::Renderer> { ) -> crate::widget::Button<'static, Message, crate::Theme, crate::Renderer> {
let style = if is_day { let style = if is_day {
crate::widget::button::Style::Suggested button::Style::Suggested
} else { } else {
crate::widget::button::Style::Text button::Style::Text
}; };
let button = button( let button = button(
text(format!("{day}")) text(format!("{}", date.day()))
.horizontal_alignment(Horizontal::Center) .horizontal_alignment(Horizontal::Center)
.vertical_alignment(Vertical::Center), .vertical_alignment(Vertical::Center),
) )
@ -154,7 +150,7 @@ fn date_button<Message>(
.width(Length::Fixed(36.0)); .width(Length::Fixed(36.0));
if is_month { if is_month {
button.on_press((on_select)(day)) button.on_press((on_select)(set_day(date, date.day())))
} else { } else {
button button
} }