]> Pileus Git - lackey/blobdiff - src/view.c
Add popup views
[lackey] / src / view.c
index 437e69c1ec693e260afedf6d14988e31b40a5c10..dfc087120f8b55d40d5b6d84488c6c02ee1cd1f0 100644 (file)
@@ -21,6 +21,7 @@
 #include <ncurses.h>
 
 #include "util.h"
+#include "conf.h"
 #include "date.h"
 #include "cal.h"
 #include "view.h"
@@ -36,23 +37,48 @@ typedef struct {
        WINDOW *win;
 } view_t;
 
+/* 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 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,         {             } },
 };
 
 /* Config data */
 int COMPACT = 0;
 int ACTIVE  = 0;
+int POPUP   = -1;
 
 /* Local functions */
 static void draw_header(void)
@@ -60,12 +86,21 @@ static void draw_header(void)
        move(0, 0);
        attron(COLOR_PAIR(COLOR_TITLE));
        for (int i = 0; i < N_ELEMENTS(views); i++) {
+               if (!views[i].name)
+                       break;
                if (i == ACTIVE)
                        attron(A_BOLD);
                printw("%s ", views[i].name);
                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));
        if (!COMPACT)
                mvhline(1, 0, ACS_HLINE, COLS);
@@ -80,6 +115,44 @@ static int get_color(const char *cat)
               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 */
 void event_box(WINDOW *win, event_t *event, int y, int x, int h, int w)
 {
@@ -174,29 +247,6 @@ void todo_line(WINDOW *win, todo_t *todo, int y, int x, int w, int full)
        mvwprintw(win, y, x, "%s", desc);
 }
 
-/* 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);
-}
-
 /* View init */
 void view_init(void)
 {
@@ -211,6 +261,17 @@ void view_init(void)
        }
 }
 
+/* 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)
 {
@@ -228,20 +289,11 @@ void view_resize(void)
 /* 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);
-}
-
-/* View set */
-int view_set(int num)
-{
-       if (ACTIVE != num) {
-               ACTIVE = num;
-               view_draw();
-       }
-       return 1;
+       werase(views[view].win);
+       views[view].draw();
+       wrefresh(views[view].win);
 }
 
 /* View run */
@@ -250,6 +302,7 @@ int view_run(int key, mmask_t btn, int row, int col)
        /* Check for compact mode toggle */
        if (key == 'c') {
                COMPACT ^= 1;
+               set_bool("view", 0, "compact", COMPACT);
                view_resize();
                view_draw();
                return 1;
@@ -261,7 +314,7 @@ int view_run(int key, mmask_t btn, int row, int col)
                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;
                }
        }
@@ -272,7 +325,7 @@ int view_run(int key, mmask_t btn, int row, int col)
                        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 */
@@ -284,9 +337,18 @@ 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);
        }
 
        /* 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);
 }