Calendar: Implement basic reading feature
This commit contains a lot of different changes. Starting from some refacting of user input code, coloring, and adding a basic reading feature to the program.
This commit is contained in:
parent
f810759f12
commit
ad50383d03
|
@ -30,9 +30,11 @@ For example: `vis school.cal`
|
||||||
This will open the default view mode (month) and display the current month's calendar. From there, you can use the following commands to navigate and edit the calendar:
|
This will open the default view mode (month) and display the current month's calendar. From there, you can use the following commands to navigate and edit the calendar:
|
||||||
- `h/j/k/l` - Move 1 day left/down/up/right
|
- `h/j/k/l` - Move 1 day left/down/up/right
|
||||||
- `u/o` - Move 1 month left/right
|
- `u/o` - Move 1 month left/right
|
||||||
- `gg` - Go to the beginning of the month
|
- `g` - Go to the beginning of the month
|
||||||
- `G` - Go to the end of the month
|
- `G` - Go to the end of the month
|
||||||
- `i` - Enter insert mode for the active day.
|
- `i` - Enter insert mode for selected day.
|
||||||
|
- `x` - Delete event from selected day.
|
||||||
|
- `w` - Write changes to file (i.e. save)
|
||||||
- `q` - Quit and save the calendar
|
- `q` - Quit and save the calendar
|
||||||
|
|
||||||
# Todos
|
# Todos
|
||||||
|
|
|
@ -11,6 +11,13 @@ calendar_information::calendar_information() {
|
||||||
current_month_days = Calendar::get_days_in_month(current_month, current_year);
|
current_month_days = Calendar::get_days_in_month(current_month, current_year);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calendar_information::calendar_information(int cday, int cmonth, int cyear) {
|
||||||
|
current_day = cday;
|
||||||
|
current_month = cmonth;
|
||||||
|
current_year = cyear;
|
||||||
|
current_month_days = Calendar::get_days_in_month(current_month, current_year);
|
||||||
|
}
|
||||||
|
|
||||||
int Calendar::get_days_in_month(int month, int year) {
|
int Calendar::get_days_in_month(int month, int year) {
|
||||||
tm date = {0};
|
tm date = {0};
|
||||||
date.tm_year = year - 1900;
|
date.tm_year = year - 1900;
|
||||||
|
@ -45,7 +52,12 @@ calendar_information Calendar::get_info() {
|
||||||
return this->info;
|
return this->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calendar_information Calendar::get_current_date() {
|
||||||
|
return this->current_date;
|
||||||
|
}
|
||||||
|
|
||||||
Calendar::Calendar(calendar_information *preinfo) {
|
Calendar::Calendar(calendar_information *preinfo) {
|
||||||
|
this->current_date = calendar_information();
|
||||||
this->info = *preinfo;
|
this->info = *preinfo;
|
||||||
|
|
||||||
if (preinfo != nullptr)
|
if (preinfo != nullptr)
|
||||||
|
@ -53,3 +65,25 @@ Calendar::Calendar(calendar_information *preinfo) {
|
||||||
|
|
||||||
this->info = calendar_information();
|
this->info = calendar_information();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/6054016/c-program-to-find-day-of-week-given-date
|
||||||
|
int get_weekday(calendar_information *date_info) {
|
||||||
|
if (date_info == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int d = date_info->current_day;
|
||||||
|
int m = date_info->current_month;
|
||||||
|
int y = date_info->current_year;
|
||||||
|
|
||||||
|
return (d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int datecmp(calendar_information *one, calendar_information *two) {
|
||||||
|
if (one->current_day != two->current_day) return 0;
|
||||||
|
if (one->current_month != two->current_month) return 0;
|
||||||
|
if (one->current_month_days != two->current_month_days) return 0;
|
||||||
|
if (one->current_year != two->current_year) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct calendar_information {
|
||||||
int current_year;
|
int current_year;
|
||||||
|
|
||||||
calendar_information();
|
calendar_information();
|
||||||
|
calendar_information(int cday, int cmonth, int cyear);
|
||||||
};
|
};
|
||||||
|
|
||||||
const bool operator<(const calendar_information& first, const calendar_information& second) {
|
const bool operator<(const calendar_information& first, const calendar_information& second) {
|
||||||
|
@ -23,11 +24,17 @@ class Calendar {
|
||||||
void set_day(int day);
|
void set_day(int day);
|
||||||
void set_month(int month);
|
void set_month(int month);
|
||||||
void set_year(int year);
|
void set_year(int year);
|
||||||
calendar_information get_info();
|
|
||||||
|
|
||||||
|
calendar_information get_info();
|
||||||
|
calendar_information get_current_date();
|
||||||
Calendar(calendar_information *preinfo = nullptr);
|
Calendar(calendar_information *preinfo = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
calendar_information info;
|
calendar_information info; // mutable date that can be changed
|
||||||
|
calendar_information current_date; // current date
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int get_weekday(calendar_information *date_info = nullptr);
|
||||||
|
int datecmp(calendar_information *one, calendar_information *two);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <regex>
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
|
|
||||||
Engine::Engine(int padding, calendar_view_mode view_mode) {
|
Engine::Engine(int padding, calendar_view_mode view_mode) {
|
||||||
|
@ -60,12 +62,20 @@ void Engine::ui_month_draw(WINDOW *win) {
|
||||||
if (this->events_map.count(tmp_date) > 0)
|
if (this->events_map.count(tmp_date) > 0)
|
||||||
wattron(win, COLOR_PAIR(2));
|
wattron(win, COLOR_PAIR(2));
|
||||||
|
|
||||||
|
calendar_information current_date = this->calendar->get_current_date();
|
||||||
|
if (datecmp(¤t_date, &tmp_date))
|
||||||
|
wattron(win, COLOR_PAIR(3));
|
||||||
|
|
||||||
if (this->active_cell == i)
|
if (this->active_cell == i)
|
||||||
wattron(win, COLOR_PAIR(1));
|
wattron(win, COLOR_PAIR(1));
|
||||||
|
|
||||||
mvwprintw(win, y_location, x_location, "D%d", i+1);
|
std::string weekday_prefix = weekday_prefixes[get_weekday(&tmp_date)];
|
||||||
|
|
||||||
|
// mvwprintw(win, y_location, x_location, "D%d", i+1);
|
||||||
|
mvwprintw(win, y_location, x_location, "%s[%d]", weekday_prefix.c_str(), i+1);
|
||||||
wattroff(win, COLOR_PAIR(1));
|
wattroff(win, COLOR_PAIR(1));
|
||||||
wattroff(win, COLOR_PAIR(2));
|
wattroff(win, COLOR_PAIR(2));
|
||||||
|
wattroff(win, COLOR_PAIR(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +91,6 @@ void Engine::ui_top_draw(WINDOW *win) {
|
||||||
if (VIS_COLORING) wattron(win, COLOR_PAIR(1));
|
if (VIS_COLORING) wattron(win, COLOR_PAIR(1));
|
||||||
|
|
||||||
mvwprintw(win, 1, 1, "Vi Scheduler");
|
mvwprintw(win, 1, 1, "Vi Scheduler");
|
||||||
mvwprintw(win, 2, 1, "@0xdeadbeer");
|
|
||||||
|
|
||||||
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
|
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
|
||||||
}
|
}
|
||||||
|
@ -97,12 +106,24 @@ void Engine::ui_bottom_draw(WINDOW *win) {
|
||||||
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
|
if (VIS_COLORING) wattroff(win, COLOR_PAIR(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::input_handle_month(WINDOW *win) {
|
void Engine::input_handle(WINDOW *win) {
|
||||||
char key = getch();
|
char key = getch();
|
||||||
|
|
||||||
calendar_information date_info = this->calendar->get_info();
|
if (this->input_handle_universal(win, key))
|
||||||
|
return;
|
||||||
|
|
||||||
int day, month, res;
|
if (this->view_mode == MONTH_VIEW)
|
||||||
|
this->input_handle_month(win, key);
|
||||||
|
else if (this->view_mode == WEEK_VIEW)
|
||||||
|
this->input_handle_week(win, key);
|
||||||
|
else if (this->view_mode == MONTHS_VIEW)
|
||||||
|
this->input_handle_months(win, key);
|
||||||
|
|
||||||
|
// fuc.
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Engine::input_handle_universal(WINDOW *win, char key) {
|
||||||
|
int day;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'h':
|
case 'h':
|
||||||
if (this->calendar->get_info().current_day <= 1) break;
|
if (this->calendar->get_info().current_day <= 1) break;
|
||||||
|
@ -128,32 +149,14 @@ void Engine::input_handle_month(WINDOW *win) {
|
||||||
|
|
||||||
this->active_cell += 7;
|
this->active_cell += 7;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
|
||||||
if (this->calendar->get_info().current_day-7 < 1) break;
|
if (this->calendar->get_info().current_day-7 < 1) break;
|
||||||
|
case 'k':
|
||||||
|
|
||||||
day = this->calendar->get_info().current_day;
|
day = this->calendar->get_info().current_day;
|
||||||
this->calendar->set_day(day-7);
|
this->calendar->set_day(day-7);
|
||||||
|
|
||||||
this->active_cell -= 7;
|
this->active_cell -= 7;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
|
||||||
if (this->calendar->get_info().current_month <= 1) break;
|
|
||||||
|
|
||||||
month = this->calendar->get_info().current_month;
|
|
||||||
this->calendar->set_month(--month);
|
|
||||||
this->calendar->set_day(1);
|
|
||||||
|
|
||||||
this->active_cell = 0;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
if (this->calendar->get_info().current_month >= 12) break;
|
|
||||||
|
|
||||||
month = this->calendar->get_info().current_month;
|
|
||||||
this->calendar->set_month(++month);
|
|
||||||
this->calendar->set_day(1);
|
|
||||||
|
|
||||||
this->active_cell = 0;
|
|
||||||
break;
|
|
||||||
case 'i': { // TODO: Break down this monstrocity of a case
|
case 'i': { // TODO: Break down this monstrocity of a case
|
||||||
endwin();
|
endwin();
|
||||||
int vipe_out[2], vipe_in[2];
|
int vipe_out[2], vipe_in[2];
|
||||||
|
@ -200,6 +203,44 @@ void Engine::input_handle_month(WINDOW *win) {
|
||||||
this->events_map.erase(date_info);
|
this->events_map.erase(date_info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'w':
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
endwin();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::input_handle_month(WINDOW *win, char key) {
|
||||||
|
|
||||||
|
calendar_information date_info = this->calendar->get_info();
|
||||||
|
|
||||||
|
int month;
|
||||||
|
switch (key) {
|
||||||
|
case 'u':
|
||||||
|
if (this->calendar->get_info().current_month <= 1) break;
|
||||||
|
|
||||||
|
month = this->calendar->get_info().current_month;
|
||||||
|
this->calendar->set_month(--month);
|
||||||
|
this->calendar->set_day(1);
|
||||||
|
|
||||||
|
this->active_cell = 0;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (this->calendar->get_info().current_month >= 12) break;
|
||||||
|
|
||||||
|
month = this->calendar->get_info().current_month;
|
||||||
|
this->calendar->set_month(++month);
|
||||||
|
this->calendar->set_day(1);
|
||||||
|
|
||||||
|
this->active_cell = 0;
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
this->calendar->set_day(1);
|
this->calendar->set_day(1);
|
||||||
this->active_cell = 0;
|
this->active_cell = 0;
|
||||||
|
@ -208,17 +249,55 @@ void Engine::input_handle_month(WINDOW *win) {
|
||||||
this->calendar->set_day(this->calendar->get_info().current_month_days);
|
this->calendar->set_day(this->calendar->get_info().current_month_days);
|
||||||
this->active_cell = this->calendar->get_info().current_month_days-1;
|
this->active_cell = this->calendar->get_info().current_month_days-1;
|
||||||
break;
|
break;
|
||||||
case 't':
|
|
||||||
this->view_mode = WEEK_VIEW;
|
|
||||||
wclear(win);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::input_handle_week(WINDOW *win) {
|
void Engine::input_handle_week(WINDOW *win, char key) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::input_handle_months(WINDOW *win) {
|
void Engine::input_handle_months(WINDOW *win, char key) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calendar_information Engine::parse_date(std::string date) {
|
||||||
|
char *token = strtok((char *) date.c_str(), ".");
|
||||||
|
std::vector<int> tokens;
|
||||||
|
|
||||||
|
while (token != NULL) {
|
||||||
|
tokens.push_back(std::stoi(token));
|
||||||
|
token = strtok(NULL, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
return calendar_information(tokens[0], tokens[1], tokens[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::parse_line(std::string line) {
|
||||||
|
char *token = strtok((char *) line.c_str(), " ");
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
|
||||||
|
while (token != NULL) {
|
||||||
|
tokens.push_back(token);
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tokens.size() != 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
calendar_information event_date = this->parse_date(tokens[0]);
|
||||||
|
this->events_map[event_date] = tokens[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::open_calendar(char *filename) {
|
||||||
|
this->calendar_file.open(filename, std::ios::in | std::ios::out);
|
||||||
|
|
||||||
|
// If the file does not exist,
|
||||||
|
// we'll create and reopen it later ('write' shortcut)
|
||||||
|
if (this->calendar_file.fail())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(this->calendar_file, line)) {
|
||||||
|
this->parse_line(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define ENGINE_HPP
|
#define ENGINE_HPP
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
// #include <unordered_map>
|
// #include <unordered_map>
|
||||||
|
@ -20,6 +21,16 @@ enum calendar_view_mode {
|
||||||
MONTHS_VIEW
|
MONTHS_VIEW
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string weekday_prefixes[] = {
|
||||||
|
"Sun",
|
||||||
|
"Mon",
|
||||||
|
"Tue",
|
||||||
|
"Wed",
|
||||||
|
"Thu",
|
||||||
|
"Fri",
|
||||||
|
"Sat"
|
||||||
|
};
|
||||||
|
|
||||||
std::string calendar_view_mode_str[] = {
|
std::string calendar_view_mode_str[] = {
|
||||||
"MONTH_VIEW",
|
"MONTH_VIEW",
|
||||||
"WEEK_VIEW",
|
"WEEK_VIEW",
|
||||||
|
@ -30,7 +41,7 @@ std::string calendar_view_mode_str[] = {
|
||||||
// description: use for drawing the TUI and interact with the cells
|
// description: use for drawing the TUI and interact with the cells
|
||||||
class Engine {
|
class Engine {
|
||||||
public:
|
public:
|
||||||
Engine(int padding = 10, calendar_view_mode view_mode = MONTH_VIEW);
|
Engine(int padding, calendar_view_mode view_mode);
|
||||||
~Engine();
|
~Engine();
|
||||||
|
|
||||||
void ui_draw(WINDOW *win);
|
void ui_draw(WINDOW *win);
|
||||||
|
@ -40,9 +51,15 @@ class Engine {
|
||||||
void ui_bottom_draw(WINDOW *win);
|
void ui_bottom_draw(WINDOW *win);
|
||||||
void ui_top_draw(WINDOW *win);
|
void ui_top_draw(WINDOW *win);
|
||||||
|
|
||||||
void input_handle_month(WINDOW *win);
|
void input_handle(WINDOW* win);
|
||||||
void input_handle_week(WINDOW *win);
|
bool input_handle_universal(WINDOW *win, char key);
|
||||||
void input_handle_months(WINDOW *win);
|
void input_handle_month(WINDOW *win, char key);
|
||||||
|
void input_handle_week(WINDOW *win, char key);
|
||||||
|
void input_handle_months(WINDOW *win, char key);
|
||||||
|
|
||||||
|
calendar_information parse_date(std::string date);
|
||||||
|
void parse_line(std::string line);
|
||||||
|
void open_calendar(char *filename);
|
||||||
|
|
||||||
Calendar *calendar;
|
Calendar *calendar;
|
||||||
// std::unordered_map<calendar_information, std::string> events_map;
|
// std::unordered_map<calendar_information, std::string> events_map;
|
||||||
|
@ -54,7 +71,7 @@ class Engine {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<engine_child> cells_table;
|
std::vector<engine_child> cells_table;
|
||||||
|
std::fstream calendar_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
31
src/main.cpp
31
src/main.cpp
|
@ -6,7 +6,7 @@
|
||||||
#include "engine/engine.hpp"
|
#include "engine/engine.hpp"
|
||||||
#include "global/global.hpp"
|
#include "global/global.hpp"
|
||||||
|
|
||||||
Engine engine = Engine(10, MONTH_VIEW);
|
Engine engine(10, MONTH_VIEW);
|
||||||
WINDOW *main_win;
|
WINDOW *main_win;
|
||||||
|
|
||||||
void sig_winch(int sig) {
|
void sig_winch(int sig) {
|
||||||
|
@ -31,7 +31,25 @@ void signals() {
|
||||||
signal(SIGWINCH, sig_winch);
|
signal(SIGWINCH, sig_winch);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
void print_help() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool check_args(int argc, char **argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
print_help();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.open_calendar(argv[1]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (!check_args(argc, argv))
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
initscr();
|
initscr();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
|
@ -49,6 +67,7 @@ int main() {
|
||||||
init_pair(0, COLOR_WHITE, COLOR_BLACK);
|
init_pair(0, COLOR_WHITE, COLOR_BLACK);
|
||||||
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
init_pair(1, COLOR_BLACK, COLOR_WHITE);
|
||||||
init_pair(2, COLOR_BLACK, COLOR_RED);
|
init_pair(2, COLOR_BLACK, COLOR_RED);
|
||||||
|
init_pair(3, COLOR_BLACK, COLOR_GREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle required signals
|
// handle required signals
|
||||||
|
@ -57,14 +76,10 @@ int main() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
engine.ui_draw(main_win);
|
engine.ui_draw(main_win);
|
||||||
|
|
||||||
if (engine.view_mode == MONTH_VIEW)
|
engine.input_handle(main_win);
|
||||||
engine.input_handle_month(main_win);
|
|
||||||
if (engine.view_mode == WEEK_VIEW)
|
|
||||||
engine.input_handle_week(main_win);
|
|
||||||
else if (engine.view_mode == MONTHS_VIEW)
|
|
||||||
engine.input_handle_months(main_win);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
endwin();
|
endwin();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user