diff options
author | Joris | 2022-01-09 13:12:45 +0100 |
---|---|---|
committer | Joris | 2022-01-09 13:12:45 +0100 |
commit | 99af88a840bef534540a4b273d24a8a17e7fc9b9 (patch) | |
tree | 20bda6c9eccd66d0c165e1f5d42fe76f80be58d2 /src/app/calendar.rs | |
parent | bd59a5128c05dcd550e91bbdd0cd9d5996a65586 (diff) |
Split app into modules
Diffstat (limited to 'src/app/calendar.rs')
-rw-r--r-- | src/app/calendar.rs | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/app/calendar.rs b/src/app/calendar.rs new file mode 100644 index 0000000..847ea71 --- /dev/null +++ b/src/app/calendar.rs @@ -0,0 +1,157 @@ +use gtk4 as gtk; + +use async_channel::Sender; +use chrono::{Datelike, NaiveDate}; +use gtk::glib; +use gtk::prelude::*; + +use crate::{app::update, app::update::Msg, model::event::Event}; + +static DAYS: [&str; 7] = ["LUN", "MAR", "MER", "JEU", "VEN", "SAM", "DIM"]; +static MONTHES: [&str; 12] = [ + "Jan", "Fév", "Mar", "Avr", "Mai", "Juin", "Juil", "Aoû", "Sep", "Oct", "Nov", "Déc", +]; + +pub fn grid( + tx: Sender<Msg>, + today: &NaiveDate, + start_date: &NaiveDate, + events: &Vec<Event>, +) -> gtk::Grid { + let grid = gtk::Grid::builder().build(); + + for col in 0..7 { + grid.attach(&day_title(col), col, 0, 1, 1); + } + + show_days(tx, &grid, &start_date, &today, &events); + + grid +} + +fn show_days( + tx: Sender<Msg>, + grid: >k::Grid, + start_date: &NaiveDate, + today: &NaiveDate, + events: &Vec<Event>, +) { + let mut d = *start_date; + for row in 1..5 { + for col in 0..7 { + grid.attach(&day_entry(tx.clone(), &d, &today, &events), col, row, 1, 1); + d = d.succ(); + } + } +} + +fn day_title(col: i32) -> gtk::Box { + let vbox = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .build(); + + vbox.add_css_class("g-Calendar__DayTitle"); + + let label = gtk::Label::builder().label(DAYS[col as usize]).build(); + + vbox.append(&label); + + vbox +} + +pub fn day_entry( + tx: Sender<Msg>, + date: &NaiveDate, + today: &NaiveDate, + events: &Vec<Event>, +) -> gtk::ScrolledWindow { + let vbox = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .build(); + + vbox.add_css_class("g-Calendar__Day"); + + let gesture = gtk::GestureClick::new(); + gesture.connect_pressed(glib::clone!(@strong date => move |_, n, _, _| { + if n == 2 { + update::send(tx.clone(), Msg::ShowAddForm { date }); + } + })); + vbox.add_controller(&gesture); + + if date == today { + vbox.add_css_class("g-Calendar__Day--Today"); + } + + vbox.append(&day_label(date)); + + let mut events = events + .iter() + .filter(|e| e.date == *date) + .collect::<Vec<&Event>>(); + events.sort_by_key(|e| e.start); + + if !events.is_empty() { + vbox.append(&day_events(events)); + } + + let scrolled_window = gtk::ScrolledWindow::builder() + .hscrollbar_policy(gtk::PolicyType::Never) + .hexpand(true) + .vexpand(true) + .child(&vbox) + .build(); + + scrolled_window +} + +fn day_label(date: &NaiveDate) -> gtk::Label { + let label = gtk::Label::builder() + .label(&format!( + "{} {}", + date.day(), + MONTHES[date.month0() as usize] + )) + .halign(gtk::Align::Start) + .build(); + + label.add_css_class("g-Calendar__DayNumber"); + + label +} + +fn day_events(events: Vec<&Event>) -> gtk::Box { + let vbox = gtk::Box::builder() + .orientation(gtk::Orientation::Vertical) + .build(); + + for event in events { + let hbox = gtk::Box::builder() + .orientation(gtk::Orientation::Horizontal) + .hexpand(true) + .build(); + + let gesture = gtk::GestureClick::new(); + let click_event = event.clone(); + gesture.connect_pressed(move |gesture, _, _, _| { + gesture.set_state(gtk::EventSequenceState::Claimed); + println!("Click: {:?}", click_event); + }); + hbox.add_controller(&gesture); + + hbox.add_css_class("g-Calendar__DayEvent"); + + let event_txt = &event.pprint(); + let label = gtk::Label::builder() + .label(&event_txt) + .ellipsize(gtk::pango::EllipsizeMode::End) + .tooltip_text(&event_txt) + .halign(gtk::Align::Start) + .build(); + + hbox.append(&label); + vbox.append(&hbox); + } + + vbox +} |