local navigation
[oftp] / src / tui.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <assert.h>
5 #include "tui.h"
6 #include "tuipriv.h"
7 #include "tgfx.h"
8 #include "darray.h"
9 #include "util.h"
10
11
12 int tui_init(void)
13 {
14         return 0;
15 }
16
17 void tui_shutdown(void)
18 {
19 }
20
21
22 struct tui_widget *tui_widget(int type)
23 {
24         struct tui_widget *w;
25
26         if(!(w = calloc(1, sizeof *w))) {
27                 return 0;
28         }
29         w->type = type;
30         return w;
31 }
32
33 void tui_free(struct tui_widget *w)
34 {
35         if(w) {
36                 if(w->cbfunc[TUI_FREE]) {
37                         w->cbfunc[TUI_FREE](w, 0);
38                 }
39                 free(w->title);
40                 free(w);
41         }
42 }
43
44 void tui_add_widget(struct tui_widget *par, struct tui_widget *w)
45 {
46         if(w->par == par) return;
47
48         w->next = par->child;
49         par->child = w;
50         w->par = par;
51 }
52
53 void tui_remove_widget(struct tui_widget *par, struct tui_widget *w)
54 {
55         struct tui_widget *iter, dummy;
56
57         if(w->par != par) {
58                 fprintf(stderr, "failed to remove widget %p from %p\n", (void*)w, (void*)par);
59                 return;
60         }
61
62         dummy.next = par->child;
63         iter = &dummy;
64         while(iter->next) {
65                 if(iter->next == w) {
66                         iter->next = w->next;
67                         break;
68                 }
69                 iter = iter->next;
70         }
71         par->child = dummy.next;
72
73         w->next = 0;
74         w->par = 0;
75 }
76
77 struct tui_widget *tui_parent(struct tui_widget *w)
78 {
79         return w->par;
80 }
81
82 int tui_isdirty(struct tui_widget *w)
83 {
84         return w->dirty;
85 }
86
87 void tui_draw(struct tui_widget *w)
88 {
89         struct tui_widget *iter;
90
91         if(w->cbfunc[TUI_DRAW]) {
92                 w->cbfunc[TUI_DRAW](w, 0);
93         }
94         w->dirty = 0;
95
96         iter = w->child;
97         while(iter) {
98                 tui_draw(iter);
99                 iter = iter->next;
100         }
101
102         tg_redraw();
103 }
104
105 void tui_set_callback(struct tui_widget *w, int type, tui_callback func, void *cls)
106 {
107         w->cbfunc[type] = func;
108         w->cbcls[type] = cls;
109 }
110
111 void tui_call_callback(struct tui_widget *w, int type)
112 {
113         if(w->cbfunc[type]) {
114                 w->cbfunc[type](w, w->cbcls[type]);
115         }
116 }
117
118 void tui_focus(struct tui_widget *w, int focus)
119 {
120         focus = focus ? 1 : 0;
121         if(w->focus == focus) {
122                 return;
123         }
124         w->focus = focus;
125         w->dirty = 1;
126         tui_call_callback(w, TUI_ONFOCUS);
127 }
128
129 int tui_set_title(struct tui_widget *w, const char *s)
130 {
131         free(w->title);
132         w->title = strdup_nf(s);
133         return 0;
134 }
135
136 const char *tui_get_title(struct tui_widget *w)
137 {
138         return w->title;
139 }
140
141 struct tui_widget *tui_window(const char *title, int x, int y, int width, int height)
142 {
143         struct tui_widget *w;
144
145         if(!(w = tui_widget(TUI_WINDOW))) {
146                 return 0;
147         }
148         w->title = strdup(title);
149         w->x = x;
150         w->y = y;
151         w->width = width;
152         w->height = height;
153         return w;
154 }
155
156 struct tui_widget *tui_button(const char *title, int x, int y, tui_callback cbfunc, void *cbdata)
157 {
158         struct tui_widget *w;
159
160         if(!(w = tui_widget(TUI_BUTTON))) {
161                 return 0;
162         }
163         w->title = strdup(title);
164         w->x = x;
165         w->y = y;
166         w->width = strlen(title) + 2;
167         w->height = 1;
168
169         if(cbfunc) {
170                 tui_set_callback(w, TUI_ONCLICK, cbfunc, cbdata);
171         }
172         return w;
173 }
174
175 void tui_wtoscr(struct tui_widget *w, int x, int y, int *retx, int *rety)
176 {
177         while(w) {
178                 x += w->x;
179                 y += w->y;
180                 w = w->par;
181         }
182         *retx = x;
183         *rety = y;
184 }
185
186 void tui_scrtow(struct tui_widget *w, int x, int y, int *retx, int *rety)
187 {
188         while(w) {
189                 x -= w->x;
190                 y -= w->y;
191                 w = w->par;
192         }
193         *retx = x;
194         *rety = y;
195 }
196
197
198 void tui_status(int type, const char *fmt, ...)
199 {
200         va_list ap;
201         va_start(ap, fmt);
202         tui_vstatus(type, fmt, ap);
203         va_end(ap);
204 }
205
206 void tui_vstatus(int type, const char *fmt, va_list ap)
207 {
208         /* TODO */
209         tg_color(15);
210         tg_bgcolor(0);
211         tg_vtext(0, 25, fmt, ap);
212 }
213
214 void tui_msgbox(int type, const char *title, const char *msg, ...)
215 {
216         va_list ap;
217         va_start(ap, msg);
218         tui_vmsgbox(type, title, msg, ap);
219         va_end(ap);
220 }
221
222 void tui_vmsgbox(int type, const char *title, const char *msg, va_list ap)
223 {
224         /* TODO */
225         tg_color(15);
226         tg_bgcolor(0);
227         tg_vtext(0, 25, msg, ap);
228 }