preliminary guild view in the side bar
This commit is contained in:
parent
b879151e07
commit
af49931b49
@ -21,27 +21,27 @@ typedef enum {
|
||||
|
||||
/* A direct message channel for 1:1 communication
|
||||
*/
|
||||
CHANNEL_TYPE_DM,
|
||||
CHANNEL_TYPE_DM = 1,
|
||||
|
||||
/* A guild voice channel
|
||||
*/
|
||||
CHANNEL_TYPE_GUILD_VOICE,
|
||||
CHANNEL_TYPE_GUILD_VOICE = 2,
|
||||
|
||||
/* Group direct message channel 1:N communication
|
||||
*/
|
||||
CHANNEL_TYPE_GROUP_DM,
|
||||
CHANNEL_TYPE_GROUP_DM = 3,
|
||||
|
||||
/* Category within a GUILD
|
||||
*/
|
||||
CHANNEL_TYPE_GUILD_CATEGORY,
|
||||
CHANNEL_TYPE_GUILD_CATEGORY = 4,
|
||||
|
||||
/* News channel
|
||||
*/
|
||||
CHANNEL_TYPE_GUILD_NEWS,
|
||||
CHANNEL_TYPE_GUILD_NEWS = 5,
|
||||
|
||||
/* Guild store, no idea what this is
|
||||
*/
|
||||
CHANNEL_TYPE_GUILD_STORE,
|
||||
CHANNEL_TYPE_GUILD_STORE = 6,
|
||||
} dc_channel_type_t;
|
||||
|
||||
struct dc_channel_;
|
||||
@ -51,6 +51,7 @@ dc_channel_t dc_channel_new(void);
|
||||
dc_channel_t dc_channel_from_json(json_t *j);
|
||||
|
||||
char const *dc_channel_id(dc_channel_t c);
|
||||
char const *dc_channel_name(dc_channel_t c);
|
||||
|
||||
dc_channel_type_t dc_channel_type(dc_channel_t c);
|
||||
bool dc_channel_is_dm(dc_channel_t c);
|
||||
|
@ -1,12 +1,21 @@
|
||||
#ifndef DC_GUILD_H
|
||||
#define DC_GUILD_H
|
||||
|
||||
#include <dc/channel.h>
|
||||
|
||||
#include <jansson.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Discords version of groups or chat servers
|
||||
*/
|
||||
struct dc_guild_;
|
||||
typedef struct dc_guild_ *dc_guild_t;
|
||||
|
||||
dc_guild_t dc_guild_new(void);
|
||||
dc_guild_t dc_guild_from_json(json_t *j);
|
||||
|
||||
size_t dc_guild_channels(dc_guild_t d);
|
||||
dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx);
|
||||
|
||||
char const *dc_guild_name(dc_guild_t d);
|
||||
void dc_guild_set_name(dc_guild_t d, char const *val);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <dc/account.h>
|
||||
#include <dc/channel.h>
|
||||
#include <dc/gateway.h>
|
||||
#include <dc/guild.h>
|
||||
|
||||
/**
|
||||
* A session object will contain all information gathered after a user
|
||||
@ -86,6 +87,12 @@ dc_channel_t dc_session_make_channel(dc_session_t s, dc_account_t *r,
|
||||
dc_channel_t dc_session_channel_recipients(dc_session_t s,
|
||||
dc_account_t *r, size_t sz);
|
||||
|
||||
/**
|
||||
* Add a guild to be managed by this session.
|
||||
*/
|
||||
void dc_session_add_guild(dc_session_t s, dc_guild_t g);
|
||||
GHashTable *dc_session_guilds(dc_session_t s);
|
||||
|
||||
/**
|
||||
* comparision functions for sorting, and finding
|
||||
*/
|
||||
|
@ -124,7 +124,7 @@ dc_channel_t dc_channel_from_json(json_t *j)
|
||||
}
|
||||
|
||||
v = json_object_get(j, "name");
|
||||
if (v == NULL && json_is_string(v)) {
|
||||
if (v != NULL && json_is_string(v)) {
|
||||
c->name = strdup(json_string_value(v));
|
||||
}
|
||||
|
||||
@ -237,6 +237,12 @@ json_t *dc_channel_to_json(dc_channel_t c)
|
||||
return j;
|
||||
}
|
||||
|
||||
char const *dc_channel_name(dc_channel_t c)
|
||||
{
|
||||
return_if_true(c == NULL, NULL);
|
||||
return c->name;
|
||||
}
|
||||
|
||||
char const *dc_channel_id(dc_channel_t c)
|
||||
{
|
||||
return_if_true(c == NULL, NULL);
|
||||
|
@ -9,6 +9,8 @@ struct dc_guild_
|
||||
|
||||
char *name;
|
||||
char *id;
|
||||
|
||||
GPtrArray *channels;
|
||||
};
|
||||
|
||||
static void dc_guild_free(dc_guild_t ptr)
|
||||
@ -16,6 +18,11 @@ static void dc_guild_free(dc_guild_t ptr)
|
||||
free(ptr->name);
|
||||
free(ptr->id);
|
||||
|
||||
if (ptr->channels != NULL) {
|
||||
g_ptr_array_unref(ptr->channels);
|
||||
ptr->channels = NULL;
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
@ -26,9 +33,64 @@ dc_guild_t dc_guild_new(void)
|
||||
|
||||
p->ref.cleanup = (dc_cleanup_t)dc_guild_free;
|
||||
|
||||
p->channels = g_ptr_array_new_with_free_func((GDestroyNotify)dc_unref);
|
||||
if (p->channels == NULL) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dc_ref(p);
|
||||
}
|
||||
|
||||
dc_guild_t dc_guild_from_json(json_t *j)
|
||||
{
|
||||
dc_guild_t g = dc_guild_new();
|
||||
json_t *val = NULL;
|
||||
json_t *c = NULL;
|
||||
size_t idx = 0;
|
||||
|
||||
val = json_object_get(j, "name");
|
||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
||||
g->name = strdup(json_string_value(val));
|
||||
|
||||
val = json_object_get(j, "id");
|
||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
||||
g->id = strdup(json_string_value(val));
|
||||
|
||||
/* there is a ton of more information here, that we should look
|
||||
* add, including "member_count", "owner_id", but for channels
|
||||
* will do nicely
|
||||
*/
|
||||
val = json_object_get(j, "channels");
|
||||
goto_if_true(val == NULL || !json_is_array(val), error);
|
||||
|
||||
json_array_foreach(val, idx, c) {
|
||||
dc_channel_t chan = dc_channel_from_json(c);
|
||||
continue_if_true(chan == NULL);
|
||||
g_ptr_array_add(g->channels, chan);
|
||||
}
|
||||
|
||||
return g;
|
||||
|
||||
error:
|
||||
|
||||
dc_unref(g);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t dc_guild_channels(dc_guild_t d)
|
||||
{
|
||||
return_if_true(d == NULL || d->channels == NULL, 0);
|
||||
return d->channels->len;
|
||||
}
|
||||
|
||||
dc_channel_t dc_guild_nth_channel(dc_guild_t d, size_t idx)
|
||||
{
|
||||
return_if_true(d == NULL || d->channels == NULL, NULL);
|
||||
return_if_true(idx >= d->channels->len, NULL);
|
||||
return g_ptr_array_index(d->channels, idx);
|
||||
}
|
||||
|
||||
char const *dc_guild_name(dc_guild_t d)
|
||||
{
|
||||
return_if_true(d == NULL, NULL);
|
||||
|
@ -12,6 +12,7 @@ struct dc_session_
|
||||
|
||||
GHashTable *accounts;
|
||||
GHashTable *channels;
|
||||
GHashTable *guilds;
|
||||
};
|
||||
|
||||
/* event handlers
|
||||
@ -40,6 +41,11 @@ static void dc_session_free(dc_session_t s)
|
||||
s->channels = NULL;
|
||||
}
|
||||
|
||||
if (s->guilds != NULL) {
|
||||
g_hash_table_unref(s->guilds);
|
||||
s->guilds = NULL;
|
||||
}
|
||||
|
||||
dc_session_logout(s);
|
||||
|
||||
dc_unref(s->api);
|
||||
@ -79,6 +85,7 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
|
||||
size_t idx = 0;
|
||||
json_t *c = NULL;
|
||||
json_t *channels = NULL;
|
||||
json_t *guilds = NULL;
|
||||
|
||||
/* retrieve user information about ourselves, including snowflake,
|
||||
* discriminator, and other things
|
||||
@ -127,6 +134,17 @@ static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
|
||||
}
|
||||
}
|
||||
|
||||
/* load guilds
|
||||
*/
|
||||
guilds = json_object_get(r, "guilds");
|
||||
if (guilds != NULL && json_is_array(guilds)) {
|
||||
json_array_foreach(guilds, idx, c) {
|
||||
dc_guild_t guild = dc_guild_from_json(c);
|
||||
continue_if_true(guild == NULL);
|
||||
dc_session_add_guild(s, guild);
|
||||
}
|
||||
}
|
||||
|
||||
/* load channels
|
||||
*/
|
||||
channels = json_object_get(r, "private_channels");
|
||||
@ -181,6 +199,11 @@ dc_session_t dc_session_new(dc_loop_t loop)
|
||||
);
|
||||
goto_if_true(s->channels == NULL, error);
|
||||
|
||||
s->guilds = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
free, dc_unref
|
||||
);
|
||||
goto_if_true(s->channels == NULL, error);
|
||||
|
||||
s->loop = dc_ref(loop);
|
||||
|
||||
s->api = dc_api_new();
|
||||
@ -394,3 +417,23 @@ dc_channel_t dc_session_channel_recipients(dc_session_t s,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GHashTable *dc_session_guilds(dc_session_t s)
|
||||
{
|
||||
return_if_true(s == NULL, NULL);
|
||||
return s->guilds;
|
||||
}
|
||||
|
||||
void dc_session_add_guild(dc_session_t s, dc_guild_t g)
|
||||
{
|
||||
return_if_true(s == NULL || g == NULL,);
|
||||
return_if_true(dc_guild_id(g) == NULL,);
|
||||
|
||||
char const *id = dc_guild_id(g);
|
||||
|
||||
if (!g_hash_table_contains(s->guilds, id)) {
|
||||
g_hash_table_insert(s->guilds, strdup(id), dc_ref(g));
|
||||
/* TODO: dedup for saving storage
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
|
31
ncdc/include/ncdc/treeview.h
Normal file
31
ncdc/include/ncdc/treeview.h
Normal 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
|
@ -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
181
ncdc/src/treeview.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user