static unsigned int def_colors[] = {
0xf0f0f0, /* font/foreground */
- 0x333333, /* background */
- 0x444444, /* highlight */
- 0x222222, /* shadow */
+ 0x444444, /* background */
+ 0x555555, /* highlight */
+ 0x333333, /* shadow */
0x403065, /* inactive frame */
0x54349c, /* inactive frame highlight */
0x221e2c, /* inactive frame shadow */
int wt_init(int w, int h, struct wt_graphics *gfx)
{
+ wt->root = 0;
if(!(wt->root = wt_alloc_widget(0))) {
return -1;
}
wt->root = 0;
}
+struct wt_theme *wt_load_theme(const char *path)
+{
+ return 0; /* TODO */
+}
+
+void wt_unload_theme(struct wt_theme *theme)
+{
+}
+
+static void use_theme(wt_widget *w, struct wt_theme *theme)
+{
+ int i;
+
+ if(w->use_theme) {
+ w->use_theme(w, theme);
+ }
+
+ for(i=0; i<w->num_child; i++) {
+ use_theme(w->child[i], theme);
+ }
+}
+
+void wt_use_theme(struct wt_theme *theme)
+{
+ wt->theme = theme;
+ use_theme(wt->root, theme);
+}
+
void wt_viewport(int x, int y, int w, int h)
{
- wt_setrect(&wt->vp, x, y, w, h);
+ wt_rect(&wt->vp, x, y, w, h);
wt_move(wt->root, x, y);
wt_resize(wt->root, w, h);
}
{
}
+void wt_draw_tree(wt_widget *tree)
+{
+ int i;
+
+ if(tree->draw) {
+ if(wt->gfx.flags & WT_GFX_NODIRTY) {
+ tree->draw(tree, &wt->gfx);
+ } else {
+ if(tree->dirty) {
+ tree->draw(tree, &wt->gfx);
+
+ if(!tree->parent || !tree->parent->dirty) {
+ /* topmost dirty widget should update rects */
+ if(tree->type == WT_TYPE_WINDOW) {
+ struct wt_rect r;
+ calc_window_rect(&r, tree);
+ wt_add_upd_rect(&r);
+ } else {
+ wt_add_upd_rect(&tree->rect);
+ }
+ }
+ }
+ }
+ }
+
+ for(i=0; i<tree->num_child; i++) {
+ wt_draw_tree(tree->child[i]);
+ }
+
+ tree->dirty = 0;
+}
+
+void wt_draw(void)
+{
+ wt->num_upd = 0;
+ wt_draw_tree(wt->root);
+}
+
+int wt_num_upd(void)
+{
+ return wt->num_upd;
+}
+
+struct wt_rect *wt_upd_rect(int idx)
+{
+ if(idx < 0 || idx >= wt->num_upd) {
+ return 0;
+ }
+ return wt->upd + idx;
+}
+
+void wt_add_upd_rect(struct wt_rect *r)
+{
+ int i;
+ struct wt_rect rect;
+
+ for(i=0; i<wt->num_upd; i++) {
+ if(wt_rect_overlap(wt->upd + i, r)) {
+ rect = wt->upd[i];
+ wt->upd[i] = wt->upd[--wt->num_upd];
+ wt_rect_union(&rect, r);
+ wt_add_upd_rect(&rect);
+ return;
+ }
+ }
+
+ /* no overlaps found, add it if there is space, or union with existing if not */
+ if(wt->num_upd >= MAX_UPD_RECTS) {
+ wt_rect_union(wt->upd, r);
+ } else {
+ wt->upd[wt->num_upd++] = *r;
+ }
+}
+
+
void wt_gfx_color(int cidx)
{
wt->gfx.color(wt->colors[cidx]);
wt->gfx.fillrect(r);
}
+void wt_gfx_fillrect4i(int x, int y, int w, int h)
+{
+ struct wt_rect r;
+ wt_rect(&r, x, y, w, h);
+ wt->gfx.fillrect(&r);
+}
+
void wt_gfx_frame(struct wt_rect *r, int style, int basecol)
{
- wt_gfx_color(basecol);
- wt_gfx_fillrect(r);
- wt_gfx_color(style == FRM_OUT ? basecol + 2 : basecol + 1);
- wt_gfx_line(r->x, r->y + r->height, r->x + r->width - 1, r->y + r->height);
- wt_gfx_line(r->x + r->width, r->y + 1, r->x + r->width, r->y + r->height);
- wt_gfx_color(style == FRM_OUT ? basecol + 1 : basecol + 2);
- wt_gfx_line(r->x, r->y, r->x + r->width, r->y);
- wt_gfx_line(r->x, r->y + 1, r->x, r->y + r->height - 1);
+ if((style & FRM_NOFILL) == 0) {
+ wt_gfx_color(basecol);
+ wt_gfx_fillrect(r);
+ }
+ wt_gfx_color(FRMSTYLE(style) == FRM_OUT ? basecol + 2 : basecol + 1);
+ wt_gfx_fillrect4i(r->x + 1, r->y + r->h - 1, r->w - 2, 1);
+ wt_gfx_fillrect4i(r->x + r->w - 1, r->y, 1, r->h);
+ wt_gfx_color(FRMSTYLE(style) == FRM_OUT ? basecol + 1 : basecol + 2);
+ wt_gfx_fillrect4i(r->x + 1, r->y, r->w - 2, 1);
+ wt_gfx_fillrect4i(r->x, r->y, 1, r->h);
}
void wt_gfx_line(int x0, int y0, int x1, int y1)
wt->gfx.line(x0, y0, x1, y1);
}
-void wt_setrect(struct wt_rect *r, int x, int y, int w, int h)
+void wt_rect(struct wt_rect *r, int x, int y, int w, int h)
{
r->x = x;
r->y = y;
- r->width = w;
- r->height = h;
+ r->w = w;
+ r->h = h;
+}
+
+void wt_rect_union(struct wt_rect *a, struct wt_rect *b)
+{
+ int x1, y1;
+
+ x1 = a->x + a->w;
+ y1 = a->y + a->h;
+
+ if(b->x < a->x) a->x = b->x;
+ if(b->y < a->y) a->y = b->y;
+ if(b->x + b->w > x1) x1 = b->x + b->w;
+ if(b->y + b->h > y1) y1 = b->y + b->h;
+
+ a->w = x1 - a->x;
+ a->h = y1 - a->y;
+}
+
+int wt_rect_overlap(struct wt_rect *a, struct wt_rect *b)
+{
+ if(a->x > b->x + b->w) return 0;
+ if(b->x > a->x + a->w) return 0;
+ if(a->y > b->y + b->h) return 0;
+ if(b->y > a->x + a->h) return 0;
+ return 1;
}