introduce treeview navigation and collapsing
This commit is contained in:
parent
d9c276c68c
commit
9a90773210
@ -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[];
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <ncdc/mainwindow.h>
|
||||
#include <ncdc/input.h>
|
||||
#include <ncdc/treeview.h>
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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,14 +141,36 @@ 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);
|
||||
|
||||
mvwaddwstr(win, l, c, t->content);
|
||||
off = ((len + c) / cols) + 1;
|
||||
if (t->highlight) {
|
||||
wattron(win, COLOR_PAIR(ncdc_colour_treehighlight));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
@ -147,6 +178,7 @@ ncdc_treeitem_render(ncdc_treeitem_t t, WINDOW *win,
|
||||
);
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user