aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2022-02-27 13:25:27 +0100
committerJoris2022-02-27 13:25:27 +0100
commite84d7e08c780133bd16a5a320bb786b5d22fddad (patch)
tree75164f20d5a8200a401862fe081e00a096051838
parenta83697a4d919c2b8307de10f60df5a4ae32f3a69 (diff)
downloadcalendar-e84d7e08c780133bd16a5a320bb786b5d22fddad.tar.gz
calendar-e84d7e08c780133bd16a5a320bb786b5d22fddad.tar.bz2
calendar-e84d7e08c780133bd16a5a320bb786b5d22fddad.zip
Change week with arrow keys
-rw-r--r--README.md1
-rw-r--r--src/gui/calendar.rs12
-rw-r--r--src/gui/form/repetition.rs4
-rw-r--r--src/gui/update.rs51
-rw-r--r--src/model/repetition.rs9
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<Option<Repetition>, 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<Msg>, 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::<HashSet<NaiveDate>>(),
- )
+ 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<NaiveDate>) {
calendar::refresh_date(app, *date, &repetitions)
}
}
+
+/// Seven days vector from the given date.
+fn week_from(date: NaiveDate) -> Vec<NaiveDate> {
+ 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<u32, String> {
- let n = str.parse::<u32>().map_err(|_| format!("{} n’est pas une période valide.", str))?;
+ let n = str
+ .parse::<u32>()
+ .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<u32, String> {
}
}
-
pub fn validate_day(str: &str) -> Result<u8, String> {
- let n = str.parse::<u8>().map_err(|_| format!("« {} » n’est pas un jour valide.", str))?;
+ let n = str
+ .parse::<u8>()
+ .map_err(|_| format!("« {} » n’est pas un jour valide.", str))?;
if (1..=31).contains(&n) {
Ok(n)
} else {