//! Simple calendar applications. mod ui; mod model; use ui::calendar; use model::events::EventsCollection; use chrono::{Datelike, NaiveDate, Months, Utc}; use calendar::{CalendarMonthView, CalendarYearView, CalendarParams }; use iced::{ alignment, executor, Alignment, Application, Command, Element, Length, Settings, }; use iced::widget::{ Column, Row, Container, Button, Text, pick_list, }; //use iced::button; use iced::theme; pub fn main() -> iced::Result { CalendarApp::run(Settings::default()) } #[derive(Default)] struct CalendarApp { month: NaiveDate, controls: Controls, events: EventsCollection, } #[derive(Debug, Clone, Copy)] enum Message { NextMonth, PrevMonth, ViewModeSelected(ViewMode), } //#[derive(Default)] struct Controls { mode: Option, } impl Default for Controls { fn default() -> Controls { Controls { mode : Some(ViewMode::Year) } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ViewMode { Month, Year, } impl std::fmt::Display for ViewMode { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{}", match self { ViewMode::Month => "Month", ViewMode::Year => "Year", } ) } } impl Controls { const MODES : [ViewMode; 2] = [ViewMode::Month, ViewMode::Year]; fn view<'a>(&'a self, month_name: &'a str, year: i32) -> Element { Row::new() .align_items(Alignment::Center) .padding(5) .spacing(10) .push( pick_list( &Controls::MODES[..], self.mode, Message::ViewModeSelected, ).placeholder("mode") ) .push( Button::new(Text::new("<")) .on_press(Message::PrevMonth) .style(theme::Button::Secondary), ) .push( Button::new(Text::new(">")) .on_press(Message::NextMonth) .style(theme::Button::Secondary), ) .push( Text::new(month_name) .width(Length::Fill) .horizontal_alignment(alignment::Horizontal::Left) .size(40), ) .push( Text::new(year.to_string()) .width(Length::Fill) .horizontal_alignment(alignment::Horizontal::Right) .size(40), ) .into() } } impl Application for CalendarApp { type Executor = executor::Default; type Message = Message; type Theme = iced::Theme; type Flags = (); fn new(_flags: Self::Flags) -> (Self, Command) { let month = Utc::today().naive_local(); (CalendarApp { month, events: EventsCollection::new(), ..CalendarApp::default() }, Command::none()) } fn title(&self) -> String { String::from("Calendar") } fn update(&mut self, message: Message) -> Command { match message { Message::PrevMonth => { self.month = self.month - Months::new(1); } Message::NextMonth => { self.month = self.month + Months::new(1); } Message::ViewModeSelected(mode) => { self.controls.mode = Some(mode); } } Command::none() } fn view(&self) -> Element { const MONTH_NAMES: [&str;12] = [ "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre", ]; let mut content = Column::new() .align_items(Alignment::Center) .push(self.controls.view(MONTH_NAMES[self.month.month0() as usize], self.month.year())) ; match self.controls.mode { Some(ViewMode::Year) => content = content.push(CalendarYearView::new(&CalendarParams::new(), self.month, &self.events)), Some(ViewMode::Month) | None => content = content.push(CalendarMonthView::new(&CalendarParams::new(), self.month, &self.events)), }; Container::new(content) .width(Length::Fill) .height(Length::Fill) .center_x() .center_y() .into() } }