10 static void free_list(struct tui_widget *w, void *cls);
11 static void draw_list(struct tui_widget *w, void *cls);
13 struct tui_widget *tui_list(const char *title, int x, int y, int width, int height, tui_callback cbfunc, void *cbdata)
17 if(!(w = calloc(1, sizeof *w))) {
21 w->title = strdup(title);
27 w->entries = darr_alloc(0, sizeof *w->entries);
32 tui_set_callback((struct tui_widget*)w, TUI_ONMODIFY, cbfunc, cbdata);
34 tui_set_callback((struct tui_widget*)w, TUI_FREE, free_list, 0);
35 tui_set_callback((struct tui_widget*)w, TUI_DRAW, draw_list, 0);
36 return (struct tui_widget*)w;
39 static void free_list(struct tui_widget *w, void *cls)
41 struct tui_list *wl = (struct tui_list*)w;
44 darr_free(wl->entries);
48 void tui_clear_list(struct tui_widget *w)
51 struct tui_list *wl = (struct tui_list*)w;
52 assert(wl->type == TUI_LIST);
54 for(i=0; i<darr_size(wl->entries); i++) {
57 darr_clear(wl->entries);
61 void tui_add_list_item(struct tui_widget *w, const char *text)
64 struct tui_list *wl = (struct tui_list*)w;
65 assert(wl->type == TUI_LIST);
66 str = strdup_nf(text);
67 darr_push(wl->entries, &str);
71 int tui_num_list_items(struct tui_widget *w)
73 struct tui_list *wl = (struct tui_list*)w;
74 assert(wl->type == TUI_LIST);
75 return darr_size(wl->entries);
78 int tui_list_select(struct tui_widget *w, int idx)
81 struct tui_list *wl = (struct tui_list*)w;
82 assert(wl->type == TUI_LIST);
85 return 0; /* no change */
92 if(idx >= (nelem = darr_size(wl->entries))) {
97 if(idx < wl->view_offs || idx >= wl->view_offs + wl->height) {
98 offs = idx - wl->height / 2;
99 if(offs + wl->height >= nelem) {
100 offs = nelem - wl->height;
105 wl->view_offs = offs;
112 int tui_get_list_sel(struct tui_widget *w)
114 struct tui_list *wl = (struct tui_list*)w;
115 assert(wl->type == TUI_LIST);
119 int tui_list_sel_next(struct tui_widget *w)
122 struct tui_list *wl = (struct tui_list*)w;
123 assert(wl->type == TUI_LIST);
125 nelem = darr_size(wl->entries);
127 if(wl->sel + 1 >= nelem) {
131 if(++wl->sel - wl->view_offs >= wl->height) {
132 wl->view_offs = wl->sel - wl->height;
138 int tui_list_sel_prev(struct tui_widget *w)
140 struct tui_list *wl = (struct tui_list*)w;
141 assert(wl->type == TUI_LIST);
146 if(--wl->sel < wl->view_offs) {
147 wl->view_offs = wl->sel;
153 int tui_list_sel_start(struct tui_widget *w)
155 struct tui_list *wl = (struct tui_list*)w;
156 assert(wl->type == TUI_LIST);
164 int tui_list_sel_end(struct tui_widget *w)
167 struct tui_list *wl = (struct tui_list*)w;
168 assert(wl->type == TUI_LIST);
170 nelem = darr_size(wl->entries);
173 wl->view_offs = nelem - wl->height;
174 if(wl->view_offs < 0) wl->view_offs = 0;
179 void tui_sort_list(struct tui_widget *w, int (*cmpfunc)(const void*, const void*))
181 struct tui_list *wl = (struct tui_list*)w;
182 assert(wl->type == TUI_LIST);
185 cmpfunc = (int (*)(const void*, const void*))strcmp;
187 qsort(wl->entries, darr_size(wl->entries), sizeof *wl->entries, cmpfunc);
190 static void draw_list(struct tui_widget *w, void *cls)
192 int i, x, y, num, idx;
193 struct tui_list *wl = (struct tui_list*)w;
195 tui_wtoscr(w, 0, 0, &x, &y);
197 tg_bgcolor(TGFX_BLUE);
198 tg_fgcolor(TGFX_CYAN);
199 tg_rect(wl->title, x, y, wl->width, wl->height, TGFX_FRAME);
201 num = darr_size(wl->entries);
202 if(num > wl->height - 2) {
203 num = wl->height - 2;
207 for(i=0; i<num; i++) {
208 idx = i + wl->view_offs;
210 tg_bgcolor(TGFX_CYAN);
211 tg_fgcolor(TGFX_BLUE);
213 tg_rect(0, x, ++y, wl->width-2, 1, 0);
214 tg_text(x, y, "%s", wl->entries[idx]);
216 tg_bgcolor(TGFX_BLUE);
217 tg_fgcolor(TGFX_CYAN);
219 tg_text(x, ++y, "%s", wl->entries[idx]);