diff --git a/ncdc/include/ncdc/keycodes.h b/ncdc/include/ncdc/keycodes.h index 7d494c9..59b813b 100644 --- a/ncdc/include/ncdc/keycodes.h +++ b/ncdc/include/ncdc/keycodes.h @@ -15,6 +15,7 @@ typedef struct { #define NCDC_BINDING(k, n, f) { .key = k, .name = n, .handler = (ncdc_keyhandler_t) f } #define NCDC_BINDEND() { .key = {0}, .name = NULL, .handler = NULL } +extern ncdc_keybinding_t keys_guilds[]; extern ncdc_keybinding_t keys_emacs[]; extern ncdc_keybinding_t keys_mainwin[]; diff --git a/ncdc/include/ncdc/ncdc.h b/ncdc/include/ncdc/ncdc.h index 1b2f468..fa926d3 100644 --- a/ncdc/include/ncdc/ncdc.h +++ b/ncdc/include/ncdc/ncdc.h @@ -37,6 +37,11 @@ #define return_if_true(v,r) do { if (v) return r; } while(0) #define goto_if_true(v,l) do { if (v) goto l; } while(0) +typedef enum { + ncdc_colour_separator = 1, + ncdc_colour_treehighlight = 2, +} ncdc_colour_pair; + extern GPtrArray *sessions; extern dc_session_t current_session; diff --git a/ncdc/include/ncdc/treeview.h b/ncdc/include/ncdc/treeview.h index 0424f57..e2ff1ba 100644 --- a/ncdc/include/ncdc/treeview.h +++ b/ncdc/include/ncdc/treeview.h @@ -29,4 +29,11 @@ ncdc_treeview_t ncdc_treeview_new(void); ncdc_treeitem_t ncdc_treeview_root(ncdc_treeview_t t); void ncdc_treeview_render(ncdc_treeview_t t, WINDOW *w, int lines, int cols); +/* move the cursor around, and collapse/expand items + */ +void ncdc_treeview_previous(ncdc_treeview_t t); +void ncdc_treeview_next(ncdc_treeview_t t); +void ncdc_treeview_collapse(ncdc_treeview_t t); +void ncdc_treeview_expand(ncdc_treeview_t t); + #endif diff --git a/ncdc/src/keycodes.c b/ncdc/src/keycodes.c index 845d2a2..5eef037 100644 --- a/ncdc/src/keycodes.c +++ b/ncdc/src/keycodes.c @@ -2,6 +2,7 @@ #include #include +#include ncdc_keybinding_t * ncdc_find_keybinding(ncdc_keybinding_t *keys, wchar_t const *key, size_t l) @@ -18,6 +19,22 @@ ncdc_find_keybinding(ncdc_keybinding_t *keys, wchar_t const *key, size_t l) return NULL; } +ncdc_keybinding_t keys_guilds[] = { + /* CTRL+KEY_UP + */ + NCDC_BINDING(L"\x1B[1;5A", L"previous-item", ncdc_treeview_previous), + /* CTRL+KEY_DOWN + */ + NCDC_BINDING(L"\x1B[1;5B", L"next-item", ncdc_treeview_next), + /* CTRL+KEY_RIGHT + */ + NCDC_BINDING(L"\x1B[1;5C", L"expand-item", ncdc_treeview_expand), + /* CTRL+KEY_LEFT + */ + NCDC_BINDING(L"\x1B[1;5D", L"collapse-item", ncdc_treeview_collapse), + NCDC_BINDEND() +}; + ncdc_keybinding_t keys_mainwin[] = { /* ALT+KEY_RIGHT */ diff --git a/ncdc/src/mainwindow.c b/ncdc/src/mainwindow.c index 21acb98..55cee06 100644 --- a/ncdc/src/mainwindow.c +++ b/ncdc/src/mainwindow.c @@ -368,7 +368,9 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n) keylen = wcslen(key); FILE *f = fopen("keys.txt", "a+"); - fwprintf(f, L"KEY: %ls\n", key); + fwprintf(f, L"KEY: %02X %ls\n", + key[0], &key[1] + ); fclose(f); } @@ -382,6 +384,12 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n) return; } + if (key != NULL && + (k = ncdc_find_keybinding(keys_guilds, key, keylen)) != NULL) { + k->handler(n->guildview); + return; + } + if (n->focus == FOCUS_INPUT) { if (key == NULL) { ncdc_input_feed(n->in, (wchar_t const *)&i, 1); @@ -422,11 +430,11 @@ void ncdc_mainwindow_refresh(ncdc_mainwindow_t n) ncdc_input_draw(n->in, n->input); wnoutrefresh(n->input); - wbkgd(n->sep1, COLOR_PAIR(1)); + wbkgd(n->sep1, COLOR_PAIR(ncdc_colour_separator)); ncdc_mainwindow_render_status(n); wnoutrefresh(n->sep1); - wbkgd(n->sep2, COLOR_PAIR(1)); + wbkgd(n->sep2, COLOR_PAIR(ncdc_colour_separator)); wnoutrefresh(n->sep2); ncdc_mainwindow_update_focus(n); diff --git a/ncdc/src/ncdc.c b/ncdc/src/ncdc.c index e17ce6d..d33bfe0 100644 --- a/ncdc/src/ncdc.c +++ b/ncdc/src/ncdc.c @@ -179,7 +179,8 @@ int main(int ac, char **av) start_color(); use_default_colors(); - init_pair(1, COLOR_WHITE, COLOR_BLUE); + init_pair(ncdc_colour_separator, COLOR_WHITE, COLOR_BLUE); + init_pair(ncdc_colour_treehighlight, COLOR_WHITE, COLOR_RED); } mainwin = ncdc_mainwindow_new(); diff --git a/ncdc/src/treeview.c b/ncdc/src/treeview.c index d93312a..07a545f 100644 --- a/ncdc/src/treeview.c +++ b/ncdc/src/treeview.c @@ -20,6 +20,14 @@ struct ncdc_treeitem_ /* user defined data */ void *tag; + + /* highlight current item? + */ + bool highlight; + + /* parent + */ + struct ncdc_treeitem_ *parent; }; struct ncdc_treeview_ @@ -86,6 +94,7 @@ void ncdc_treeitem_add(ncdc_treeitem_t i, ncdc_treeitem_t c) { return_if_true(i == NULL || c == NULL,); g_ptr_array_add(i->children, dc_ref(c)); + c->parent = i; } void ncdc_treeitem_remove(ncdc_treeitem_t i, ncdc_treeitem_t c) @@ -132,20 +141,43 @@ ncdc_treeitem_render(ncdc_treeitem_t t, WINDOW *win, { size_t i = 0, off = 0; int ret = 0; + wchar_t *data = NULL; + size_t len = 0; if (t->content != NULL) { - size_t len = wcslen(t->content); + if (t->highlight) { + wattron(win, COLOR_PAIR(ncdc_colour_treehighlight)); + } - mvwaddwstr(win, l, c, t->content); + if (t->children->len > 0) { + aswprintf(&data, L"[%c] %ls", + (t->collapsed ? '-' : '+'), + t->content + ); + } else { + data = wcsdup(t->content); + } + len = wcslen(data); + + mvwaddwstr(win, l, c, data); off = ((len + c) / cols) + 1; + + free(data); + data = NULL; + + if (t->highlight) { + wattroff(win, COLOR_PAIR(ncdc_colour_treehighlight)); + } } - for (i = 0; i < t->children->len; i++) { - ncdc_treeitem_t child = g_ptr_array_index(t->children, i); - ret = ncdc_treeitem_render(child, win, lines, cols, - l + off, c + 1 - ); - off += ret; + if (!t->collapsed) { + for (i = 0; i < t->children->len; i++) { + ncdc_treeitem_t child = g_ptr_array_index(t->children, i); + ret = ncdc_treeitem_render(child, win, lines, cols, + l + off, c + 1 + ); + off += ret; + } } return off; @@ -193,3 +225,89 @@ ncdc_treeitem_t ncdc_treeview_root(ncdc_treeview_t t) return_if_true(t == NULL, NULL); return t->root; } + +void ncdc_treeview_previous(ncdc_treeview_t t) +{ + return_if_true(t == NULL,); + + ncdc_treeitem_t cur = t->current; + ncdc_treeitem_t found = NULL, child = NULL; + size_t i = 0; + + if (cur->parent != NULL) { + for (i = 0; i < cur->parent->children->len; i++) { + child = g_ptr_array_index(cur->parent->children, i); + if (child == cur && i > 0) { + found = g_ptr_array_index(cur->parent->children, i-1); + break; + } + } + } + + if (found == NULL) { + cur = cur->parent; + } else { + cur = found; + } + + if (cur == NULL) { + cur = t->root; + } + + t->current->highlight = false; + cur->highlight = true; + t->current = cur; +} + +void ncdc_treeview_next(ncdc_treeview_t t) +{ + return_if_true(t == NULL,); + + ncdc_treeitem_t cur = t->current; + ncdc_treeitem_t found = NULL; + ncdc_treeitem_t child = NULL; + size_t i = 0; + + if (cur->children->len == 0 || cur->collapsed) { + while (cur != NULL && cur->parent != NULL && found == NULL) { + + found = NULL; + for (i = 0; i < cur->parent->children->len; i++) { + child = g_ptr_array_index(cur->parent->children, i); + if (child == cur && i < cur->parent->children->len-1) { + found = g_ptr_array_index(cur->parent->children, i+1); + break; + } + } + + if (found == NULL) { + cur = cur->parent; + } + } + cur = found; + } else if (cur->children->len > 0 && !cur->collapsed) { + cur = g_ptr_array_index(cur->children, 0); + } + + if (cur == NULL) { + cur = t->root; + } + + t->current->highlight = false; + cur->highlight = true; + t->current = cur; +} + +void ncdc_treeview_collapse(ncdc_treeview_t t) +{ + return_if_true(t == NULL || t->current == NULL,); + return_if_true(t->current == t->root,); + t->current->collapsed = true; +} + +void ncdc_treeview_expand(ncdc_treeview_t t) +{ + return_if_true(t == NULL || t->current == NULL,); + return_if_true(t->current == t->root,); + t->current->collapsed = false; +}