diff --git a/Cargo.lock b/Cargo.lock index 293ecdf..2c08478 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,6 +549,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "pure-rust-locales", "wasm-bindgen", "windows-targets 0.52.0", ] @@ -2547,6 +2548,12 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "332cd62e95873ea4f41f3dfd6bbbfc5b52aec892d7e8d534197c4720a0bbbab2" +[[package]] +name = "pure-rust-locales" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a" + [[package]] name = "quick-xml" version = "0.31.0" diff --git a/Cargo.toml b/Cargo.toml index 7a7ee3d..321153a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ tracing = ["dep:lttng-ust"] #iced_native = "0.5.1" iced = { path = "../iced", features = ["advanced"] } iced_aw = { path = "../iced_aw", default-features = false, features = ["segmented_button", "tab_bar", "icons"] } -chrono = "0.4" +chrono = { version = "0.4", features = ["unstable-locales"] } lttng-ust = { version = "0.1.0", optional = true } icalendar = "0.15.4" directories = "5.0.1" diff --git a/src/ui/calendar.rs b/src/ui/calendar.rs index 85e9e20..ecc9626 100644 --- a/src/ui/calendar.rs +++ b/src/ui/calendar.rs @@ -12,7 +12,15 @@ use super::basics::CellGrid; use super::row::CalendarRow; use super::row::RowDay; use crate::model::events::{Event, EventsCollection}; -use chrono::{Datelike, Duration, Local, Months, NaiveDate}; +use chrono::{ + Datelike, + Duration, + Local, + Locale, + Months, + NaiveDate, + Weekday +}; use iced::advanced::text::Paragraph as _; // this is necessary to have Paragraph in scope and use its methods use iced::{ advanced::{ @@ -22,15 +30,15 @@ use iced::{ renderer }, mouse, - alignment, + alignment, Border, - Color, - Element, - Length, - Pixels, - Point, - Rectangle, - Size, + Color, + Element, + Length, + Pixels, + Point, + Rectangle, + Size, Theme }; @@ -43,10 +51,6 @@ use lttng_ust::import_tracepoints; #[cfg(feature = "tracing")] import_tracepoints!(concat!(env!("OUT_DIR"), "/tracepoints.rs"), tracepoints); -const MONTH_NAMES: [&str; 12] = [ - "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic", -]; - // 5 weeks plus two extra days is enough to accomodate the longest months of 31 days const YEAR_VIEW_DAYS_PER_ROW: u32 = 5 * 7 + 2; @@ -246,14 +250,15 @@ fn render_events_in_row( //------------------------------------------------------------------------- -fn compute_month_name_width(renderer: &Renderer, bounds: Size, margin: f32, font_size: Pixels) -> f32 +fn compute_month_name_width(renderer: &Renderer, bounds: Size, margin: f32, font_size: Pixels, locale: Locale) -> f32 where Renderer: text::Renderer, { let mut max_month_width = 0.0; - for month_name in MONTH_NAMES { + for month in 1..12 { + let d = NaiveDate::from_ymd_opt(0, month, 1).unwrap(); let paragraph = Renderer::Paragraph::with_text(Text { - content: month_name, + content: d.format_localized("%b", locale).to_string().as_str(), bounds, size: font_size, line_height: LineHeight::default(), @@ -310,6 +315,7 @@ pub struct CalendarView<'a> { events: &'a EventsCollection, row_name_font_size: f32, margin: f32, + locale: Locale, } impl<'a> CalendarView<'a> { @@ -319,13 +325,14 @@ impl<'a> CalendarView<'a> { CalendarViewMode::Month => day.with_day0(0).unwrap(), CalendarViewMode::Year => day.with_month0(0).unwrap().with_day0(0).unwrap() }; - CalendarView { - first_day, - params: params.clone(), - mode, - events, + CalendarView { + first_day, + params: params.clone(), + mode, + events, row_name_font_size: 24.0, margin: 10.0, + locale: Locale::it_IT, } } @@ -340,7 +347,7 @@ impl<'a> CalendarView<'a> { fn get_row_count(&self) -> u32 { match self.mode { CalendarViewMode::Week => 1, // just one week - CalendarViewMode::Month => 6, // one week per row -> max 6 (incomplate) in a month + CalendarViewMode::Month => 6, // one week per row -> max 6 (incomplete) in a month CalendarViewMode::Year => 12, // one month per row } } @@ -357,7 +364,7 @@ impl<'a> CalendarView<'a> { match self.mode { CalendarViewMode::Week => (cal_row.begin.iso_week().week()).to_string(), CalendarViewMode::Month => (cal_row.begin.iso_week().week()).to_string(), - CalendarViewMode::Year => MONTH_NAMES[cal_row.begin.month0() as usize].to_string(), + CalendarViewMode::Year => cal_row.begin.format_localized("%b", self.locale).to_string(), } } @@ -365,7 +372,7 @@ impl<'a> CalendarView<'a> { let sidebar_width = match self.mode { CalendarViewMode::Week => compute_week_num_width(renderer, bounds, self.margin, self.row_name_font_size.into()), CalendarViewMode::Month => compute_week_num_width(renderer, bounds, self.margin, self.row_name_font_size.into()), - CalendarViewMode::Year => compute_month_name_width(renderer, bounds, self.margin, self.row_name_font_size.into()), + CalendarViewMode::Year => compute_month_name_width(renderer, bounds, self.margin, self.row_name_font_size.into(), self.locale), }; // side column only visible if there is enough space if self.params.show_sidebar && bounds.width > sidebar_width { @@ -403,7 +410,7 @@ impl<'a> CalendarView<'a> { // font dimension let font_size = renderer.default_size(); - let days_of_week = ["L", "M", "M", "G", "V", "S", "D"]; + let mut weekday = Weekday::Mon; let grid = CellGrid::new( bounds.x, @@ -421,10 +428,8 @@ impl<'a> CalendarView<'a> { height: cell.height, }; - let weekday = (cell.pos_x as usize) % 7; - // background color of the day cell - let bg_color = if weekday > 4 { + let bg_color = if weekday.number_from_monday() > 5 { self.params.day_weekend_bg } else { Color::TRANSPARENT @@ -443,8 +448,11 @@ impl<'a> CalendarView<'a> { bg_color, ); - // label (day letter on row 0, day number on the rest) - let t = days_of_week[weekday]; + let d = NaiveDate::from_isoywd_opt(2000, 1, weekday).unwrap(); + let mut day_initial = d.format_localized("%a", self.locale).to_string().to_uppercase(); + day_initial.truncate(1); + + weekday = weekday.succ(); // color of text let fg = self.params.header_fg; @@ -453,7 +461,7 @@ impl<'a> CalendarView<'a> { let y = bounds.center_y(); renderer.fill_text( Text { - content: t.to_string(), + content: day_initial, bounds: bounds.size(), size: font_size, line_height: LineHeight::default(), diff --git a/src/ui/controls.rs b/src/ui/controls.rs index 445f708..f4a6c5f 100644 --- a/src/ui/controls.rs +++ b/src/ui/controls.rs @@ -2,7 +2,10 @@ use crate::{ app::Message, calendar::CalendarViewMode as ViewMode }; -use chrono::{NaiveDate, Datelike}; +use chrono::{ + NaiveDate, + Locale, +}; use iced::{ alignment, Alignment, @@ -21,37 +24,24 @@ use iced_aw::widgets::segmented_button::SegmentedButton; //#[derive(Default)] pub struct Controls { pub mode: Option, + locale: Locale, } impl Default for Controls { fn default() -> Controls { Controls { - mode : Some(ViewMode::Year) + mode : Some(ViewMode::Year), + locale: Locale::it_IT, } } } impl Controls { - const MODES : [ViewMode; 3] = [ViewMode::Week, ViewMode::Month, ViewMode::Year]; - const MONTH_NAMES: [&'static str;12] = [ - "gennaio", - "febbraio", - "marzo", - "aprile", - "maggio", - "giugno", - "luglio", - "agosto", - "settembre", - "ottobre", - "novembre", - "dicembre", - ]; - pub fn view<'a>(&'a self, view_date: NaiveDate, year: i32) -> Element { let description = match self.mode { - Some(ViewMode::Month) => Controls::MONTH_NAMES[view_date.month0() as usize], - _ => "" + Some(ViewMode::Month) => view_date.format_localized("%B", self.locale).to_string(), + Some(ViewMode::Week) => view_date.format_localized("%B", self.locale).to_string(), + _ => "".to_string() }; Row::new() .align_items(Alignment::Center)