5 ag_widget *ag_alloc_widget(ag_widget *par)
8 if(!(w = ag_zalloc(sizeof *w))) {
11 w->type = AG_TYPE_WIDGET;
14 if(!par) par = ag->root;
19 void ag_free_widget(ag_widget *w)
28 void ag_free_tree(ag_widget *tree)
34 for(i=0; i<tree->num_child; i++) {
35 ag_free_tree(tree->child[i]);
40 void ag_dirty_widget(ag_widget *w)
46 for(i=0; i<w->num_child; i++) {
47 ag_dirty_widget(w->child[i]);
51 int ag_type(ag_widget *w)
56 int ag_set_text(ag_widget *w, const char *text)
60 if(!(s = ag_alloc(strlen(text) + 1))) {
69 const char *ag_text(ag_widget *w)
74 static int find_child(ag_widget *w, ag_widget *c)
77 for(i=0; i<w->num_child; i++) {
78 if(w->child[i] == c) {
85 int ag_add_child(ag_widget *w, ag_widget *c)
87 if(!w || !c) return -1;
89 if(find_child(w, c) != -1) {
93 ag_remove_child(c->parent, c);
96 if(w->num_child >= w->max_child) {
98 int newsz = w->max_child ? w->max_child << 1 : 8;
99 if(!(newarr = ag_alloc(newsz * sizeof *w->child))) {
102 memcpy(newarr, w->child, w->num_child * sizeof *w->child);
105 w->max_child = newsz;
108 w->child[w->num_child++] = c;
112 int ag_remove_child(ag_widget *w, ag_widget *c)
116 if(!w->num_child || (idx = find_child(w, c)) == -1) {
119 w->child[idx] = w->child[--w->num_child];
121 if(w->max_child > 8 && w->num_child < w->max_child / 3) {
123 int newsz = w->max_child >> 1;
124 if(!(newarr = ag_alloc(newsz * sizeof *w->child))) {
127 memcpy(newarr, w->child, w->num_child * sizeof *w->child);
130 w->max_child = newsz;
135 ag_widget *ag_parent(ag_widget *w)
140 ag_widget *ag_widget_window(ag_widget *w)
143 while(par && par->type != AG_TYPE_WINDOW) {
149 int ag_child_count(ag_widget *w)
154 ag_widget *ag_child(ag_widget *w, int idx)
156 if(idx < 0 || idx >= w->num_child) {
159 return w->child[idx];
162 void ag_move(ag_widget *w, int x, int y)
166 /* TODO: invalidate something */
169 void ag_resize(ag_widget *w, int x, int y)
173 /* TODO: invalidate something */
176 int *ag_position(ag_widget *w, int *xret, int *yret)
178 if(xret) *xret = w->rect.x;
179 if(yret) *yret = w->rect.y;
183 int *ag_size(ag_widget *w, int *xret, int *yret)
185 if(xret) *xret = w->rect.w;
186 if(yret) *yret = w->rect.h;
190 int ag_hittest(ag_widget *w, int x, int y)
192 return x >= w->rect.x && y >= w->rect.y && x < w->rect.x + w->rect.w &&
193 y < w->rect.y + w->rect.h;
196 ag_widget *ag_widget_at(int x, int y)
201 if(!ag_hittest(ag->root, x, y)) {
210 for(i=0; i<w->num_child; i++) {
211 if(ag_hittest(w->child[i], x, y)) {
222 void ag_layout(ag_widget *w, int layout);
223 void ag_padding(ag_widget *w, int pad);
224 void ag_relayout(ag_widget *w);
226 void ag_focus(ag_widget *w);
227 void ag_unfocus(ag_widget *w);
228 int ag_isfocused(ag_widget *w);
230 void ag_hover(ag_widget *w);
231 void ag_unhover(ag_widget *w);
232 int ag_ishover(ag_widget *w);
234 void ag_enable(ag_widget *w);
235 void ag_disable(ag_widget *w);
236 int ag_isenabled(ag_widget *w);
239 void ag_callback(ag_widget *w, int type, ag_callback_func func, void *cls)
242 w->cbcls[type] = cls;