From e84d7e08c780133bd16a5a320bb786b5d22fddad Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 27 Feb 2022 13:25:27 +0100 Subject: Change week with arrow keys --- README.md | 1 - src/gui/calendar.rs | 12 ++++++++++- src/gui/form/repetition.rs | 4 +++- src/gui/update.rs | 51 +++++++++++++++++++++++++++++++--------------- src/model/repetition.rs | 9 +++++--- 5 files changed, 55 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index e52d48c..064fa6d 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ cargo test ## V1 -- Select previous or next week with shortcuts. - Update / delete specific repetition occurences. ## V2 diff --git a/src/gui/calendar.rs b/src/gui/calendar.rs index 918438d..026f86b 100644 --- a/src/gui/calendar.rs +++ b/src/gui/calendar.rs @@ -28,7 +28,17 @@ pub fn create( } let repetitions = event::repetitions_between(repeated_events, start_date, end_date); - attach_days(tx, &grid, start_date, today, events, &repetitions); + attach_days(tx.clone(), &grid, start_date, today, events, &repetitions); + + let event_controller_key = gtk::EventControllerKey::new(); + event_controller_key.connect_key_released(glib::clone!(@strong tx => move |_, _, keycode, _| { + match keycode { + 111 => update::send(tx.clone(), Msg::SelectPreviousWeek), // UP + 116 => update::send(tx.clone(), Msg::SelectNextWeek), // DOWN + _ => () + } + })); + grid.add_controller(&event_controller_key); grid } diff --git a/src/gui/form/repetition.rs b/src/gui/form/repetition.rs index 7236016..accb091 100644 --- a/src/gui/form/repetition.rs +++ b/src/gui/form/repetition.rs @@ -134,7 +134,9 @@ pub fn validate(model: &Model) -> Result, String> { Ok(Some(Repetition::Daily { period })) } else if model.monthly_radio.is_active() { let day = repetition::validate_day(&model.monthly_entry.buffer().text())?; - Ok(Some(Repetition::Monthly { day: DayOfMonth::Day { day } })) + Ok(Some(Repetition::Monthly { + day: DayOfMonth::Day { day }, + })) } else if model.first_day_radio.is_active() { let weekday = WEEKDAYS[model.first_day_dropdown.selected() as usize]; Ok(Some(Repetition::Monthly { diff --git a/src/gui/update.rs b/src/gui/update.rs index 91102bf..c8dfa6d 100644 --- a/src/gui/update.rs +++ b/src/gui/update.rs @@ -1,5 +1,6 @@ use async_channel::{Receiver, Sender}; -use chrono::NaiveDate; +use chrono::{Duration, NaiveDate}; +use gtk4::prelude::GridExt; use std::collections::HashSet; use crate::{ @@ -19,36 +20,45 @@ pub enum Msg { AddEvent { new: Event }, UpdateEvent { old: Event, new: Event }, DeleteEvent { event: Event }, + SelectPreviousWeek, + SelectNextWeek, } pub async fn event_handler(rx: Receiver, mut app: App) { while let Ok(msg) = rx.recv().await { match msg { - Msg::ShowAddForm { date } => { - form::show(&app, event::init(date), true).await; - } - Msg::ShowUpdateForm { event } => { - form::show(&app, event, false).await; - } + Msg::ShowAddForm { date } => form::show(&app, event::init(date), true).await, + Msg::ShowUpdateForm { event } => form::show(&app, event, false).await, Msg::AddEvent { new } => { let refresh_dates = add(&mut app, &new); refresh(&app, &refresh_dates) } Msg::UpdateEvent { old, new } => { - let refresh_dates_1 = remove(&mut app, &old); - let refresh_dates_2 = add(&mut app, &new); - refresh( - &app, - &refresh_dates_1 - .union(&refresh_dates_2) - .copied() - .collect::>(), - ) + let mut refresh_dates = remove(&mut app, &old); + refresh_dates.extend(add(&mut app, &new)); + refresh(&app, &refresh_dates); } Msg::DeleteEvent { event } => { let refresh_dates = remove(&mut app, &event); refresh(&app, &refresh_dates) } + Msg::SelectPreviousWeek => { + app.grid.remove_row(4); + app.grid.insert_row(1); + app.start_date -= Duration::days(7); + app.end_date -= Duration::days(7); + refresh(&app, &HashSet::from_iter(week_from(app.start_date))); + } + Msg::SelectNextWeek => { + app.grid.remove_row(1); + app.grid.insert_row(4); + app.start_date += Duration::days(7); + app.end_date += Duration::days(7); + refresh( + &app, + &HashSet::from_iter(week_from(app.end_date - Duration::days(6))), + ); + } } } } @@ -110,3 +120,12 @@ fn refresh(app: &App, dates: &HashSet) { calendar::refresh_date(app, *date, &repetitions) } } + +/// Seven days vector from the given date. +fn week_from(date: NaiveDate) -> Vec { + let mut res = vec![date]; + for i in 1..=6 { + res.push(date + Duration::days(i)) + } + res +} diff --git a/src/model/repetition.rs b/src/model/repetition.rs index 5288358..2e790d1 100644 --- a/src/model/repetition.rs +++ b/src/model/repetition.rs @@ -15,7 +15,9 @@ pub enum DayOfMonth { } pub fn validate_period(str: &str) -> Result { - let n = str.parse::().map_err(|_| format!("{} n’est pas une période valide.", str))?; + let n = str + .parse::() + .map_err(|_| format!("{} n’est pas une période valide.", str))?; if n == 0 { Err("La periode doit être positive.".to_string()) } else { @@ -23,9 +25,10 @@ pub fn validate_period(str: &str) -> Result { } } - pub fn validate_day(str: &str) -> Result { - let n = str.parse::().map_err(|_| format!("« {} » n’est pas un jour valide.", str))?; + let n = str + .parse::() + .map_err(|_| format!("« {} » n’est pas un jour valide.", str))?; if (1..=31).contains(&n) { Ok(n) } else { -- cgit v1.2.3