X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Frtk.c;h=4049f882cfd5e89b6e88ff93e078cecbcd5a9118;hb=3c3612761bcf77a5c4ec6810aa47e0e3f0131bf1;hp=c9de38fdcf96c1a69470c43d90fdb5e6c5a3097c;hpb=d6c18f77cb710c5e4069fd12fde0dbed76f3a131;p=retroray diff --git a/src/rtk.c b/src/rtk.c index c9de38f..4049f88 100644 --- a/src/rtk.c +++ b/src/rtk.c @@ -2,6 +2,7 @@ #include #include "imago2.h" #include "rtk_impl.h" +#include "app.h" static rtk_draw_ops gfx; @@ -11,6 +12,8 @@ static void draw_button(rtk_widget *w); static void draw_checkbox(rtk_widget *w); static void draw_separator(rtk_widget *w); +static void invalfb(rtk_widget *w); + static rtk_widget *hover, *focused, *pressed; @@ -56,7 +59,7 @@ void rtk_move(rtk_widget *w, int x, int y) { w->any.x = x; w->any.y = y; - w->any.flags |= GEOMCHG; + w->any.flags |= GEOMCHG | DIRTY; } void rtk_pos(rtk_widget *w, int *xptr, int *yptr) @@ -69,7 +72,7 @@ void rtk_resize(rtk_widget *w, int xsz, int ysz) { w->any.width = xsz; w->any.height = ysz; - w->any.flags |= GEOMCHG; + w->any.flags |= GEOMCHG | DIRTY; } void rtk_size(rtk_widget *w, int *xptr, int *yptr) @@ -78,6 +81,14 @@ void rtk_size(rtk_widget *w, int *xptr, int *yptr) *yptr = w->any.height; } +void rtk_get_rect(rtk_widget *w, rtk_rect *r) +{ + r->x = w->any.x; + r->y = w->any.y; + r->width = w->any.width; + r->height = w->any.height; +} + int rtk_set_text(rtk_widget *w, const char *str) { rtk_rect rect; @@ -89,6 +100,7 @@ int rtk_set_text(rtk_widget *w, const char *str) calc_widget_rect(w, &rect); rtk_resize(w, rect.width, rect.height); + rtk_invalidate(w); return 0; } @@ -100,6 +112,7 @@ const char *rtk_get_text(rtk_widget *w) void rtk_set_value(rtk_widget *w, int val) { w->any.value = val; + rtk_invalidate(w); } int rtk_get_value(rtk_widget *w) @@ -113,6 +126,33 @@ void rtk_set_callback(rtk_widget *w, rtk_callback cbfunc, void *cls) w->any.cbcls = cls; } +void rtk_show(rtk_widget *w) +{ + w->any.flags |= VISIBLE; + rtk_invalidate(w); +} + +void rtk_hide(rtk_widget *w) +{ + w->any.flags &= ~VISIBLE; + invalfb(w); +} + +int rtk_visible(const rtk_widget *w) +{ + return w->any.flags & VISIBLE; +} + +void rtk_invalidate(rtk_widget *w) +{ + w->any.flags |= DIRTY; +} + +void rtk_validate(rtk_widget *w) +{ + w->any.flags &= ~DIRTY; +} + void rtk_win_layout(rtk_widget *w, int layout) { w->win.layout = layout; @@ -131,6 +171,7 @@ void rtk_win_clear(rtk_widget *w) } w->win.clist = w->win.ctail = 0; + rtk_invalidate(w); } void rtk_win_add(rtk_widget *par, rtk_widget *child) @@ -154,6 +195,7 @@ void rtk_win_add(rtk_widget *par, rtk_widget *child) child->any.next = 0; child->any.par = par; + rtk_invalidate(par); } void rtk_win_rm(rtk_widget *par, rtk_widget *child) @@ -175,6 +217,7 @@ void rtk_win_rm(rtk_widget *par, rtk_widget *child) prev = prev->any.next; } par->win.clist = dummy.any.next; + rtk_invalidate(par); } int rtk_win_has(rtk_widget *par, rtk_widget *child) @@ -198,6 +241,7 @@ void rtk_bn_mode(rtk_widget *w, int mode) { RTK_ASSERT_TYPE(w, RTK_BUTTON); w->bn.mode = mode; + rtk_invalidate(w); } void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon) @@ -209,6 +253,7 @@ void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon) calc_widget_rect(w, &rect); rtk_resize(w, rect.width, rect.height); + rtk_invalidate(w); } rtk_icon *rtk_bn_get_icon(rtk_widget *w) @@ -219,7 +264,8 @@ rtk_icon *rtk_bn_get_icon(rtk_widget *w) /* --- constructors --- */ -rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, int width, int height) +rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, + int width, int height, unsigned int flags) { rtk_widget *w; @@ -231,6 +277,8 @@ rtk_widget *rtk_create_window(rtk_widget *par, const char *title, int x, int y, rtk_set_text(w, title); rtk_move(w, x, y); rtk_resize(w, width, height); + + w->any.flags |= flags << 16; return w; } @@ -460,15 +508,27 @@ static void calc_layout(rtk_widget *w) w->any.width = rect.width; w->any.height = rect.height; - w->any.flags = (w->any.flags & ~GEOMCHG) | DIRTY; + w->any.flags &= ~GEOMCHG; + rtk_invalidate(w); } void rtk_draw_widget(rtk_widget *w) { + int dirty; + + if(!(w->any.flags & VISIBLE)) { + return; + } + if(need_relayout(w)) { calc_layout(w); } + dirty = w->any.flags & DIRTY; + if(!dirty && w->any.type != RTK_WIN) { + return; + } + switch(w->any.type) { case RTK_WIN: draw_window(w); @@ -490,7 +550,10 @@ void rtk_draw_widget(rtk_widget *w) break; } - w->any.flags &= ~DIRTY; + if(dirty) { + rtk_validate(w); + invalfb(w); + } } static void widget_rect(rtk_widget *w, rtk_rect *rect) @@ -523,6 +586,9 @@ static void abs_pos(rtk_widget *w, int *xpos, int *ypos) #define COL_LBEV 0xffaaaaaa #define COL_SBEV 0xff222222 #define COL_TEXT 0xff000000 +#define COL_WINFRM 0xff2244aa +#define COL_WINFRM_LIT 0xff4466ff +#define COL_WINFRM_SHAD 0xff051166 static void hline(int x, int y, int sz, uint32_t col) { @@ -546,6 +612,16 @@ static void vline(int x, int y, int sz, uint32_t col) enum {FRM_SOLID, FRM_OUTSET, FRM_INSET}; +enum {UICOL_BG, UICOL_LBEV, UICOL_SBEV}; +static uint32_t uicol[3]; + +static void uicolor(uint32_t col, uint32_t lcol, uint32_t scol) +{ + uicol[UICOL_BG] = col; + uicol[UICOL_LBEV] = lcol; + uicol[UICOL_SBEV] = scol; +} + static void draw_frame(rtk_rect *rect, int type) { int tlcol, brcol; @@ -555,12 +631,12 @@ static void draw_frame(rtk_rect *rect, int type) tlcol = brcol = 0xff000000; break; case FRM_OUTSET: - tlcol = COL_LBEV; - brcol = COL_SBEV; + tlcol = uicol[UICOL_LBEV]; + brcol = uicol[UICOL_SBEV]; break; case FRM_INSET: - tlcol = COL_SBEV; - brcol = COL_LBEV; + tlcol = uicol[UICOL_SBEV]; + brcol = uicol[UICOL_LBEV]; break; default: break; @@ -572,16 +648,55 @@ static void draw_frame(rtk_rect *rect, int type) vline(rect->x + rect->width - 1, rect->y + 1, rect->height - 2, brcol); } +#define WINFRM_SZ 2 +#define WINFRM_TBAR 16 + static void draw_window(rtk_widget *w) { - rtk_rect rect; + rtk_rect rect, frmrect, tbrect; rtk_widget *c; + int win_dirty = w->any.flags & DIRTY; + + if(win_dirty) { + widget_rect(w, &rect); + + if(w->any.flags & FRAME) { + uicolor(COL_WINFRM, COL_WINFRM_LIT, COL_WINFRM_SHAD); + + frmrect = rect; + frmrect.width += WINFRM_SZ * 2; + frmrect.height += WINFRM_SZ * 2 + WINFRM_TBAR; + frmrect.x -= WINFRM_SZ; + frmrect.y -= WINFRM_SZ + WINFRM_TBAR; + + tbrect.x = rect.x; + tbrect.y = rect.y - WINFRM_TBAR; + tbrect.width = rect.width; + tbrect.height = WINFRM_TBAR; + + draw_frame(&frmrect, FRM_OUTSET); + frmrect.x++; + frmrect.y++; + frmrect.width -= 2; + frmrect.height -= 2; + draw_frame(&frmrect, FRM_INSET); + + draw_frame(&tbrect, FRM_OUTSET); + tbrect.x++; + tbrect.y++; + tbrect.width -= 2; + tbrect.height -= 2; + gfx.fill(&tbrect, COL_WINFRM); + } - widget_rect(w, &rect); - gfx.fill(&rect, COL_BG); + gfx.fill(&rect, COL_BG); + } c = w->win.clist; while(c) { + if(win_dirty) { + rtk_invalidate(c); + } rtk_draw_widget(c); c = c->any.next; } @@ -601,6 +716,8 @@ static void draw_button(rtk_widget *w) pressed = w->any.flags & PRESS; } + uicolor(COL_BG, COL_LBEV, COL_SBEV); + if(rect.width > 2 && rect.height > 2) { draw_frame(&rect, pressed ? FRM_INSET : FRM_OUTSET); @@ -630,6 +747,8 @@ static void draw_separator(rtk_widget *w) if(!win) return; + uicolor(COL_BG, COL_LBEV, COL_SBEV); + widget_rect(w, &rect); abs_pos(w, &rect.x, &rect.y); @@ -666,10 +785,20 @@ static void sethover(rtk_widget *w) if(hover) { hover->any.flags &= ~HOVER; + + if(hover->type != RTK_WIN) { + rtk_invalidate(hover); + invalfb(hover); + } } hover = w; if(w) { w->any.flags |= HOVER; + + if(w->type != RTK_WIN) { + rtk_invalidate(w); + invalfb(w); + } } } @@ -679,10 +808,14 @@ static void setpress(rtk_widget *w) if(pressed) { pressed->any.flags &= ~PRESS; + rtk_invalidate(pressed); + invalfb(pressed); } pressed = w; if(w) { w->any.flags |= PRESS; + rtk_invalidate(w); + invalfb(w); } } @@ -697,6 +830,8 @@ static void click(rtk_widget *w, int x, int y) if(w->any.cbfunc) { w->any.cbfunc(w, w->any.cbcls); } + rtk_invalidate(w); + invalfb(w); break; default: @@ -739,8 +874,6 @@ int rtk_input_mmotion(rtk_widget *w, int x, int y) return res; } - sethover(w); - if(w->type == RTK_WIN) { c = w->win.clist; while(c) { @@ -751,5 +884,60 @@ int rtk_input_mmotion(rtk_widget *w, int x, int y) } } - return 1; + if(hover != w) { + sethover(w); + return 1; + } + return 0; +} + +void rtk_fix_rect(rtk_rect *rect) +{ + int x, y, w, h; + + x = rect->x; + y = rect->y; + + if(rect->width < 0) { + w = -rect->width; + x += rect->width; + } else { + w = rect->width; + } + if(rect->height < 0) { + h = -rect->height; + y += rect->height; + } else { + h = rect->height; + } + + rect->x = x; + rect->y = y; + rect->width = w; + rect->height = h; +} + +void rtk_rect_union(rtk_rect *a, const rtk_rect *b) +{ + int x0, y0, x1, y1; + + x0 = a->x; + y0 = a->y; + x1 = a->x + a->width; + y1 = a->y + a->height; + + if(b->x < x0) x0 = b->x; + if(b->y < y0) y0 = b->y; + if(b->x + b->width > x1) x1 = b->x + b->width; + if(b->y + b->height > y1) y1 = b->y + b->height; + + a->x = x0; + a->y = y0; + a->width = x1 - x0; + a->height = y1 - y0; +} + +static void invalfb(rtk_widget *w) +{ + app_redisplay(w->any.x, w->any.y, w->any.width, w->any.height); }