]> Pileus Git - lackey/blob - src/screen.c
Start using windows and views
[lackey] / src / screen.c
1 #include <string.h>
2 #include <ncurses.h>
3 #include "main.h"
4 #include "screen.h"
5
6 /* Types */
7 typedef struct {
8         char   *name;
9         void  (*init)(WINDOW*);
10         void  (*draw)(void);
11         int   (*run)(int,mmask_t,int,int);
12         int     keys[8];
13         WINDOW *win;
14 } view_t;
15
16 /* Data */
17 view_t views[] = {
18         { "Day",      day_init,      day_draw,      day_run,      {KEY_F(1), '1', 'd',    } },
19         { "Week",     week_init,     week_draw,     week_run,     {KEY_F(2), '2', 'w',    } },
20         { "Month",    month_init,    month_draw,    month_run,    {KEY_F(3), '3', 'm',    } },
21         { "Year",     year_init,     year_draw,     year_run,     {KEY_F(4), '4', 'y',    } },
22         { "|",        NULL,          NULL,          NULL,         {                       } },
23         { "Todo",     todo_init,     todo_draw,     todo_run,     {KEY_F(5), '5', 't',    } },
24         { "Notes",    notes_init,    notes_draw,    notes_run,    {KEY_F(6), '6', 'n',    } },
25         { "|",        NULL,          NULL,          NULL,         {                       } },
26         { "Settings", settings_init, settings_draw, settings_run, {KEY_F(7), '7', 's',    } },
27         { "Help",     help_init,     help_draw,     help_run,     {KEY_F(8), '8', 'h', '?'} },
28 };
29
30 int active = 0;
31
32 /* Local functions */
33 void draw_header(void)
34 {
35         move(0, 0);
36         attron(COLOR_PAIR(COLOR_TITLE));
37         for (int i = 0; i < N_ELEMENTS(views); i++) {
38                 if (i == active)
39                         attron(A_BOLD);
40                 printw(" %s", views[i].name);
41                 if (i == active)
42                         attroff(A_BOLD);
43         }
44         attroff(COLOR_PAIR(COLOR_TITLE));
45         mvhline(1, 0, ACS_HLINE, COLS);
46         refresh();
47 }
48
49 /* Screen init */
50 void screen_init(void)
51 {
52         for (int i = 0; i < N_ELEMENTS(views); i++) {
53                 if (views[i].init) {
54                         views[i].win = newwin(LINES-2, COLS, 2, 0);
55                         views[i].init(views[i].win);
56                 }
57         }
58 }
59
60 /* Screen draw */
61 void screen_draw(void)
62 {
63         draw_header();
64         views[active].draw();
65 }
66
67 /* Screen set */
68 int screen_set(int num)
69 {
70         if (active != num) {
71                 active = num;
72                 screen_draw();
73         }
74         return 1;
75 }
76
77 /* Screen run */
78 int screen_run(int key, mmask_t btn, int row, int col)
79 {
80         /* Check for mouse events */
81         if (key == KEY_MOUSE && row == 0) {
82                 int start = 1;
83                 for (int i = 0; i < N_ELEMENTS(views); i++) {
84                         int end = start + strlen(views[i].name) - 1;
85                         if (start <= col && col <= end)
86                                 return screen_set(i);
87                         start = end + 2;
88                 }
89         }
90
91         /* Check for view change */
92         for (int i = 0; i < N_ELEMENTS(views); i++) {
93                 if (i == active)
94                         continue;
95                 for (int j = 0; j < N_ELEMENTS(views[i].keys); j++)
96                         if (views[i].keys[j] == key)
97                                 return screen_set(i);
98         }
99
100         /* Shift windows */
101         int num   = active;
102         int shift = key == KEY_RIGHT ? +1 :
103                     key == KEY_LEFT  ? -1 : 0;
104         while (shift) {
105                 num += shift;
106                 num += N_ELEMENTS(views);
107                 num %= N_ELEMENTS(views);
108                 if (views[num].run)
109                         return screen_set(num);
110         }
111
112         /* Pass key to active view */
113         return views[active].run(key, btn, row, col);
114 }