aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app.rs')
-rw-r--r--src/app.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/app.rs b/src/app.rs
new file mode 100644
index 0000000..c43a43e
--- /dev/null
+++ b/src/app.rs
@@ -0,0 +1,169 @@
1use std::f64;
2
3use cursive::direction::{Absolute, Direction};
4use cursive::event::{Event, EventResult, Key};
5use cursive::view::View;
6use cursive::{Printer, Vec2};
7
8use crate::views::habitview::HabitView;
9
10#[derive(PartialEq)]
11pub enum ViewMode {
12 Day,
13 Month,
14 Year,
15}
16
17pub struct App {
18 habits: Vec<HabitView>,
19 view_mode: ViewMode,
20 focus: usize,
21 grid_width: usize,
22
23 padding: usize,
24}
25
26impl App {
27 pub fn new() -> Self {
28 return App {
29 habits: vec![],
30 view_mode: ViewMode::Day,
31 focus: 0,
32 grid_width: 3,
33 padding: 12,
34 };
35 }
36
37 pub fn add_habit(mut self, h: HabitView) -> Self {
38 self.habits.push(h);
39 return self;
40 }
41
42 pub fn set_mode(mut self, set_mode: ViewMode) -> Self {
43 if set_mode != self.view_mode {
44 self.view_mode = set_mode
45 }
46 return self;
47 }
48
49 fn set_focus(&mut self, d: Absolute) {
50 match d {
51 Absolute::Right => {
52 if self.focus != self.habits.len() - 1 {
53 self.focus += 1;
54 }
55 }
56 Absolute::Left => {
57 if self.focus != 0 {
58 self.focus -= 1;
59 }
60 }
61 Absolute::Down => {
62 if self.focus + self.grid_width < self.habits.len() - 1 {
63 self.focus += self.grid_width;
64 } else {
65 self.focus = self.habits.len() - 1;
66 }
67 }
68 Absolute::Up => {
69 if self.focus as isize - self.grid_width as isize >= 0 {
70 self.focus -= self.grid_width;
71 } else {
72 self.focus = 0;
73 }
74 }
75 Absolute::None => {}
76 }
77 }
78
79 fn status(&self) -> String {
80 let remaining = self.habits.iter().map(|h| h.remaining()).sum::<u32>();
81 let total = self.habits.iter().map(|h| h.total()).sum::<u32>();
82 let completed = total - remaining;
83
84 return format!("{}/{} ", completed, total);
85 }
86 fn max_size(&self) -> Vec2 {
87 let grid_width = self.grid_width;
88 let width = {
89 if self.habits.len() > 0 {
90 grid_width * self.habits[0].get_size().x
91 } else {
92 0
93 }
94 };
95 let height = {
96 if self.habits.len() > 0 {
97 (self.habits[0].get_size().y as f64
98 * (self.habits.len() as f64 / grid_width as f64).ceil())
99 as usize
100 } else {
101 0
102 }
103 };
104 Vec2::new(width, height)
105 }
106}
107
108impl View for App {
109 fn draw(&self, printer: &Printer) {
110 let grid_width = self.grid_width;
111 let mut offset = Vec2::zero();
112 for (idx, i) in self.habits.iter().enumerate() {
113 if idx >= grid_width && idx % grid_width == 0 {
114 offset = offset.map_y(|y| y + i.get_size().y).map_x(|_| 0);
115 }
116 i.draw(&printer.offset(offset).focused(self.focus == idx));
117 offset = offset.map_x(|x| x + i.get_size().x);
118 }
119 offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 2);
120 printer.print(offset, &self.status());
121 }
122
123 fn required_size(&mut self, _: Vec2) -> Vec2 {
124 let grid_width = self.grid_width;
125 let width = {
126 if self.habits.len() > 0 {
127 grid_width * self.habits[0].get_size().x
128 } else {
129 0
130 }
131 };
132 let height = {
133 if self.habits.len() > 0 {
134 (self.habits[0].get_size().y as f64
135 * (self.habits.len() as f64 / grid_width as f64).ceil())
136 as usize
137 } else {
138 0
139 }
140 };
141 Vec2::new(width, height)
142 }
143
144 fn take_focus(&mut self, _: Direction) -> bool {
145 false
146 }
147
148 fn on_event(&mut self, e: Event) -> EventResult {
149 match e {
150 Event::Key(Key::Right) | Event::Key(Key::Tab) | Event::Char('l') => {
151 self.set_focus(Absolute::Right);
152 return EventResult::Consumed(None);
153 }
154 Event::Key(Key::Left) | Event::Shift(Key::Tab) | Event::Char('h') => {
155 self.set_focus(Absolute::Left);
156 return EventResult::Consumed(None);
157 }
158 Event::Key(Key::Up) | Event::Char('k') => {
159 self.set_focus(Absolute::Up);
160 return EventResult::Consumed(None);
161 }
162 Event::Key(Key::Down) | Event::Char('j') => {
163 self.set_focus(Absolute::Down);
164 return EventResult::Consumed(None);
165 }
166 _ => self.habits[self.focus].on_event(e),
167 }
168 }
169}