From f1a342d37aaff9a96bae27d5c14a3c7226a99d66 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 17 Jun 2013 05:35:45 +0000 Subject: [PATCH] Add cursor like movement to events and todos view This needs a lot of work, we should figure out how to better deal with scroll views between events and todos and also do a better job at keeping EVENT consistent with the SEL variable. --- views/events.c | 47 +++++++++++++++++++++++--------- views/todo.c | 72 +++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 91 insertions(+), 28 deletions(-) diff --git a/views/events.c b/views/events.c index ced1a3f..9915867 100644 --- a/views/events.c +++ b/views/events.c @@ -61,10 +61,18 @@ void events_draw(void) cur.day != next.day ; int newtime = cur.hour != next.hour || cur.min != next.min ; + + /* Update events */ + if (EVENT == NULL || compare(&EVENT->start, &start) < 0) + EVENT = event; + + /* Spacing before the date */ if ((newdate || newtime) && row != 0) row++; if (newdate && row != 0) row++; + + /* Print date */ if (newdate) { wday_t wday = day_of_week(next.year, next.month, next.day); wattron(win, A_BOLD); @@ -75,9 +83,13 @@ void events_draw(void) wattroff(win, A_BOLD); row++; } - event_line(win, event, row++-line, 4, COLS-4, SHOW_DETAILS); + + /* Print event info */ + event_line(win, event, row++-line, 4, COLS-4, + SHOW_DETAILS | SHOW_ACTIVE); if (event->name && event->desc) mvwprintw(win, row++-line, 14, "%s", event->desc); + cur = next; count += 1; } @@ -89,23 +101,32 @@ void events_draw(void) /* Events run */ int events_run(int key, mmask_t btn, int row, int col) { - int scroll = 0; + int scroll = 0, move = 0; switch (key) { - case 'g': scroll = -line; break; - case 'G': scroll = rows; break; - case 'j': scroll = 1; break; - case 'k': scroll = -1; break; - case 'd': scroll = LINES/2; break; - case 'u': scroll = -LINES/2; break; - case 'D': scroll = LINES; break; - case 'U': scroll = -LINES; break; + case 'g': scroll = -line; break; + case 'G': scroll = rows; break; + case '\005': scroll = 1; break; // ctrl-e + case '\031': scroll = -1; break; // ctrl-y + case 'd': scroll = LINES/2; break; + case 'u': scroll = -LINES/2; break; + case 'D': scroll = LINES; break; + case 'U': scroll = -LINES; break; + case 'j': move = 1; break; + case 'k': move = -1; break; + case '\012': // enter + view_edit(EDIT_EVENT); + return 1; } - line = CLAMP(line+scroll, 0, rows-1); - if (scroll) { + line = CLAMP(line+scroll, 0, rows-1); + for (int i=0; inext; i++) + EVENT = EVENT->next; + for (int i=0; i>move && EVENT && EVENT->prev; i--) + EVENT = EVENT->prev; + if (scroll || move) { werase(win); events_draw(); wrefresh(win); } - return scroll; + return scroll || move; } diff --git a/views/todo.c b/views/todo.c index 8ab6c9c..3f2b634 100644 --- a/views/todo.c +++ b/views/todo.c @@ -24,8 +24,15 @@ /* Static data */ static WINDOW *win; -static int line; -static int rows; + +static int line; // scroll offset +static int rows; // number of rows + +static int srow; // selected row +static int cursor; // index of the selected row +static int items; // number of items displayed +static int first; // cursor on first item in group +static int last; // cursor on last item in group static int show_new = 1; static int show_started = 1; @@ -34,10 +41,21 @@ static int show_finished = 0; /* Helper functions */ static int print_todos(WINDOW *win, int row, todo_t *todos, status_t low, status_t high) { - int n = 0; - for (todo_t *cur = todos; cur; cur = cur->next) - if (low <= cur->status && cur->status <= high) - todo_line(win, cur, row+n++, 4, COLS-4, SHOW_DETAILS); + int n = 0, found = 0; + for (todo_t *cur = todos; cur; cur = cur->next) { + if (low <= cur->status && cur->status <= high) { + if (found) + last = 0; + if (items++ == cursor) { + found = 1; + first = n == 0; + last = 1; + TODO = cur; + srow = row+n; + } + todo_line(win, cur, row+n++, 4, COLS-4, SHOW_DETAILS | SHOW_ACTIVE); + } + } return n; } @@ -80,6 +98,9 @@ void todo_draw(void) { int row = -line; + TODO = 0; + items = 0; + row = print_group(win, row, TODOS, show_new, "New Tasks", NEW, NEW); @@ -95,18 +116,39 @@ void todo_draw(void) /* Todo run */ int todo_run(int key, mmask_t btn, int row, int col) { - int scroll = 0, ref = 0; + int scroll = 0, move = 0, ref = 0; switch (key) { - case 'g': ref = 1; scroll = -line; break; - case 'G': ref = 1; scroll = rows; break; - case 'j': ref = 1; scroll = 1; break; - case 'k': ref = 1; scroll = -1; break; - case 'n': ref = 1; show_new ^= 1; break; - case 's': ref = 1; show_started ^= 1; break; - case 'f': ref = 1; show_finished ^= 1; break; + case 'g': ref = 1; scroll = -line; break; + case 'G': ref = 1; scroll = rows; break; + case '\005': ref = 1; scroll = 1; break; // ctrl-e + case '\031': ref = 1; scroll = -1; break; // ctrl-y + case 'j': ref = 1; move = 1; break; + case 'k': ref = 1; move = -1; break; + case 'n': ref = 1; show_new ^= 1; break; + case 's': ref = 1; show_started ^= 1; break; + case 'f': ref = 1; show_finished ^= 1; break; + case '\012': // enter + view_edit(EDIT_TODO); + return 1; } - line = CLAMP(line+scroll, 0, rows-1); + + /* Move more if we're on the edge of a group */ + int extra = 0; + if (move < 0 && first) extra = -2; + if (move > 0 && last) extra = 2; + + /* Scroll window when we move off screen */ + int next = line + srow + move + extra; + int ymax = getmaxy(win)-1; + while (next-line < 0) line--; + while (next-line > ymax) line++; + + /* Update line and cursor positions */ + line = CLAMP(line+scroll, 0, rows-1); + cursor = CLAMP(cursor+move, 0, items-1); + + /* Repaint */ if (ref) { werase(win); todo_draw(); -- 2.43.2