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