diff --git a/Cargo.lock b/Cargo.lock index 37105b7..e6757f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -292,10 +292,10 @@ dependencies = [ ] [[package]] -name = "copyless" -version = "0.1.5" +name = "const_panic" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" +checksum = "9ed2b28323eee4fb66bb824401daa3e46bd445b9a9298a3d382b320710ba69dd" [[package]] name = "core-foundation" @@ -520,6 +520,38 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +[[package]] +name = "encase" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a516181e9a36e8982cb37933c5e7dba638c42938cacde46ee4e5b4156f881b9" +dependencies = [ + "const_panic", + "encase_derive", + "glam", + "thiserror", +] + +[[package]] +name = "encase_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5b802412eea315f29f2bb2da3a5963cd6121f56eaa06aebcdc0c54eea578f22" +dependencies = [ + "encase_derive_impl", +] + +[[package]] +name = "encase_derive_impl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2f4de457d974f548d2c2a16f709ebd81013579e543bd1a9b19ced88132c2cf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "error-code" version = "2.3.1" @@ -760,12 +792,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.10.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579160312273c954cc51bd440f059dde741029ac8daf8c84fece76cb77f62c15" -dependencies = [ - "version_check", -] +checksum = "518faa5064866338b013ff9b2350dc318e14cc4fcd6cb8206d7e7c9886c98815" [[package]] name = "glow" @@ -912,7 +941,7 @@ dependencies = [ [[package]] name = "iced" -version = "0.4.2" +version = "0.5.2" dependencies = [ "iced_core", "iced_futures", @@ -925,7 +954,7 @@ dependencies = [ [[package]] name = "iced_core" -version = "0.5.0" +version = "0.6.1" dependencies = [ "bitflags", "palette", @@ -934,7 +963,7 @@ dependencies = [ [[package]] name = "iced_futures" -version = "0.4.1" +version = "0.5.1" dependencies = [ "futures", "log", @@ -944,19 +973,21 @@ dependencies = [ [[package]] name = "iced_graphics" -version = "0.3.1" +version = "0.4.0" dependencies = [ + "bitflags", "bytemuck", "glam", "iced_native", "iced_style", - "raw-window-handle 0.4.3", + "log", + "raw-window-handle 0.5.0", "thiserror", ] [[package]] name = "iced_native" -version = "0.5.1" +version = "0.6.1" dependencies = [ "iced_core", "iced_futures", @@ -968,34 +999,35 @@ dependencies = [ [[package]] name = "iced_style" -version = "0.4.0" +version = "0.5.0" dependencies = [ "iced_core", - "lazy_static", + "once_cell", "palette", ] [[package]] name = "iced_wgpu" -version = "0.5.1" +version = "0.6.1" dependencies = [ "bitflags", "bytemuck", + "encase", "futures", + "glam", "glyph_brush", "guillotiere", "iced_graphics", "iced_native", - "kamadak-exif", "log", - "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", "wgpu", "wgpu_glyph", ] [[package]] name = "iced_winit" -version = "0.4.0" +version = "0.5.1" dependencies = [ "iced_futures", "iced_graphics", @@ -1024,12 +1056,6 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "inplace_it" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67f0347836f3f6362c1e7efdadde2b1c4b4556d211310b70631bae7eb692070b" - [[package]] name = "instant" version = "0.1.12" @@ -1050,22 +1076,13 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kamadak-exif" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70494964492bf8e491eb3951c5d70c9627eb7100ede6cc56d748b9a3f302cfb6" -dependencies = [ - "mutate_once", -] - [[package]] name = "khronos-egl" version = "4.1.0" @@ -1198,17 +1215,11 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "mutate_once" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" - [[package]] name = "naga" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f50357e1167a3ab92d6b3c7f4bf5f7fd13fde3f4b28bf0d5ea07b5100fdb6c0" +checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" dependencies = [ "bit-set", "bitflags", @@ -1408,9 +1419,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "ordered-float" @@ -2045,9 +2056,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2055,9 +2066,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", "log", @@ -2070,9 +2081,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -2082,9 +2093,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2092,9 +2103,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -2105,9 +2116,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.82" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasm-timer" @@ -2199,9 +2210,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.59" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2209,17 +2220,18 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "277e967bf8b7820a76852645a6bce8bbd31c32fda2042e82d8e3ea75fda8892d" +checksum = "c2272b17bffc8a0c7d53897435da7c1db587c87d3a14e8dae9cdb8d1d210fc0f" dependencies = [ "arrayvec 0.7.2", "js-sys", "log", "naga", "parking_lot 0.12.1", - "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", "smallvec", + "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2230,22 +2242,21 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.13.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b92788dec9d0c1bed849a1b83f01b2ee12819bf04a79c90f68e4173f7b5ba2" +checksum = "73d14cad393054caf992ee02b7da6a372245d39a484f7461c1f44f6f6359bd28" dependencies = [ "arrayvec 0.7.2", "bit-vec", "bitflags", "cfg_aliases", "codespan-reporting", - "copyless", "fxhash", "log", "naga", "parking_lot 0.12.1", "profiling", - "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", "smallvec", "thiserror", "web-sys", @@ -2255,9 +2266,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.13.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cbdfc3d0637dba3d5536b93adef3d26023a0b96f0e1ee5ee9560a401d9f646" +checksum = "3cc320a61acb26be4f549c9b1b53405c10a223fbfea363ec39474c32c348d12f" dependencies = [ "android_system_properties", "arrayvec 0.7.2", @@ -2272,7 +2283,6 @@ dependencies = [ "glow", "gpu-alloc", "gpu-descriptor", - "inplace_it", "js-sys", "khronos-egl", "libloading", @@ -2283,8 +2293,9 @@ dependencies = [ "parking_lot 0.12.1", "profiling", "range-alloc", - "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", "renderdoc-sys", + "smallvec", "thiserror", "wasm-bindgen", "web-sys", @@ -2294,18 +2305,18 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.13.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f762cbc08e1a51389859cf9c199c7aef544789cf3510889aab12c607f701604" +checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" dependencies = [ "bitflags", ] [[package]] name = "wgpu_glyph" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "362152ff06b11372ddfdfc706606fb0f3b6f1b540f017675443a61d074a0a5df" +checksum = "0cafb82773e0f124a33674dab5de4dff73175aeb921949047ab014efb58fb446" dependencies = [ "bytemuck", "glyph_brush", diff --git a/doc/architecture.uxf b/doc/architecture.uxf new file mode 100644 index 0000000..28fa032 --- /dev/null +++ b/doc/architecture.uxf @@ -0,0 +1,16 @@ + + + + 10 + + UMLClass + + 20 + 20 + 100 + 30 + + SimpleClass + + + diff --git a/src/main.rs b/src/main.rs index 2c09df0..cf78e35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ //! Simple calendar applications. -mod calendar; +mod ui; +use ui::calendar; use chrono::{Datelike, NaiveDate, Months, Utc}; -use calendar::{CalendarMonthView, CalendarParams }; +use calendar::{CalendarMonthView, CalendarYearView, CalendarParams }; use iced::{ Alignment, @@ -42,7 +43,7 @@ struct Controls { impl Default for Controls { fn default() -> Controls { Controls { - mode : Some(ViewMode::Month) + mode : Some(ViewMode::Year) } } } @@ -51,7 +52,6 @@ impl Default for Controls { pub enum ViewMode { Month, Year, - Day, } impl std::fmt::Display for ViewMode { @@ -62,13 +62,13 @@ impl std::fmt::Display for ViewMode { match self { ViewMode::Month => "Month", ViewMode::Year => "Year", - ViewMode::Day => "Day", +// ViewMode::Day => "Day", } ) } } impl Controls { - const MODES : [ViewMode; 3] = [ViewMode::Month, ViewMode::Year, ViewMode::Day]; + const MODES : [ViewMode; 2] = [ViewMode::Month, ViewMode::Year]; fn view<'a>(&'a self, month_name: &'a str, year: i32) -> Element { Row::new() @@ -135,7 +135,6 @@ impl Sandbox for CalendarApp { self.controls.mode = Some(mode); } } - //println!("month={}", self.month); } fn view(&self) -> Element { @@ -153,21 +152,16 @@ impl Sandbox for CalendarApp { "novembre", "dicembre", ]; - let content = Column::new() + let mut content = Column::new() .align_items(Alignment::Fill) .push(self.controls.view(MONTH_NAMES[self.month.month0() as usize], self.month.year())) - .push(CalendarMonthView::new(&CalendarParams::new(), self.month)) ; -// let area = Row::new() -// .align_items(Alignment::Fill) -// .push(Column::new() -// .align_items(Alignment::Start) -// .push(CalendarMonthView::new(6)) -// .push(CalendarMonthView::new(6)) -// ) -// .push(content) -// ; + match self.controls.mode { + Some(ViewMode::Year) => content = content.push(CalendarYearView::new(&CalendarParams::new(), self.month)), + Some(ViewMode::Month) | None => content = content.push(CalendarMonthView::new(&CalendarParams::new(), self.month)), + }; + Container::new(content) .width(Length::Fill) .height(Length::Fill) @@ -175,4 +169,4 @@ impl Sandbox for CalendarApp { .center_y() .into() } -} \ No newline at end of file +} diff --git a/src/calendar.rs b/src/ui/calendar.rs similarity index 52% rename from src/calendar.rs rename to src/ui/calendar.rs index 0f23c4a..3221bed 100644 --- a/src/calendar.rs +++ b/src/ui/calendar.rs @@ -16,7 +16,20 @@ use iced_native::alignment; use iced_native::widget::Tree; use chrono::{NaiveDate, Datelike, Duration, Weekday, Local}; -//use std::cmp; +const MONTH_NAMES: [&str;12] = [ + "gen", + "feb", + "mar", + "apr", + "mag", + "giu", + "lug", + "ago", + "set", + "ott", + "nov", + "dic", +]; //------------------------------------------------------------------------- @@ -358,7 +371,329 @@ impl<'a, Message, Renderer> From for Element<'a, Message, Ren where Renderer: text::Renderer, { - fn from(circle: CalendarMonthView) -> Self { - Self::new(circle) + fn from(month_view: CalendarMonthView) -> Self { + Self::new(month_view) + } +} + +//------------------------------------------------------------------------- + +pub struct CalendarYearView { + first_day: NaiveDate, + first_day_in_view: NaiveDate, + params: CalendarParams, + weekday_on_first: Weekday, + month_column_font_size: f32, + margin: f32, +} + +impl CalendarYearView { + pub fn new(params: &CalendarParams, day: NaiveDate) -> Self { + // first day of the year + let first_day = NaiveDate::from_ymd(day.year(), 1, 1); + + // weekday on first day of the year + let weekday_on_first = first_day.weekday(); + + // first visible day in the view + let first_day_in_view = first_day - Duration::days(weekday_on_first.num_days_from_monday() as i64); + + Self { + first_day, + first_day_in_view, + params: params.clone(), + weekday_on_first, + month_column_font_size: 24.0, + margin: 10.0 + } + } + + pub fn set_year(&mut self, day: NaiveDate) { + // first day of the year + self.first_day = NaiveDate::from_ymd(day.year(), 1, 1); + + // weekday on first day of the year + self.weekday_on_first = self.first_day.weekday(); + + // first visible day in the view + self.first_day_in_view = self.first_day - Duration::days(self.weekday_on_first.num_days_from_monday() as i64); + } + + fn draw_header( + &self, + renderer: &mut impl text::Renderer, + bounds: Rectangle, + week_w: f32, + ) { + // paint background over full width + if self.params.header_bg != Color::TRANSPARENT { + renderer.fill_quad(renderer::Quad { + bounds, + border_radius: 0.0, + border_width: 0.0, + border_color: Color::TRANSPARENT, + }, + self.params.header_bg); + } + + // redefine bounds to skip the week column + let bounds = Rectangle { + x: bounds.x + week_w, + y: bounds.y, + width: bounds.width - week_w, + height: bounds.height}; + + let origin = bounds.position(); + + // font dimension + let font_size = renderer.default_size() as f32; + + // dimensions of each box representing a day + let w: f32 = bounds.width / (7.0 * 6.0); + let h: f32 = bounds.height; + + let days_of_week = ["L", "M", "M", "G", "V", "S", "D"]; + + for col in 0..42i32 { + let bounds = Rectangle { + x: (col as f32) * w + origin.x, + y: origin.y, + width: w, + height: h + }; + + let weekday = (col as usize) % 7; + + // background color of the day cell + let bg_color = if weekday > 4 { + self.params.day_weekend_bg + } else { + Color::TRANSPARENT + }; + + renderer.fill_quad(renderer::Quad { + bounds, + border_radius: 0.0, + border_width: 1.0, + border_color: Color::TRANSPARENT, + }, + bg_color); + + // label (day letter on row 0, day number on the rest) + let t = days_of_week[weekday]; + + // color of text + let fg = self.params.header_fg; + + let x = bounds.x + self.params.day_text_margin; + let y = bounds.center_y(); + renderer.fill_text(text::Text { + content : t, + size: font_size, + bounds: Rectangle {x, y, ..bounds}, + color: fg, + font: Default::default(), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + }); + } + } + + fn draw_month_column( + &self, + renderer: &mut impl text::Renderer, + bounds: Rectangle, + ) { + // dimensions of each box representing a month name + let h: f32 = bounds.height / 12.0; + + for month in 0..12usize { + // where to place the month name + let month_name_bounds = Rectangle { + x: bounds.x, + y: (month as f32) * h + bounds.y + self.params.day_text_margin, + width: bounds.width, + height: h + }; + + // render month name + renderer.fill_text(text::Text { + content : MONTH_NAMES[month], + size: self.month_column_font_size, + bounds: Rectangle { + x: month_name_bounds.x + self.margin, + y: month_name_bounds.center_y(), + ..month_name_bounds + }, + color: self.params.day_text, + font: Default::default(), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + }); + } + } + + fn draw_days( + &self, + renderer: &mut impl text::Renderer, + bounds: Rectangle, + ) { + let size: Size = bounds.size(); + let origin = bounds.position(); + + // font dimension + let font_size = renderer.default_size() as f32; + + // dimensions of each box representing a day + let w: f32 = size.width / 42.0; + let h: f32 = size.height / 12.0; + + for current_day in self.first_day.iter_days() { + if current_day.year() != self.first_day.year() { + break; + } + let month = current_day.month0(); + let weekday = current_day.weekday().num_days_from_monday(); + let first_day_of_month = current_day.with_day0(0).unwrap().weekday().num_days_from_monday(); + let monthday = current_day.day0() + first_day_of_month; + let day_bounds = Rectangle { + x: (monthday as f32) * w + origin.x, + y: (month as f32) * h + origin.y, + width: w, + height: h + }; + + + // label (day letter on row 0, day number on the rest) + let t = current_day.day().to_string(); + let content = t.as_str(); + + // color of text + let fg = self.params.day_text; + + // background color of the day cell + let bg_color = if current_day == Local::today().naive_local() { + self.params.day_today_bg + } else if weekday > 4 { + self.params.day_weekend_bg + } else { + Color::TRANSPARENT + }; + + // where to place the day content + let x = day_bounds.x + self.params.day_text_margin; + let y = day_bounds.y + self.params.day_text_margin; + + renderer.fill_quad(renderer::Quad { + bounds: Rectangle {width: day_bounds.width + 0.5, height: day_bounds.height + 0.5, ..day_bounds}, + border_radius: 0.0, + border_width: 1.0, + border_color: self.params.day_text_other_month, + }, + bg_color); + + // render day cell text + renderer.fill_text(text::Text { + content, + size: font_size, + bounds: Rectangle {x, y, ..day_bounds}, + color: fg, + font: Default::default(), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Top, + }); + } + } + + fn compute_month_col_width(&self, renderer: &mut impl text::Renderer) -> f32 { + let mut max_max_font_width = 0.0; + for month_name in MONTH_NAMES { + let month_width = renderer.measure_width(month_name, self.month_column_font_size as u16, Default::default()); + if month_width > max_max_font_width { + max_max_font_width = month_width; + } + } + return max_max_font_width; + } + +} // CalendarYearView + +impl Widget for CalendarYearView +where + Renderer: text::Renderer, +{ + fn width(&self) -> Length { + Length::Shrink + } + + fn height(&self) -> Length { + Length::Shrink + } + + fn layout( + &self, + _renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + layout::Node::new(limits.max()) + } + + fn draw( + &self, + _state: &Tree, + renderer: &mut Renderer, + _theme: &Renderer::Theme, + _style: &renderer::Style, + layout: Layout<'_>, + _cursor_position: Point, + _viewport: &Rectangle, + ) { + let size: Size = layout.bounds().size(); + let origin = layout.bounds().position(); + let margin: f32 = 20.0; + + // week column only visible if there is enough space + let month_w = if self.params.show_weeks { + //self.month_column_width + self.compute_month_col_width(renderer) + self.margin + } else { + 0.0 + }; + + // font and header dimension + let font_size = renderer.default_size() as f32; + let first_row_h = font_size + margin; + + // header + let x = origin.x; + let y = origin.y; + let width = size.width; + let height = first_row_h; + self.draw_header(renderer, Rectangle {x, y, width, height}, month_w); + + // month column + if month_w > 0.0 && size.width > month_w { + let x = origin.x; + let y = origin.y + first_row_h; + let width = month_w; + let height = size.height - first_row_h; + self.draw_month_column(renderer, Rectangle{x, y, width, height}); + } + + // monthly calendar cells + let x = origin.x + month_w; + let y = origin.y + first_row_h; + let width = size.width - month_w; + let height = size.height - first_row_h; + self.draw_days(renderer, Rectangle{x, y, width, height}); + } +} + +impl<'a, Message, Renderer> From for Element<'a, Message, Renderer> +where + Renderer: text::Renderer, +{ + fn from(year_view: CalendarYearView) -> Self { + Self::new(year_view) } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs new file mode 100644 index 0000000..e1087a7 --- /dev/null +++ b/src/ui/mod.rs @@ -0,0 +1 @@ +pub mod calendar;