preliminary guild view in the side bar

This commit is contained in:
2019-07-19 20:52:12 +02:00
parent b879151e07
commit af49931b49
11 changed files with 440 additions and 8 deletions

View File

@@ -13,6 +13,7 @@ SET(SOURCES
"include/ncdc/mainwindow.h"
"include/ncdc/ncdc.h"
"include/ncdc/textview.h"
"include/ncdc/treeview.h"
"src/ack.c"
"src/cmds.c"
"src/config.c"
@@ -26,6 +27,7 @@ SET(SOURCES
"src/ncdc.c"
"src/post.c"
"src/textview.c"
"src/treeview.c"
"src/util.c"
)

View File

@@ -24,4 +24,6 @@ void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n);
void ncdc_mainwindow_rightview(ncdc_mainwindow_t n);
void ncdc_mainwindow_leftview(ncdc_mainwindow_t n);
void ncdc_mainwindow_update_guilds(ncdc_mainwindow_t n);
#endif

View File

@@ -0,0 +1,31 @@
#ifndef NCDC_TREEVIEW_H
#define NCDC_TREEVIEW_H
#include <string.h>
#include <stdlib.h>
#include <ncdc/ncdc.h>
struct ncdc_treeitem_;
typedef struct ncdc_treeitem_ *ncdc_treeitem_t;
ncdc_treeitem_t ncdc_treeitem_new(void);
ncdc_treeitem_t ncdc_treeitem_new_string(wchar_t const *s);
wchar_t const *ncdc_treeitem_label(ncdc_treeitem_t i);
void ncdc_treeitem_set_label(ncdc_treeitem_t i, wchar_t const *s);
void *ncdc_treeitem_tag(ncdc_treeitem_t i);
void ncdc_treeitem_set_tag(ncdc_treeitem_t i, void *t);
void ncdc_treeitem_clear(ncdc_treeitem_t i);
void ncdc_treeitem_add(ncdc_treeitem_t i, ncdc_treeitem_t c);
void ncdc_treeitem_remove(ncdc_treeitem_t i, ncdc_treeitem_t c);
struct ncdc_treeview_;
typedef struct ncdc_treeview_ *ncdc_treeview_t;
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);
#endif

View File

@@ -1,6 +1,7 @@
#include <ncdc/mainwindow.h>
#include <ncdc/input.h>
#include <ncdc/textview.h>
#include <ncdc/treeview.h>
#include <ncdc/cmds.h>
#include <ncdc/ncdc.h>
@@ -37,6 +38,8 @@ struct ncdc_mainwindow_
WINDOW *sep2;
ncdc_input_t in;
ncdc_treeview_t guildview;
ncdc_treeitem_t root;
GPtrArray *views;
int curview;
@@ -62,6 +65,7 @@ static void ncdc_mainwindow_free(ncdc_mainwindow_t n)
delwin(n->sep2);
dc_unref(n->in);
dc_unref(n->guildview);
if (n->views != NULL) {
g_ptr_array_unref(n->views);
@@ -81,6 +85,9 @@ ncdc_mainwindow_t ncdc_mainwindow_new(void)
ptr->in = ncdc_input_new();
ncdc_input_set_callback(ptr->in, ncdc_mainwindow_callback, ptr);
ptr->guildview = ncdc_treeview_new();
ptr->root = ncdc_treeview_root(ptr->guildview);
ptr->views = g_ptr_array_new_with_free_func(
(GDestroyNotify)dc_unref
);
@@ -134,7 +141,7 @@ ncdc_mainwindow_callback(ncdc_input_t i, wchar_t const *s,
static void ncdc_mainwindow_resize(ncdc_mainwindow_t n)
{
n->guilds_h = LINES - 2;
n->guilds_w = (COLS / 5);
n->guilds_w = (COLS / 4);
n->guilds_y = 0;
n->guilds_x = 0;
@@ -239,6 +246,85 @@ static void ncdc_mainwindow_render_status(ncdc_mainwindow_t n)
free(status);
}
void ncdc_mainwindow_update_guilds(ncdc_mainwindow_t n)
{
GHashTableIter iter;
gpointer key = NULL, value = NULL;
size_t idx = 0;
ncdc_treeitem_clear(n->root);
if (!is_logged_in()) {
return;
}
g_hash_table_iter_init(&iter, dc_session_guilds(current_session));
while (g_hash_table_iter_next(&iter, &key, &value)) {
dc_guild_t g = (dc_guild_t)value;
ncdc_treeitem_t i = ncdc_treeitem_new();
wchar_t *name = NULL;
if (i == NULL) {
continue;
}
name = s_convert(dc_guild_name(g));
if (name == NULL) {
continue;
}
ncdc_treeitem_set_label(i, name);
free(name);
name = NULL;
ncdc_treeitem_set_tag(i, g);
/* add subchannels
*/
for (idx = 0; idx < dc_guild_channels(g); idx++) {
dc_channel_t c = dc_guild_nth_channel(g, idx);
ncdc_treeitem_t ci = NULL;
if (dc_channel_name(c) == NULL ||
dc_channel_id(c) == NULL) {
continue;
}
/* skip categories, and shop channels
*/
if (dc_channel_type(c) == CHANNEL_TYPE_GUILD_CATEGORY ||
dc_channel_type(c) == CHANNEL_TYPE_GUILD_NEWS ||
dc_channel_type(c) == CHANNEL_TYPE_GUILD_STORE) {
continue;
}
ci = ncdc_treeitem_new();
if (ci == NULL) {
continue;
}
aswprintf(&name, L"[%s] %s",
(dc_channel_type(c) == CHANNEL_TYPE_GUILD_VOICE ?
"<" : "#"),
dc_channel_name(c)
);
if (name == NULL) {
continue;
}
ncdc_treeitem_set_label(ci, name);
free(name);
name = NULL;
ncdc_treeitem_set_tag(ci, c);
ncdc_treeitem_add(i, ci);
}
ncdc_treeitem_add(n->root, i);
}
}
void ncdc_mainwindow_input_ready(ncdc_mainwindow_t n)
{
wint_t i = 0;
@@ -311,6 +397,8 @@ void ncdc_mainwindow_refresh(ncdc_mainwindow_t n)
{
ncdc_textview_t v = 0;
ncdc_mainwindow_update_guilds(n);
ncdc_treeview_render(n->guildview, n->guilds, n->guilds_h, n->guilds_w);
wnoutrefresh(n->guilds);
/* render active text view

181
ncdc/src/treeview.c Normal file
View File

@@ -0,0 +1,181 @@
#include <ncdc/treeview.h>
#include <ncdc/ncdc.h>
struct ncdc_treeitem_
{
dc_refable_t ref;
/* content
*/
wchar_t *content;
/* collapsed?
*/
bool collapsed;
/* children
*/
GPtrArray *children;
/* user defined data
*/
void *tag;
};
static void ncdc_treeitem_free(ncdc_treeitem_t t)
{
return_if_true(t == NULL,);
free(t->content);
t->content = NULL;
if (t->children != NULL) {
g_ptr_array_unref(t->children);
t->children = NULL;
}
free(t);
}
ncdc_treeitem_t ncdc_treeitem_new(void)
{
ncdc_treeitem_t t = calloc(1, sizeof(struct ncdc_treeitem_));
return_if_true(t == NULL, NULL);
t->ref.cleanup = (dc_cleanup_t)ncdc_treeitem_free;
t->children = g_ptr_array_new_with_free_func((GDestroyNotify)dc_unref);
if (t->children == NULL) {
free(t);
return NULL;
}
return dc_ref(t);
}
ncdc_treeitem_t ncdc_treeitem_new_string(wchar_t const *s)
{
ncdc_treeitem_t t = ncdc_treeitem_new();
return_if_true(t == NULL, NULL);
t->content = wcsdup(s);
return t;
}
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));
}
void ncdc_treeitem_remove(ncdc_treeitem_t i, ncdc_treeitem_t c)
{
return_if_true(i == NULL || c == NULL,);
g_ptr_array_remove(i->children, c);
}
void ncdc_treeitem_clear(ncdc_treeitem_t i)
{
return_if_true(i == NULL || i->children == NULL,);
return_if_true(i->children->len == 0,);
g_ptr_array_remove_range(i->children, 0, i->children->len);
}
void *ncdc_treeitem_tag(ncdc_treeitem_t i)
{
return_if_true(i == NULL, NULL);
return i->tag;
}
void ncdc_treeitem_set_tag(ncdc_treeitem_t i, void *t)
{
return_if_true(i == NULL,);
i->tag = t;
}
wchar_t const *ncdc_treeitem_label(ncdc_treeitem_t i)
{
return_if_true(i == NULL, NULL);
return i->content;
}
void ncdc_treeitem_set_label(ncdc_treeitem_t i, wchar_t const *s)
{
return_if_true(i == NULL || s == NULL,);
free(i->content);
i->content = wcsdup(s);
}
static int
ncdc_treeitem_render(ncdc_treeitem_t t, WINDOW *win,
int lines, int cols, int l, int c)
{
size_t i = 0, off = 0;
int ret = 0;
if (t->content != NULL) {
size_t len = wcslen(t->content);
mvwaddwstr(win, l, c, t->content);
off = ((len + c) / cols) + 1;
}
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;
}
struct ncdc_treeview_
{
dc_refable_t ref;
ncdc_treeitem_t root;
};
static void ncdc_treeview_free(ncdc_treeview_t t)
{
return_if_true(t == NULL,);
dc_unref(t->root);
t->root = NULL;
free(t);
}
ncdc_treeview_t ncdc_treeview_new(void)
{
ncdc_treeview_t t = calloc(1, sizeof(struct ncdc_treeview_));
return_if_true(t == NULL, NULL);
t->ref.cleanup = (dc_cleanup_t)ncdc_treeview_free;
t->root = ncdc_treeitem_new();
goto_if_true(t->root == NULL, error);
return dc_ref(t);
error:
dc_unref(t);
return NULL;
}
void ncdc_treeview_render(ncdc_treeview_t t, WINDOW *w, int lines, int cols)
{
werase(w);
wmove(w, 0, 0);
ncdc_treeitem_render(t->root, w, lines, cols, 0, 0);
}
ncdc_treeitem_t ncdc_treeview_root(ncdc_treeview_t t)
{
return_if_true(t == NULL, NULL);
return t->root;
}