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,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; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user