1pub mod actions;
2pub mod configs;
3pub mod events;
4pub mod file_handler;
5pub mod widget;
6
7use configs::Configs;
8use serde::{Deserialize, Serialize};
9use std::{error::Error, io::Stdout};
10use tui::{
11 backend::CrosstermBackend,
12 style::{Modifier, Style},
13 Frame, Terminal,
14};
15
16pub type DynResult = Result<(), Box<dyn Error>>;
17pub type CrossTerminal = Terminal<CrosstermBackend<Stdout>>;
18pub type TerminalFrame<'a> = Frame<'a, CrosstermBackend<Stdout>>;
19
20#[derive(Serialize, Deserialize, Clone)]
22pub struct Quest {
23 pub title: String,
24 pub completed: bool,
25}
26
27impl Quest {
28 pub fn new(title: String) -> Self {
29 Self {
30 title,
31 completed: false,
32 }
33 }
34}
35
36#[derive(Serialize, Deserialize, Default)]
38pub struct QuestList {
39 pub quests: Vec<Quest>,
40}
41
42impl QuestList {
43 pub fn new(quests: &[Quest]) -> Self {
44 Self {
45 quests: quests.to_vec(),
46 }
47 }
48}
49
50pub enum InputMode {
52 Normal,
54 Adding,
56}
57
58pub struct App {
60 pub input: String,
62 pub input_mode: InputMode,
64 pub quests: Vec<Quest>,
66 pub should_exit: bool,
68 pub selected_quest: Option<usize>,
70 pub configs: Configs,
72}
73
74impl App {
75 pub fn new(quests: &[Quest], configs: Configs) -> Self {
76 Self {
77 quests: quests.to_vec(),
78 selected_quest: Some(0),
79 input: String::new(),
80 input_mode: InputMode::Normal,
81 should_exit: false,
82 configs,
83 }
84 }
85
86 pub fn default_style(&self) -> Style {
87 Style::default()
88 .fg(self.configs.colors.foreground)
89 .bg(self.configs.colors.background)
90 }
91
92 pub fn selection_style(&self) -> Style {
93 self.default_style()
94 .fg(self.configs.colors.selection_fg)
95 .bg(self.configs.colors.selection_bg)
96 }
97
98 pub fn check_sign_style(&self, selected: bool) -> Style {
99 if selected {
100 self.selection_style().fg(self.configs.colors.check_sign)
101 } else {
102 self.default_style().fg(self.configs.colors.check_sign)
103 }
104 }
105
106 pub fn checked_quest_style(&self, selected: bool) -> Style {
107 if selected {
108 self.selection_style().add_modifier(Modifier::CROSSED_OUT)
109 } else {
110 self.default_style().add_modifier(Modifier::CROSSED_OUT)
111 }
112 }
113}