X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Frtk.c;h=b9d06d5e269de29dcf88d2eb8e6a5818964addc2;hb=86aa9bdd85243207bbd7e888d73c2b865d805265;hp=abd4244f710e0479babc43005d5ddf5ba6cf38f2;hpb=b0088adf036a53139f67ebf96f1bbb55abf199f4;p=retroray diff --git a/src/rtk.c b/src/rtk.c index abd4244..b9d06d5 100644 --- a/src/rtk.c +++ b/src/rtk.c @@ -11,6 +11,10 @@ static void draw_button(rtk_widget *w); static void draw_checkbox(rtk_widget *w); static void draw_separator(rtk_widget *w); + +static rtk_widget *hover, *focused, *pressed; + + void rtk_setup(rtk_draw_ops *drawop) { gfx = *drawop; @@ -190,6 +194,11 @@ int rtk_win_has(rtk_widget *par, rtk_widget *child) } /* --- button functions --- */ +void rtk_bn_mode(rtk_widget *w, int mode) +{ + RTK_ASSERT_TYPE(w, RTK_BUTTON); + w->bn.mode = mode; +} void rtk_bn_set_icon(rtk_widget *w, rtk_icon *icon) { @@ -361,6 +370,11 @@ static void calc_widget_rect(rtk_widget *w, rtk_rect *rect) } switch(w->type) { + case RTK_WIN: + rect->width = w->any.width; + rect->height = w->any.height; + break; + case RTK_BUTTON: if(w->bn.icon) { rect->width = w->bn.icon->width + OFFS * 2; @@ -384,9 +398,9 @@ static void calc_widget_rect(rtk_widget *w, rtk_rect *rect) case RTK_SEP: if(w->any.par->win.layout == RTK_VBOX) { rect->width = w->any.par->any.width - PAD * 2; - rect->height = (PAD + BEVELSZ) * 2; + rect->height = PAD * 4 + BEVELSZ * 2; } else if(w->any.par->win.layout == RTK_HBOX) { - rect->width = (PAD + BEVELSZ) * 2; + rect->width = PAD * 4 + BEVELSZ * 2; rect->height = w->any.par->any.height - PAD * 2; } else { rect->width = rect->height = 0; @@ -422,6 +436,7 @@ static void calc_layout(rtk_widget *w) { int x, y; rtk_widget *c; + rtk_rect rect; if(w->any.type == RTK_WIN && w->win.layout != RTK_NONE) { x = y = PAD; @@ -432,15 +447,19 @@ static void calc_layout(rtk_widget *w) calc_layout(c); if(w->win.layout == RTK_VBOX) { - y += c->any.height + PAD; + y += c->any.height + PAD * 2; } else { - x += c->any.width + PAD; + x += c->any.width + PAD * 2; } c = c->any.next; } } + calc_widget_rect(w, &rect); + w->any.width = rect.width; + w->any.height = rect.height; + w->any.flags = (w->any.flags & ~GEOMCHG) | DIRTY; } @@ -500,8 +519,9 @@ static void abs_pos(rtk_widget *w, int *xpos, int *ypos) } #define COL_BG 0xff666666 +#define COL_BGHL 0xff808080 #define COL_LBEV 0xffaaaaaa -#define COL_SBEV 0xff333333 +#define COL_SBEV 0xff222222 #define COL_TEXT 0xff000000 static void hline(int x, int y, int sz, uint32_t col) @@ -569,13 +589,20 @@ static void draw_window(rtk_widget *w) static void draw_button(rtk_widget *w) { + int pressed; rtk_rect rect; widget_rect(w, &rect); abs_pos(w, &rect.x, &rect.y); + if(w->bn.mode == RTK_TOGGLEBN) { + pressed = w->any.value; + } else { + pressed = w->any.flags & PRESS; + } + if(rect.width > 2 && rect.height > 2) { - draw_frame(&rect, FRM_OUTSET); + draw_frame(&rect, pressed ? FRM_INSET : FRM_OUTSET); rect.x++; rect.y++; @@ -583,9 +610,10 @@ static void draw_button(rtk_widget *w) rect.height -= 2; } - gfx.fill(&rect, COL_BG); + gfx.fill(&rect, w->any.flags & HOVER ? COL_BGHL : COL_BG); if(w->bn.icon) { - gfx.blit(rect.x + OFFS, rect.y + OFFS, w->bn.icon); + int offs = w->any.flags & PRESS ? PAD + 1 : PAD; + gfx.blit(rect.x + offs, rect.y + offs, w->bn.icon); } else { gfx.fill(&rect, 0xff802020); } @@ -600,8 +628,130 @@ static void draw_separator(rtk_widget *w) rtk_widget *win = w->any.par; rtk_rect rect; + if(!win) return; + widget_rect(w, &rect); abs_pos(w, &rect.x, &rect.y); + switch(win->win.layout) { + case RTK_VBOX: + rect.y += PAD * 2; + rect.height = 2; + break; + + case RTK_HBOX: + rect.x += PAD * 2; + rect.width = 2; + break; + + default: + break; + } + draw_frame(&rect, FRM_INSET); } + + +static int hittest(rtk_widget *w, int x, int y) +{ + if(x < w->any.x || y < w->any.y) return 0; + if(x >= w->any.x + w->any.width) return 0; + if(y >= w->any.y + w->any.height) return 0; + return 1; +} + +static void sethover(rtk_widget *w) +{ + if(hover == w) return; + + if(hover) { + hover->any.flags &= ~HOVER; + } + hover = w; + if(w) { + w->any.flags |= HOVER; + } +} + +static void setpress(rtk_widget *w) +{ + if(pressed == w) return; + + if(pressed) { + pressed->any.flags &= ~PRESS; + } + pressed = w; + if(w) { + w->any.flags |= PRESS; + } +} + +static void click(rtk_widget *w, int x, int y) +{ + switch(w->type) { + case RTK_BUTTON: + if(w->bn.mode == RTK_TOGGLEBN) { + case RTK_CHECKBOX: + w->any.value ^= 1; + } + if(w->any.cbfunc) { + w->any.cbfunc(w, w->any.cbcls); + } + break; + + default: + break; + } +} + +int rtk_input_key(rtk_widget *w, int key, int press) +{ + return 0; +} + +int rtk_input_mbutton(rtk_widget *w, int bn, int press, int x, int y) +{ + if(!hittest(w, x, y)) { + return 0; + } + + if(press) { + if(hover && hittest(hover, x, y)) { + setpress(hover); + } + } else { + if(pressed && hittest(pressed, x, y)) { + click(pressed, x, y); + } + setpress(0); + } + + return 1; +} + +int rtk_input_mmotion(rtk_widget *w, int x, int y) +{ + rtk_widget *c; + + if(!hittest(w, x, y)) { + int res = hover ? 1 : 0; + sethover(0); + return res; + } + + if(w->type == RTK_WIN) { + c = w->win.clist; + while(c) { + if(hittest(c, x, y)) { + return rtk_input_mmotion(c, x, y); + } + c = c->any.next; + } + } + + if(hover != w) { + sethover(w); + return 1; + } + return 0; +}