]> Pileus Git - lackey/blobdiff - src/view.c
Set default escape key delay
[lackey] / src / view.c
index 3f1adb1659bcba89588d3c436bf6b4a54209f963..623028e15cda1075c4d31b00b98666217728a301 100644 (file)
@@ -1,16 +1,16 @@
 /*
  * Copyright (C) 2012 Andy Spencer <andy753421@gmail.com>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -21,6 +21,7 @@
 #include <ncurses.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 #include "view.h"
@@ -36,21 +37,50 @@ typedef struct {
        WINDOW *win;
 } view_t;
 
-/* Data */
+/* Macros */
+#define VIEW(name)                     \
+       void name##_init(WINDOW *win); \
+       void name##_size(int,int);     \
+       void name##_draw(void);        \
+       int  name##_run(int,mmask_t,int,int)
+
+/* Prototypes */
+VIEW(day);
+VIEW(week);
+VIEW(month);
+VIEW(year);
+VIEW(events);
+VIEW(todo);
+VIEW(settings);
+VIEW(help);
+VIEW(edit);
+
+/* View data */
+static const char *names[] = {
+       "day", "week", "month", "year",
+       "|", "events", "todo",
+       "|", "settings", "help",
+};
+
 view_t views[] = {
-       { "Day",      day_init,      day_size,      day_draw,      day_run,      {KEY_F(1), '1',    } },
-       { "Week",     week_init,     week_size,     week_draw,     week_run,     {KEY_F(2), '2',    } },
-       { "Month",    month_init,    month_size,    month_draw,    month_run,    {KEY_F(3), '3',    } },
-       { "Year",     year_init,     year_size,     year_draw,     year_run,     {KEY_F(4), '4',    } },
-       { "|",        NULL,          NULL,          NULL,          NULL,         {                  } },
-       { "Events",   events_init,   events_size,   events_draw,   events_run,   {KEY_F(5), '5',    } },
-       { "Todo",     todo_init,     todo_size,     todo_draw,     todo_run,     {KEY_F(6), '6',    } },
-       { "|",        NULL,          NULL,          NULL,          NULL,         {                  } },
-       { "Settings", settings_init, settings_size, settings_draw, settings_run, {KEY_F(7), '7',    } },
-       { "Help",     help_init,     help_size,     help_draw,     help_run,     {KEY_F(8), '8', '?'} },
+       { "Day",      day_init,      day_size,      day_draw,      day_run,      {KEY_F(1), '1'} },
+       { "Week",     week_init,     week_size,     week_draw,     week_run,     {KEY_F(2), '2'} },
+       { "Month",    month_init,    month_size,    month_draw,    month_run,    {KEY_F(3), '3'} },
+       { "Year",     year_init,     year_size,     year_draw,     year_run,     {KEY_F(4), '4'} },
+       { "|",        NULL,          NULL,          NULL,          NULL,         {             } },
+       { "Events",   events_init,   events_size,   events_draw,   events_run,   {KEY_F(5), '5'} },
+       { "Todo",     todo_init,     todo_size,     todo_draw,     todo_run,     {KEY_F(6), '6'} },
+       { "|",        NULL,          NULL,          NULL,          NULL,         {             } },
+       { "Settings", settings_init, settings_size, settings_draw, settings_run, {KEY_F(7), '7'} },
+       { "Help",     help_init,     help_size,     help_draw,     help_run,     {KEY_F(8), '8'} },
+       { NULL,       NULL,          NULL,          NULL,          NULL,         {             } },
+       { "Edit",     edit_init,     edit_size,     edit_draw,     edit_run,     {             } },
 };
 
-int active = 6;
+/* Config data */
+int COMPACT = 0;
+int ACTIVE  = 0;
+int POPUP   = -1;
 
 /* Local functions */
 static void draw_header(void)
@@ -58,23 +88,71 @@ static void draw_header(void)
        move(0, 0);
        attron(COLOR_PAIR(COLOR_TITLE));
        for (int i = 0; i < N_ELEMENTS(views); i++) {
-               if (i == active)
+               if (!views[i].name)
+                       break;
+               if (i == ACTIVE)
                        attron(A_BOLD);
                printw("%s ", views[i].name);
-               if (i == active)
+               if (i == ACTIVE)
                        attroff(A_BOLD);
        }
+       clrtoeol();
+       if (POPUP >= 0) {
+               attron(A_BOLD);
+               move(0, COLS-strlen(views[POPUP].name)-2);
+               printw("[%s]", views[POPUP].name);
+               attroff(A_BOLD);
+       }
        attroff(COLOR_PAIR(COLOR_TITLE));
-       mvhline(1, 0, ACS_HLINE, COLS);
+       if (!COMPACT)
+               mvhline(1, 0, ACS_HLINE, COLS);
        refresh();
 }
 
 static int get_color(const char *cat)
 {
        return cat == NULL           ? 0           :
-              !strcmp(cat, "class") ? COLOR_CLASS :
-              !strcmp(cat, "ec")    ? COLOR_EC    :
-              !strcmp(cat, "work")  ? COLOR_WORK  : COLOR_OTHER ;
+              match(cat, "class") ? COLOR_CLASS :
+              match(cat, "ec")    ? COLOR_EC    :
+              match(cat, "work")  ? COLOR_WORK  : COLOR_OTHER ;
+}
+
+static int view_set(int active, int popup)
+{
+       if (ACTIVE != active) {
+               ACTIVE = active;
+               set_enum("view", 0, "active", ACTIVE,
+                               names, N_ELEMENTS(names));
+               view_draw();
+       }
+       if (POPUP != popup) {
+               POPUP = popup;
+               view_draw();
+       }
+       return 1;
+}
+
+/* Curses functions */
+void wmvresize(WINDOW *win, int top, int left, int rows, int cols)
+{
+       int y = getpary(win);
+       if (top < y)
+               mvderwin(win, top, left);
+       wresize(win, rows, cols);
+       if (top > y)
+               mvderwin(win, top, left);
+}
+
+void wshrink(WINDOW *win, int top)
+{
+       int x    = getparx(win);
+       int y    = getpary(win);
+       int r    = getmaxy(win);
+       int c    = getmaxx(win);
+       int rows = r + (y - top);
+       if (top  <  y) mvderwin(win, top, x);
+       if (rows != r) wresize(win, rows, c);
+       if (top  >  y) mvderwin(win, top, x);
 }
 
 /* Helper functions */
@@ -113,8 +191,13 @@ void event_line(WINDOW *win, event_t *event, int y, int x, int w, int full)
        if (color) wattroff(win, COLOR_PAIR(color));
 
        if (full) {
-               mvwprintw(win, y, x, " %02d:%02d - ", event->start.hour, event->start.min);
-               x += 9;
+               if (all_day(&event->start, &event->end))
+                       mvwprintw(win, y, x, " [all day]   -");
+               else
+                       mvwprintw(win, y, x, " %2d:%02d-%2d:%02d -",
+                                       event->start.hour, event->start.min,
+                                       event->end.hour,   event->end.min);
+               x += 15;
        }
        if (event->name) {
                const char *label = event->name ?: event->desc;
@@ -146,9 +229,12 @@ void todo_line(WINDOW *win, todo_t *todo, int y, int x, int w, int full)
        x += 2;
 
        /* Print time */
-       mvwprintw(win, y, x, "%04d-%02d-%02d %2d:%02d",
-                       todo->due.year, todo->due.month+1, todo->due.day+1,
-                       todo->due.hour, todo->due.min);
+       if (no_date(&todo->due))
+               mvwprintw(win, y, x, "[no due date]");
+       else
+               mvwprintw(win, y, x, "%04d-%02d-%02d %2d:%02d",
+                               todo->due.year, todo->due.month+1, todo->due.day+1,
+                               todo->due.hour, todo->due.min);
        x += 18;
 
        /* Print status */
@@ -166,69 +252,86 @@ void todo_line(WINDOW *win, todo_t *todo, int y, int x, int w, int full)
 /* View init */
 void view_init(void)
 {
+       int hdr = COMPACT ? 1 : 2;
        for (int i = 0; i < N_ELEMENTS(views); i++) {
                if (views[i].init) {
-                       views[i].win = newwin(LINES-2, COLS, 2, 0);
+                       views[i].win = newwin(LINES-hdr, COLS, hdr, 0);
                        views[i].init(views[i].win);
                }
+               if (views[i].size)
+                       views[i].size(LINES-hdr, COLS);
+       }
+}
+
+/* Config parser */
+void view_config(const char *group, const char *name, const char *key, const char *value)
+{
+       if (match(group, "view")) {
+               if (match(key, "compact"))
+                       COMPACT = get_bool(value);
+               else if (match(key, "active"))
+                       ACTIVE = get_enum(value, names, N_ELEMENTS(names));
        }
 }
 
 /* View draw */
 void view_resize(void)
 {
+       int hdr = COMPACT ? 1 : 2;
        for (int i = 0; i < N_ELEMENTS(views); i++) {
-               if (views[i].win)
-                       wresize(views[i].win, LINES-2, COLS);
+               if (views[i].win) {
+                       wresize(views[i].win, LINES-hdr, COLS);
+                       mvwin(views[i].win, hdr, 0);
+               }
                if (views[i].size)
-                       views[i].size(LINES-2, COLS);
+                       views[i].size(LINES-hdr, COLS);
        }
 }
 
 /* View draw */
 void view_draw(void)
 {
+       int view = POPUP >= 0 ? POPUP : ACTIVE;
        draw_header();
-       werase(views[active].win);
-       views[active].draw();
-       wrefresh(views[active].win);
+       werase(views[view].win);
+       views[view].draw();
+       wrefresh(views[view].win);
 }
 
-/* View set */
-int view_set(int num)
+/* View run */
+int view_run(int key, mmask_t btn, int row, int col)
 {
-       if (active != num) {
-               active = num;
+       /* Check for compact mode toggle */
+       if (key == 'c') {
+               COMPACT ^= 1;
+               set_bool("view", 0, "compact", COMPACT);
+               view_resize();
                view_draw();
+               return 1;
        }
-       return 1;
-}
 
-/* View run */
-int view_run(int key, mmask_t btn, int row, int col)
-{
        /* Check for mouse events */
        if (key == KEY_MOUSE && row == 0) {
                int start = 1;
                for (int i = 0; i < N_ELEMENTS(views); i++) {
                        int end = start + strlen(views[i].name) - 1;
                        if (start <= col && col <= end && views[i].draw)
-                               return view_set(i);
+                               return view_set(i, -1);
                        start = end + 2;
                }
        }
 
        /* Check for view change */
        for (int i = 0; i < N_ELEMENTS(views); i++) {
-               if (i == active)
+               if (i == ACTIVE)
                        continue;
                for (int j = 0; j < N_ELEMENTS(views[i].keys); j++)
                        if (views[i].keys[j] == key)
-                               return view_set(i);
+                               return view_set(i, -1);
        }
 
        /* Shift windows */
-       int num   = active;
+       int num   = ACTIVE;
        int shift = key == KEY_RIGHT ? +1 :
                    key == KEY_LEFT  ? -1 : 0;
        while (shift) {
@@ -236,9 +339,20 @@ int view_run(int key, mmask_t btn, int row, int col)
                num += N_ELEMENTS(views);
                num %= N_ELEMENTS(views);
                if (views[num].run)
-                       return view_set(num);
+                       return view_set(num, -1);
+       }
+
+       /* Handle popup views */
+       switch (key) {
+               case '\033': // escape
+                       return view_set(ACTIVE, -1);
+               case '?':    // help
+                       return view_set(ACTIVE, 9);
+               case 'e':    // edit
+                       return view_set(ACTIVE, 11);
        }
 
        /* Pass key to active view */
-       return views[active].run(key, btn, row, col);
+       int view = POPUP >= 0 ? POPUP : ACTIVE;
+       return views[view].run(key, btn, row, col);
 }