diff options
Diffstat (limited to 'src/views.rs')
-rw-r--r-- | src/views.rs | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/src/views.rs b/src/views.rs index d25e59b..9e4a844 100644 --- a/src/views.rs +++ b/src/views.rs | |||
@@ -7,7 +7,8 @@ use cursive::{Printer, Vec2}; | |||
7 | use chrono::prelude::*; | 7 | use chrono::prelude::*; |
8 | use chrono::{Duration, Local, NaiveDate}; | 8 | use chrono::{Duration, Local, NaiveDate}; |
9 | 9 | ||
10 | use crate::habit::{Bit, Count, Habit, TrackEvent}; | 10 | use crate::habit::{Bit, Count, Habit, TrackEvent, ViewMode}; |
11 | |||
11 | use crate::CONFIGURATION; | 12 | use crate::CONFIGURATION; |
12 | 13 | ||
13 | pub trait ShadowView { | 14 | pub trait ShadowView { |
@@ -62,26 +63,66 @@ where | |||
62 | }, | 63 | }, |
63 | ); | 64 | ); |
64 | 65 | ||
65 | let mut i = 1; | 66 | let draw_month = |printer: &Printer| { |
66 | while let Some(d) = NaiveDate::from_ymd_opt(year, month, i) { | 67 | let days = (1..31) |
67 | let day_style; | 68 | .map(|i| NaiveDate::from_ymd_opt(year, month, i)) |
68 | if self.reached_goal(d) { | 69 | .flatten() // dates 28-31 may not exist, ignore them if they don't |
69 | day_style = goal_reached_style; | 70 | .collect::<Vec<_>>(); |
70 | } else { | 71 | for (week, line_nr) in days.chunks(7).zip(2..) { |
71 | day_style = todo_style; | 72 | let weekly_goal = self.goal() * week.len() as u32; |
72 | } | 73 | let is_this_week = week.contains(&Local::now().naive_utc().date()); |
73 | let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into(); | 74 | let remaining = week.iter().map(|&i| self.remaining(i)).sum::<u32>(); |
74 | if let Some(c) = self.get_by_date(d) { | 75 | let completions = weekly_goal - remaining; |
75 | printer.with_style(day_style, |p| { | 76 | let full = CONFIGURATION.view_width - 8; |
76 | p.print(coords, &format!("{:^3}", c)); | 77 | let bars_to_fill = (completions * full as u32) / weekly_goal; |
77 | }); | 78 | let percentage = (completions as f64 * 100.) / weekly_goal as f64; |
78 | } else { | ||
79 | printer.with_style(future_style, |p| { | 79 | printer.with_style(future_style, |p| { |
80 | p.print(coords, &format!("{:^3}", CONFIGURATION.future_chr)); | 80 | p.print((4, line_nr), &"―".repeat(full)); |
81 | }); | ||
82 | printer.with_style(goal_reached_style, |p| { | ||
83 | p.print((4, line_nr), &"―".repeat(bars_to_fill as usize)); | ||
81 | }); | 84 | }); |
85 | printer.with_style( | ||
86 | if is_this_week { | ||
87 | Style::none() | ||
88 | } else { | ||
89 | future_style | ||
90 | }, | ||
91 | |p| { | ||
92 | p.print((0, line_nr), &format!("{:2.0}% ", percentage)); | ||
93 | }, | ||
94 | ); | ||
82 | } | 95 | } |
83 | i += 1; | 96 | }; |
84 | } | 97 | |
98 | let draw_day = |printer: &Printer| { | ||
99 | let mut i = 0; | ||
100 | while let Some(d) = NaiveDate::from_ymd_opt(year, month, i + 1) { | ||
101 | let day_style; | ||
102 | if self.reached_goal(d) { | ||
103 | day_style = goal_reached_style; | ||
104 | } else { | ||
105 | day_style = todo_style; | ||
106 | } | ||
107 | let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into(); | ||
108 | if let Some(c) = self.get_by_date(d) { | ||
109 | printer.with_style(day_style, |p| { | ||
110 | p.print(coords, &format!("{:^3}", c)); | ||
111 | }); | ||
112 | } else { | ||
113 | printer.with_style(future_style, |p| { | ||
114 | p.print(coords, &format!("{:^3}", CONFIGURATION.future_chr)); | ||
115 | }); | ||
116 | } | ||
117 | i += 1; | ||
118 | } | ||
119 | }; | ||
120 | |||
121 | match self.view_mode() { | ||
122 | ViewMode::Day => draw_day(printer), | ||
123 | ViewMode::Week => draw_month(printer), | ||
124 | _ => draw_day(printer), | ||
125 | }; | ||
85 | } | 126 | } |
86 | 127 | ||
87 | fn required_size(&mut self, _: Vec2) -> Vec2 { | 128 | fn required_size(&mut self, _: Vec2) -> Vec2 { |