* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define _XOPEN_SOURCE
#define _XOPEN_SOURCE_EXTENDED
+#include <stdlib.h>
#include <string.h>
+#include <locale.h>
#include <ncurses.h>
#include "util.h"
edit_t EDIT = EDIT_NONE;
/* Local data */
-view_t *view = &day_view;
-view_t *active = &day_view;
-view_t *popup = NULL;
+view_t *view = &day_view;
+view_t *active = &day_view;
+view_t *popup = NULL;
+int running = 0;
/* Local functions */
static void draw_header(void)
match(cat, "work") ? COLOR_WORK : COLOR_OTHER ;
}
+static void update_sizes(void)
+{
+ int hdr = COMPACT ? 1 : 2;
+ for (int i = 0; i < N_ELEMENTS(views); i++) {
+ wresize(views[i]->win, LINES-hdr, COLS);
+ mvwin(views[i]->win, hdr, 0);
+ views[i]->size(LINES-hdr, COLS);
+ }
+}
+
+static void draw_view(void)
+{
+ draw_header();
+ werase(view->win);
+ view->draw();
+ wrefresh(view->win);
+}
+
static int set_view(view_t *_active, view_t *_popup)
{
view = _popup ?: _active;
if (active != _active) {
active = _active;
set_string("view", 0, "active", active->name);
- view_draw();
+ draw_view();
}
if (popup != _popup) {
popup = _popup;
- view_draw();
+ draw_view();
}
return 1;
}
+static int process(int key, mmask_t btn, int row, int col)
+{
+ /* Refresh timestamp */
+ draw_header();
+
+ /* Check for mouse events on the menu */
+ if (key == KEY_MOUSE && row == 0) {
+ int start = 1;
+ for (int i = 0; i < N_ELEMENTS(menu); i++) {
+ int end = start + strlen(menu[i]->name) - 1;
+ if (start <= col && col <= end && menu[i]->draw)
+ return set_view(menu[i], NULL);
+ start = end + 2;
+ }
+ }
+
+ /* Look though menu for hotkeys */
+ for (int i = 0; i < N_ELEMENTS(menu); i++) {
+ for (int j = 0; j < N_ELEMENTS(menu[i]->keys); j++)
+ if (menu[i]->keys[j] == key)
+ return set_view(menu[i], NULL);
+ }
+
+ /* Shift windows with left/right keys */
+ int shift = key == KEY_RIGHT ? +1 :
+ key == KEY_LEFT ? -1 : 0;
+ if (shift) {
+ int num = 0;
+ for (int i = 0; i < N_ELEMENTS(menu); i++)
+ if (menu[i] == active)
+ num = i;
+ do {
+ num += shift;
+ num += N_ELEMENTS(menu);
+ num %= N_ELEMENTS(menu);
+ } while (menu[num] == &spacer);
+ return set_view(menu[num], NULL);
+ }
+
+ /* Handle other keys */
+ switch (key) {
+ case KEY_RESIZE:
+ endwin();
+ refresh();
+ update_sizes();
+ draw_view();
+ return 1;
+ case '\14': // Ctrl-L
+ clear();
+ case '\7': // Ctrl-G
+ update_sizes();
+ draw_view();
+ return 1;
+ case '\033': // escape
+ return set_view(active, NULL);
+ case '?': // help
+ return set_view(active, &help_view);
+ case 'c':
+ COMPACT ^= 1;
+ set_bool("view", 0, "compact", COMPACT);
+ update_sizes();
+ draw_view();
+ return 1;
+ }
+
+ /* Pass key to active view */
+ return view->run(key, btn, row, col);
+}
+
/* Curses functions */
void wmvresize(WINDOW *win, int top, int left, int rows, int cols)
{
/* View init */
void view_init(void)
{
- int hdr = COMPACT ? 1 : 2;
+ /* Set default escape timeout */
+ if (!getenv("ESCDELAY"))
+ putenv("ESCDELAY=25");
+
+ /* Setup Curses */
+ setlocale(LC_ALL, "");
+ initscr();
+ cbreak();
+ noecho();
+ keypad(stdscr, TRUE);
+ start_color();
+ curs_set(false);
+ timeout(100);
+ use_default_colors();
+ mousemask(ALL_MOUSE_EVENTS, NULL);
+
+ init_pair(COLOR_TITLE, COLOR_GREEN, -1);
+ init_pair(COLOR_ERROR, COLOR_RED, -1);
+
+ init_pair(COLOR_NEW, COLOR_RED, -1);
+ init_pair(COLOR_WIP, COLOR_YELLOW, -1);
+ init_pair(COLOR_DONE, COLOR_GREEN, -1);
+
+ init_pair(COLOR_CLASS, COLOR_BLUE, -1);
+ init_pair(COLOR_EC, COLOR_GREEN, -1);
+ init_pair(COLOR_WORK, COLOR_MAGENTA, -1);
+ init_pair(COLOR_OTHER, COLOR_RED, -1);
+
+ running = 1;
+
+ /* Setup windows */
for (int i = 0; i < N_ELEMENTS(views); i++) {
+ int hdr = COMPACT ? 1 : 2;
views[i]->win = newwin(LINES-hdr, COLS, hdr, 0);
views[i]->init(views[i]->win);
views[i]->size(LINES-hdr, COLS);
}
}
-/* View draw */
-void view_resize(void)
-{
- int hdr = COMPACT ? 1 : 2;
- for (int i = 0; i < N_ELEMENTS(views); i++) {
- wresize(views[i]->win, LINES-hdr, COLS);
- mvwin(views[i]->win, hdr, 0);
- views[i]->size(LINES-hdr, COLS);
- }
-}
-
-/* View draw */
-void view_draw(void)
+/* View event */
+void view_edit(edit_t mode)
{
- draw_header();
- werase(view->win);
- view->draw();
- wrefresh(view->win);
+ EDIT = mode;
+ set_view(active, &edit_view);
}
-/* View run */
-int view_run(int key, mmask_t btn, int row, int col)
+void view_main(void)
{
- /* Refresh timestamp */
- draw_header();
-
- /* Check for mouse events on the menu */
- if (key == KEY_MOUSE && row == 0) {
- int start = 1;
- for (int i = 0; i < N_ELEMENTS(menu); i++) {
- int end = start + strlen(menu[i]->name) - 1;
- if (start <= col && col <= end && menu[i]->draw)
- return set_view(menu[i], NULL);
- start = end + 2;
- }
- }
-
- /* Look though menu for hotkeys */
- for (int i = 0; i < N_ELEMENTS(menu); i++) {
- for (int j = 0; j < N_ELEMENTS(menu[i]->keys); j++)
- if (menu[i]->keys[j] == key)
- return set_view(menu[i], NULL);
+ /* Draw initial view */
+ draw_view();
+
+ /* Run */
+ while (1) {
+ MEVENT btn;
+ conf_sync();
+ int chr = getch();
+ date_sync();
+ if (chr == KEY_MOUSE)
+ if (getmouse(&btn) != OK)
+ continue;
+ if (process(chr, btn.bstate, btn.y, btn.x))
+ continue;
+ if (chr == ERR) // timeout
+ continue;
+ if (chr == 'q')
+ break;
+ debug("main: Unhandled key - Dec %3d, Hex %02x, Oct %03o, Chr <%c>",
+ chr, chr, chr, chr);
}
- /* Shift windows with left/right keys */
- int shift = key == KEY_RIGHT ? +1 :
- key == KEY_LEFT ? -1 : 0;
- if (shift) {
- int num = 0;
- for (int i = 0; i < N_ELEMENTS(menu); i++)
- if (menu[i] == active)
- num = i;
- do {
- num += shift;
- num += N_ELEMENTS(menu);
- num %= N_ELEMENTS(menu);
- } while (menu[num] == &spacer);
- return set_view(menu[num], NULL);
- }
-
- /* Handle other keys */
- switch (key) {
- case 'c':
- COMPACT ^= 1;
- set_bool("view", 0, "compact", COMPACT);
- view_resize();
- view_draw();
- return 1;
- case '\033': // escape
- return set_view(active, NULL);
- case '?': // help
- return set_view(active, &help_view);
- case 'e': // edit
- return set_view(active, &edit_view);
- }
+ /* Cleanup window */
+ view_exit();
+}
- /* Pass key to active view */
- return view->run(key, btn, row, col);
+void view_exit(void)
+{
+ if (running)
+ endwin();
}
-/* View event */
-void view_edit(edit_t mode)
+void view_debug(const char *fmt, va_list ap)
{
- EDIT = mode;
- set_view(active, &edit_view);
+ if (running) {
+ int rev = COMPACT ? A_BOLD : 0;
+ if (!COMPACT)
+ mvhline(LINES-2, 0, ACS_HLINE, COLS);
+ move(LINES-1, 0);
+ attron(COLOR_PAIR(COLOR_ERROR) | rev);
+ vwprintw(stdscr, fmt, ap);
+ attroff(COLOR_PAIR(COLOR_ERROR) | rev);
+ if (!COMPACT)
+ clrtoeol();
+ }
}