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_BINDING(k, n, f) { .key = k, .name = n, .handler = (ncdc_keyhandler_t) f }
|
||||||
#define NCDC_BINDEND() { .key = {0}, .name = NULL, .handler = NULL }
|
#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_emacs[];
|
||||||
extern ncdc_keybinding_t keys_mainwin[];
|
extern ncdc_keybinding_t keys_mainwin[];
|
||||||
|
|
||||||
|
@ -37,6 +37,11 @@
|
|||||||
#define return_if_true(v,r) do { if (v) return r; } while(0)
|
#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)
|
#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 GPtrArray *sessions;
|
||||||
extern dc_session_t current_session;
|
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);
|
ncdc_treeitem_t ncdc_treeview_root(ncdc_treeview_t t);
|
||||||
void ncdc_treeview_render(ncdc_treeview_t t, WINDOW *w, int lines, int cols);
|
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
|
#endif
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <ncdc/mainwindow.h>
|
#include <ncdc/mainwindow.h>
|
||||||
#include <ncdc/input.h>
|
#include <ncdc/input.h>
|
||||||
|
#include <ncdc/treeview.h>
|
||||||
|
|
||||||
ncdc_keybinding_t *
|
ncdc_keybinding_t *
|
||||||
ncdc_find_keybinding(ncdc_keybinding_t *keys, wchar_t const *key, size_t l)
|
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;
|
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[] = {
|
ncdc_keybinding_t keys_mainwin[] = {
|
||||||
/* ALT+KEY_RIGHT
|
/* ALT+KEY_RIGHT
|
||||||
*/
|
*/
|
||||||
|
@ -368,7 +368,9 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
|
|||||||
keylen = wcslen(key);
|
keylen = wcslen(key);
|
||||||
|
|
||||||
FILE *f = fopen("keys.txt", "a+");
|
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);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,6 +384,12 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key != NULL &&
|
||||||
|
(k = ncdc_find_keybinding(keys_guilds, key, keylen)) != NULL) {
|
||||||
|
k->handler(n->guildview);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (n->focus == FOCUS_INPUT) {
|
if (n->focus == FOCUS_INPUT) {
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
ncdc_input_feed(n->in, (wchar_t const *)&i, 1);
|
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);
|
ncdc_input_draw(n->in, n->input);
|
||||||
wnoutrefresh(n->input);
|
wnoutrefresh(n->input);
|
||||||
|
|
||||||
wbkgd(n->sep1, COLOR_PAIR(1));
|
wbkgd(n->sep1, COLOR_PAIR(ncdc_colour_separator));
|
||||||
ncdc_mainwindow_render_status(n);
|
ncdc_mainwindow_render_status(n);
|
||||||
wnoutrefresh(n->sep1);
|
wnoutrefresh(n->sep1);
|
||||||
|
|
||||||
wbkgd(n->sep2, COLOR_PAIR(1));
|
wbkgd(n->sep2, COLOR_PAIR(ncdc_colour_separator));
|
||||||
wnoutrefresh(n->sep2);
|
wnoutrefresh(n->sep2);
|
||||||
|
|
||||||
ncdc_mainwindow_update_focus(n);
|
ncdc_mainwindow_update_focus(n);
|
||||||
|
@ -179,7 +179,8 @@ int main(int ac, char **av)
|
|||||||
start_color();
|
start_color();
|
||||||
use_default_colors();
|
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();
|
mainwin = ncdc_mainwindow_new();
|
||||||
|
@ -20,6 +20,14 @@ struct ncdc_treeitem_
|
|||||||
/* user defined data
|
/* user defined data
|
||||||
*/
|
*/
|
||||||
void *tag;
|
void *tag;
|
||||||
|
|
||||||
|
/* highlight current item?
|
||||||
|
*/
|
||||||
|
bool highlight;
|
||||||
|
|
||||||
|
/* parent
|
||||||
|
*/
|
||||||
|
struct ncdc_treeitem_ *parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ncdc_treeview_
|
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,);
|
return_if_true(i == NULL || c == NULL,);
|
||||||
g_ptr_array_add(i->children, dc_ref(c));
|
g_ptr_array_add(i->children, dc_ref(c));
|
||||||
|
c->parent = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ncdc_treeitem_remove(ncdc_treeitem_t i, ncdc_treeitem_t c)
|
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;
|
size_t i = 0, off = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
wchar_t *data = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
if (t->content != NULL) {
|
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);
|
|
||||||
off = ((len + c) / cols) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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++) {
|
for (i = 0; i < t->children->len; i++) {
|
||||||
ncdc_treeitem_t child = g_ptr_array_index(t->children, i);
|
ncdc_treeitem_t child = g_ptr_array_index(t->children, i);
|
||||||
ret = ncdc_treeitem_render(child, win, lines, cols,
|
ret = ncdc_treeitem_render(child, win, lines, cols,
|
||||||
@ -147,6 +178,7 @@ ncdc_treeitem_render(ncdc_treeitem_t t, WINDOW *win,
|
|||||||
);
|
);
|
||||||
off += ret;
|
off += ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
@ -193,3 +225,89 @@ ncdc_treeitem_t ncdc_treeview_root(ncdc_treeview_t t)
|
|||||||
return_if_true(t == NULL, NULL);
|
return_if_true(t == NULL, NULL);
|
||||||
return t->root;
|
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