start by copying windtk and dropping dirty rects and indexed colors
[anigui] / src / anigui.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include "agimpl.h"
4
5 void *(*ag_alloc)(size_t sz) = malloc;
6 void (*ag_free)(void *p) = free;
7
8 /* one day I may want to allow multiple contexts */
9 static struct ag_context defctx;
10 struct ag_context *ag_curctx_ = &defctx;
11
12 static unsigned int def_colors[] = {
13         0xf0f0f0,       /* font/foreground */
14         0x444444,       /* background */
15         0x555555,       /* highlight */
16         0x333333,       /* shadow */
17         0x403065,       /* inactive frame */
18         0x54349c,       /* inactive frame highlight */
19         0x221e2c,       /* inactive frame shadow */
20         0x8032aa,       /* active frame */
21         0xb14de8,       /* active frame highlight */
22         0x3b2846,       /* active frame shadow */
23         0
24 };
25
26 void *ag_zalloc(size_t sz)
27 {
28         void *p = ag_alloc(sz);
29         if(p) {
30                 memset(p, 0, sz);
31         }
32         return p;
33 }
34
35 void ag_allocator(void *(*allocfunc)(size_t), void (*freefunc)(void *p))
36 {
37         ag_alloc = allocfunc ? allocfunc : malloc;
38         ag_free = freefunc ? freefunc : free;
39 }
40
41
42 int ag_init(int w, int h, struct ag_graphics *gfx)
43 {
44         ag->root = 0;
45         if(!(ag->root = ag_alloc_widget(0))) {
46                 return -1;
47         }
48
49         ag_viewport(0, 0, w, h);
50         ag_graphics(gfx);
51         return 0;
52 }
53
54 void ag_destroy(void)
55 {
56         ag_free_tree(ag->root);
57         ag->root = 0;
58 }
59
60 struct ag_theme *ag_load_theme(const char *path)
61 {
62         return 0;       /* TODO */
63 }
64
65 void ag_unload_theme(struct ag_theme *theme)
66 {
67 }
68
69 static void use_theme(ag_widget *w, struct ag_theme *theme)
70 {
71         int i;
72
73         if(w->use_theme) {
74                 w->use_theme(w, theme);
75         }
76
77         for(i=0; i<w->num_child; i++) {
78                 use_theme(w->child[i], theme);
79         }
80 }
81
82 void ag_use_theme(struct ag_theme *theme)
83 {
84         ag->theme = theme;
85         use_theme(ag->root, theme);
86 }
87
88 void ag_viewport(int x, int y, int w, int h)
89 {
90         ag_rect(&ag->vp, x, y, w, h);
91         ag_move(ag->root, x, y);
92         ag_resize(ag->root, w, h);
93 }
94
95 void ag_graphics(struct ag_graphics *gfx)
96 {
97         ag->gfx = *gfx;
98         memcpy(ag->colors, def_colors, sizeof ag->colors);
99 }
100
101 void ag_inp_key(int key, int press)
102 {
103 }
104
105 void ag_inp_mouse(int bn, int st, int x, int y)
106 {
107 }
108
109 void ag_inp_motion(int x, int y)
110 {
111 }
112
113 void ag_draw_tree(ag_widget *tree)
114 {
115         int i;
116
117         if(tree->draw) {
118                 tree->draw(tree, &ag->gfx);
119         }
120
121         for(i=0; i<tree->num_child; i++) {
122                 ag_draw_tree(tree->child[i]);
123         }
124 }
125
126 void ag_draw(void)
127 {
128         ag_draw_tree(ag->root);
129 }
130
131 void ag_gfx_color(int cidx)
132 {
133         int r = (ag->colors[cidx] >> 16) & 0xff;
134         int g = (ag->colors[cidx] >> 8) & 0xff;
135         int b = ag->colors[cidx] & 0xff;
136         ag->gfx.color(r, g, b);
137 }
138
139 void ag_gfx_fillrect(struct ag_rect *r)
140 {
141         ag->gfx.fillrect(r);
142 }
143
144 void ag_gfx_fillrect4i(int x, int y, int w, int h)
145 {
146         struct ag_rect r;
147         ag_rect(&r, x, y, w, h);
148         ag->gfx.fillrect(&r);
149 }
150
151 void ag_gfx_frame(struct ag_rect *r, int style, int basecol)
152 {
153         if((style & FRM_NOFILL) == 0) {
154                 ag_gfx_color(basecol);
155                 ag_gfx_fillrect(r);
156         }
157         ag_gfx_color(FRMSTYLE(style) == FRM_OUT ? basecol + 2 : basecol + 1);
158         ag_gfx_fillrect4i(r->x + 1, r->y + r->h - 1, r->w - 2, 1);
159         ag_gfx_fillrect4i(r->x + r->w - 1, r->y, 1, r->h);
160         ag_gfx_color(FRMSTYLE(style) == FRM_OUT ? basecol + 1 : basecol + 2);
161         ag_gfx_fillrect4i(r->x + 1, r->y, r->w - 2, 1);
162         ag_gfx_fillrect4i(r->x, r->y, 1, r->h);
163 }
164
165 void ag_gfx_line(int x0, int y0, int x1, int y1)
166 {
167         ag->gfx.line(x0, y0, x1, y1);
168 }
169
170 void ag_rect(struct ag_rect *r, int x, int y, int w, int h)
171 {
172         r->x = x;
173         r->y = y;
174         r->w = w;
175         r->h = h;
176 }
177
178 void ag_rect_union(struct ag_rect *a, struct ag_rect *b)
179 {
180         int x1, y1;
181
182         x1 = a->x + a->w;
183         y1 = a->y + a->h;
184
185         if(b->x < a->x) a->x = b->x;
186         if(b->y < a->y) a->y = b->y;
187         if(b->x + b->w > x1) x1 = b->x + b->w;
188         if(b->y + b->h > y1) y1 = b->y + b->h;
189
190         a->w = x1 - a->x;
191         a->h = y1 - a->y;
192 }
193
194 int ag_rect_overlap(struct ag_rect *a, struct ag_rect *b)
195 {
196         if(a->x > b->x + b->w) return 0;
197         if(b->x > a->x + a->w) return 0;
198         if(a->y > b->y + b->h) return 0;
199         if(b->y > a->x + a->h) return 0;
200         return 1;
201 }