add public holidays support (background color of day cell)

This commit is contained in:
Fabrizio Iannetti 2024-06-30 08:26:11 +02:00
parent 281aab2a7e
commit 063a74f6f3
4 changed files with 48 additions and 10 deletions

View File

@ -18,6 +18,11 @@ Clandars are read only from ical files, which are taken:
* from command line if given as arguments
* from `<home>/.local/share/calendars/` if no argument is given
### Public holidays
* calendar files that are named `<name>_bg.ical` are treated as defining public holidays
and rendered by changing the background of the day cell
## planned features
* reload the events from a calendar file if the file changes

View File

@ -3,9 +3,16 @@ use std::vec::Vec;
use std::default::Default;
use std::string::String;
#[derive(Clone, Debug, PartialEq)]
pub enum EventType {
Regular,
Background,
}
#[derive(Clone, Debug)]
pub struct Event {
pub text: String,
pub ev_type: EventType,
pub begin: NaiveDate,
pub end: NaiveDate,
}
@ -43,13 +50,13 @@ impl EventsCollection {
}
}
pub fn create(self: &mut Self, begin: NaiveDate, end: NaiveDate, text: &str) {
self.events.push(Event {text: text.to_string(), begin, end});
pub fn create(self: &mut Self, begin: NaiveDate, end: NaiveDate, text: &str, ev_type: &EventType) {
self.events.push(Event {text: text.to_string(), ev_type: ev_type.clone(), begin, end});
}
pub fn is_any_in_day(&self, day: NaiveDate) -> Option<Event> {
pub fn is_any_in_day(&self, day: NaiveDate, ev_type: &EventType) -> Option<Event> {
for ev_day in &self.events {
if ev_day.is_in_day(day) {
if ev_day.is_in_day(day) && &ev_day.ev_type == ev_type {
return Some(ev_day.clone());
}
}
@ -105,4 +112,4 @@ impl Default for EventsCollection {
fn default() -> EventsCollection {
EventsCollection::new()
}
}
}

View File

@ -5,6 +5,8 @@ use crate::model::events::EventsCollection;
use std::fs;
use log::warn;
use super::events::EventType;
fn cdt_as_date(cdt: &CalendarDateTime) -> NaiveDate {
match cdt {
CalendarDateTime::Floating(ndt) => ndt.date(),
@ -20,8 +22,12 @@ fn as_date(cal_date: &DatePerhapsTime) -> NaiveDate {
}
}
fn create_event(events: &mut EventsCollection, event: &icalendar::Event) {
events.create(as_date(&event.get_start().unwrap()), as_date(&event.get_end().unwrap()).pred_opt().unwrap(), event.get_summary().unwrap());
fn create_event(events: &mut EventsCollection, event: &icalendar::Event, ev_type: &EventType) {
events.create(
as_date(&event.get_start().unwrap()),
as_date(&event.get_end().unwrap()).pred_opt().unwrap(),
event.get_summary().unwrap(),
ev_type);
}
pub fn load_calendar(calendar_path: &std::path::Path, events: &mut EventsCollection) {
@ -38,9 +44,19 @@ pub fn load_calendar(calendar_path: &std::path::Path, events: &mut EventsCollect
Err(e) => { warn!("Error parsing calendar {}", e); return; }
}
let stem = calendar_path.file_stem().unwrap().to_str().unwrap_or("");
// TODO: keep it simple for now, just use a filename coding
let ev_type = if stem.ends_with("_bg") {
EventType::Background
}
else {
EventType::Regular
};
for cc in calendar.iter() {
match cc {
CalendarComponent::Event(event) => create_event(events, event),
CalendarComponent::Event(event) => create_event(events, event, &ev_type),
_ => (),
}
}

View File

@ -11,6 +11,7 @@
use super::basics::CellGrid;
use super::row::CalendarRow;
use super::row::RowDay;
use crate::model::events::EventType;
use crate::model::events::{Event, EventsCollection};
use chrono::{
Datelike,
@ -70,6 +71,7 @@ pub struct CalendarParams {
ev_height: f32,
ev_margin: f32,
ev_bg: Color,
ev_bg_alt: Color,
ev_fontsize: f32,
}
@ -87,6 +89,7 @@ impl CalendarParams {
ev_height: 18.0,
ev_margin: 2.0,
ev_bg: Color::from_rgb8(200, 245, 200),
ev_bg_alt: Color::from_rgb8(215, 215, 215), //Color::from_rgb8(200, 200, 250),
ev_fontsize: 14.0,
}
}
@ -129,6 +132,7 @@ fn render_events_in_row<Renderer>(
struct EventBar<'a> {
ev: &'a Event,
bounds: Rectangle,
bg: Color,
}
let paragraph = Renderer::Paragraph::with_text(Text {
content,
@ -154,6 +158,7 @@ fn render_events_in_row<Renderer>(
let mut ev_bars: Vec<EventBar> = all_events
.iter()
.filter(|e| e.ev_type == EventType::Regular)
.map(|e| EventBar {
ev: e,
bounds: Rectangle {
@ -162,6 +167,7 @@ fn render_events_in_row<Renderer>(
width: 0.0,
height: ev_height,
},
bg: params.ev_bg,
})
.collect();
@ -215,7 +221,7 @@ fn render_events_in_row<Renderer>(
},
..renderer::Quad::default()
},
params.ev_bg,
ev_bar.bg,
);
let ev_text_size = Size {
height: ev_bar.bounds.height - 2.0,
@ -576,7 +582,11 @@ impl<'a> CalendarView<'a> {
let fg = self.params.day_fg;
// background color of the day cell
let bg_color = self.params.bg_for_day(current_day);
let bg_color = if self.events.is_any_in_day(current_day, &EventType::Background).is_some() {
self.params.ev_bg_alt
} else {
self.params.bg_for_day(current_day)
};
renderer.fill_quad(
renderer::Quad {