aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app.rs29
-rw-r--r--src/views.rs85
2 files changed, 82 insertions, 32 deletions
diff --git a/src/app.rs b/src/app.rs
index f39ae3c..1240877 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -111,7 +111,7 @@ impl App {
111 fn status(&self) -> StatusLine { 111 fn status(&self) -> StatusLine {
112 let today = chrono::Local::now().naive_utc().date(); 112 let today = chrono::Local::now().naive_utc().date();
113 let remaining = self.habits.iter().map(|h| h.remaining(today)).sum::<u32>(); 113 let remaining = self.habits.iter().map(|h| h.remaining(today)).sum::<u32>();
114 let total = self.habits.iter().map(|h| h.total()).sum::<u32>(); 114 let total = self.habits.iter().map(|h| h.goal()).sum::<u32>();
115 let completed = total - remaining; 115 let completed = total - remaining;
116 116
117 let timestamp = if self.view_month_offset == 0 { 117 let timestamp = if self.view_month_offset == 0 {
@@ -124,7 +124,7 @@ impl App {
124 let months = self.view_month_offset; 124 let months = self.view_month_offset;
125 format!( 125 format!(
126 "{:>width$}", 126 "{:>width$}",
127 format!("{} months ago", self.view_month_offset), 127 format!("{} months ago", months),
128 width = CONFIGURATION.view_width * CONFIGURATION.grid_width 128 width = CONFIGURATION.view_width * CONFIGURATION.grid_width
129 ) 129 )
130 }; 130 };
@@ -226,7 +226,7 @@ impl View for App {
226 let view_height = CONFIGURATION.view_height; 226 let view_height = CONFIGURATION.view_height;
227 let width = { 227 let width = {
228 if self.habits.len() > 0 { 228 if self.habits.len() > 0 {
229 grid_width * view_width 229 grid_width * (view_width + 2)
230 } else { 230 } else {
231 0 231 0
232 } 232 }
@@ -283,6 +283,29 @@ impl View for App {
283 self.save_state(); 283 self.save_state();
284 return EventResult::with_cb(|s| s.quit()); 284 return EventResult::with_cb(|s| s.quit());
285 } 285 }
286 Event::Char('v') => {
287 if self.habits.is_empty() {
288 return EventResult::Consumed(None);
289 }
290 if self.habits[self.focus].view_mode() == ViewMode::Month {
291 self.set_mode(ViewMode::Day)
292 } else {
293 self.set_mode(ViewMode::Month)
294 }
295 return EventResult::Consumed(None);
296 }
297 Event::Char('V') => {
298 for habit in self.habits.iter_mut() {
299 habit.set_view_mode(ViewMode::Month);
300 }
301 return EventResult::Consumed(None);
302 }
303 Event::Key(Key::Esc) => {
304 for habit in self.habits.iter_mut() {
305 habit.set_view_mode(ViewMode::Day);
306 }
307 return EventResult::Consumed(None);
308 }
286 309
287 /* We want sifting to be an app level function, 310 /* We want sifting to be an app level function,
288 * that later trickles down into each habit 311 * that later trickles down into each habit
diff --git a/src/views.rs b/src/views.rs
index 3e623a9..f5ba01b 100644
--- a/src/views.rs
+++ b/src/views.rs
@@ -7,7 +7,7 @@ use cursive::{Printer, Vec2};
7use chrono::prelude::*; 7use chrono::prelude::*;
8use chrono::{Duration, Local, NaiveDate}; 8use chrono::{Duration, Local, NaiveDate};
9 9
10use crate::habit::{Bit, Count, Habit, TrackEvent}; 10use crate::habit::{Bit, Count, Habit, TrackEvent, ViewMode};
11 11
12use crate::CONFIGURATION; 12use crate::CONFIGURATION;
13 13
@@ -63,37 +63,64 @@ where
63 }, 63 },
64 ); 64 );
65 65
66 // fn draw_day(&self, p: &Printer) { }; 66 let draw_month = |printer: &Printer| {
67 // fn draw_month(&self, p: &Printer) {}; 67 let days = (1..31)
68 68 .map(|i| NaiveDate::from_ymd_opt(year, month, i))
69 // match self.view_mode() { 69 .flatten() // dates 28-31 may not exist, ignore them if they don't
70 // ViewMode::Day => draw_day(self, p), 70 .collect::<Vec<_>>();
71 // ViewMode::Month => 71 for (week, line_nr) in days.chunks(7).zip(2..) {
72 // } 72 let weekly_goal = self.goal() * week.len() as u32;
73 73 let is_this_week = week.contains(&Local::now().naive_utc().date());
74 //let draw_day = |printer: &Printer| { 74 let remaining = week.iter().map(|&i| self.remaining(i)).sum::<u32>();
75 let mut i = 1; 75 let completions = weekly_goal - remaining;
76 while let Some(d) = NaiveDate::from_ymd_opt(year, month, i) { 76 let full = CONFIGURATION.view_width - 8;
77 let day_style; 77 let bars_to_fill = (completions * full as u32) / weekly_goal;
78 if self.reached_goal(d) { 78 let percentage = (completions as f64 * 100f64) / weekly_goal as f64;
79 day_style = goal_reached_style;
80 } else {
81 day_style = todo_style;
82 }
83 let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into();
84 if let Some(c) = self.get_by_date(d) {
85 printer.with_style(day_style, |p| {
86 p.print(coords, &format!("{:^3}", c));
87 });
88 } else {
89 printer.with_style(future_style, |p| { 79 printer.with_style(future_style, |p| {
90 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));
91 }); 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!("{:3.0}% ", percentage));
93 },
94 );
92 } 95 }
93 i += 1; 96 };
94 } 97 let draw_day = |printer: &Printer| {
95 //}; 98 let mut i = 1;
96 //draw_day(printer); 99 while let Some(d) = NaiveDate::from_ymd_opt(year, month, i) {
100 let day_style;
101 if self.reached_goal(d) {
102 day_style = goal_reached_style;
103 } else {
104 day_style = todo_style;
105 }
106 let coords: Vec2 = ((i % 7) * 3, i / 7 + 2).into();
107 if let Some(c) = self.get_by_date(d) {
108 printer.with_style(day_style, |p| {
109 p.print(coords, &format!("{:^3}", c));
110 });
111 } else {
112 printer.with_style(future_style, |p| {
113 p.print(coords, &format!("{:^3}", CONFIGURATION.future_chr));
114 });
115 }
116 i += 1;
117 }
118 };
119 match self.view_mode() {
120 ViewMode::Day => draw_day(printer),
121 ViewMode::Month => draw_month(printer),
122 _ => draw_day(printer),
123 };
97 } 124 }
98 125
99 fn required_size(&mut self, _: Vec2) -> Vec2 { 126 fn required_size(&mut self, _: Vec2) -> Vec2 {