aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app.rs')
-rw-r--r--src/app.rs58
1 files changed, 32 insertions, 26 deletions
diff --git a/src/app.rs b/src/app.rs
index 82096e1..f8797fc 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -9,26 +9,13 @@ use cursive::{Printer, Vec2};
9 9
10use chrono::{Local, NaiveDate}; 10use chrono::{Local, NaiveDate};
11 11
12use crate::habit::{Bit, Count, Habit, HabitWrapper}; 12use crate::habit::{Bit, Count, Habit, HabitWrapper, ViewMode};
13use crate::utils; 13use crate::utils;
14use crate::Command; 14use crate::Command;
15use crate::CONFIGURATION; 15use crate::CONFIGURATION;
16 16
17use serde::{Deserialize, Serialize}; 17use serde::{Deserialize, Serialize};
18 18
19#[derive(PartialEq, Serialize, Deserialize)]
20pub enum ViewMode {
21 Day,
22 Month,
23 Year,
24}
25
26impl std::default::Default for ViewMode {
27 fn default() -> Self {
28 ViewMode::Month
29 }
30}
31
32struct StatusLine(String, String); 19struct StatusLine(String, String);
33 20
34#[derive(Serialize, Deserialize)] 21#[derive(Serialize, Deserialize)]
@@ -41,9 +28,6 @@ pub struct App {
41 focus: usize, 28 focus: usize,
42 29
43 #[serde(skip)] 30 #[serde(skip)]
44 view_mode: ViewMode,
45
46 #[serde(skip)]
47 view_month_offset: u32, 31 view_month_offset: u32,
48} 32}
49 33
@@ -51,7 +35,6 @@ impl App {
51 pub fn new() -> Self { 35 pub fn new() -> Self {
52 return App { 36 return App {
53 habits: vec![], 37 habits: vec![],
54 view_mode: ViewMode::Day,
55 focus: 0, 38 focus: 0,
56 view_month_offset: 0, 39 view_month_offset: 0,
57 }; 40 };
@@ -65,9 +48,9 @@ impl App {
65 self.habits.retain(|h| h.get_name() != name); 48 self.habits.retain(|h| h.get_name() != name);
66 } 49 }
67 50
68 pub fn set_mode(&mut self, set_mode: ViewMode) { 51 pub fn set_mode(&mut self, mode: ViewMode) {
69 if set_mode != self.view_mode { 52 if !self.habits.is_empty() {
70 self.view_mode = set_mode; 53 self.habits[self.focus].set_view_mode(mode);
71 } 54 }
72 } 55 }
73 56
@@ -128,7 +111,7 @@ impl App {
128 fn status(&self) -> StatusLine { 111 fn status(&self) -> StatusLine {
129 let today = chrono::Local::now().naive_utc().date(); 112 let today = chrono::Local::now().naive_utc().date();
130 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>();
131 let total = self.habits.iter().map(|h| h.total()).sum::<u32>(); 114 let total = self.habits.iter().map(|h| h.goal()).sum::<u32>();
132 let completed = total - remaining; 115 let completed = total - remaining;
133 116
134 let timestamp = if self.view_month_offset == 0 { 117 let timestamp = if self.view_month_offset == 0 {
@@ -141,7 +124,7 @@ impl App {
141 let months = self.view_month_offset; 124 let months = self.view_month_offset;
142 format!( 125 format!(
143 "{:>width$}", 126 "{:>width$}",
144 format!("{} months ago", self.view_month_offset), 127 format!("{} months ago", months),
145 width = CONFIGURATION.view_width * CONFIGURATION.grid_width 128 width = CONFIGURATION.view_width * CONFIGURATION.grid_width
146 ) 129 )
147 }; 130 };
@@ -233,8 +216,8 @@ impl View for App {
233 } 216 }
234 217
235 offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 2); 218 offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 2);
236 printer.print(offset, &self.status().1); // right 219 printer.print(offset, &self.status().1); // right status
237 printer.print(offset, &self.status().0); // left 220 printer.print(offset, &self.status().0); // left status
238 } 221 }
239 222
240 fn required_size(&mut self, _: Vec2) -> Vec2 { 223 fn required_size(&mut self, _: Vec2) -> Vec2 {
@@ -243,7 +226,7 @@ impl View for App {
243 let view_height = CONFIGURATION.view_height; 226 let view_height = CONFIGURATION.view_height;
244 let width = { 227 let width = {
245 if self.habits.len() > 0 { 228 if self.habits.len() > 0 {
246 grid_width * view_width 229 grid_width * (view_width + 2)
247 } else { 230 } else {
248 0 231 0
249 } 232 }
@@ -300,6 +283,29 @@ impl View for App {
300 self.save_state(); 283 self.save_state();
301 return EventResult::with_cb(|s| s.quit()); 284 return EventResult::with_cb(|s| s.quit());
302 } 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::Week {
291 self.set_mode(ViewMode::Day)
292 } else {
293 self.set_mode(ViewMode::Week)
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::Week);
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 }
303 309
304 /* We want sifting to be an app level function, 310 /* We want sifting to be an app level function,
305 * that later trickles down into each habit 311 * that later trickles down into each habit