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*))
182 struct tui_list *wl = (struct tui_list*)w;
183 assert(wl->type == TUI_LIST);
186 cmpfunc = (int (*)(const void*, const void*))strcmp;
189 nelem = darr_size(wl->entries);
190 qsort(wl->entries, nelem, sizeof *wl->entries, cmpfunc);
193 static void draw_list(struct tui_widget *w, void *cls)
195 int i, x, y, num, idx;
196 struct tui_list *wl = (struct tui_list*)w;
198 tui_wtoscr(w, 0, 0, &x, &y);
200 tg_bgcolor(TGFX_BLUE);
201 tg_fgcolor(TGFX_CYAN);
202 tg_rect(wl->title, x, y, wl->width, wl->height, TGFX_FRAME);
204 num = darr_size(wl->entries);
205 if(num > wl->height - 2) {
206 num = wl->height - 2;
210 for(i=0; i<num; i++) {
211 idx = i + wl->view_offs;
213 tg_bgcolor(TGFX_CYAN);
214 tg_fgcolor(TGFX_BLUE);
216 tg_rect(0, x, ++y, wl->width-2, 1, 0);
217 tg_text(x, y, "%s", wl->entries[idx]);
219 tg_bgcolor(TGFX_BLUE);
220 tg_fgcolor(TGFX_CYAN);
222 tg_text(x, ++y, "%s", wl->entries[idx]);