ref: b9f2b8c6a28c2d4744119c7254767a0f1b51ed2e
dir: /libwidget/button.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <thread.h> #include <mouse.h> #include <keyboard.h> #include <String.h> #include <widget.h> #include "w-internal.h" static char *btnkind = "Button"; static Image *lightblue, *darkblue; int isbutton(Widget *w) { return strcmp(w->kind, btnkind) == 0; } Point btnredraw(Widget *w, Image *dst, Rectangle r) { Image *tmp; Button *btn; Point btsz, pos, sz; Rectangle conrect; if(!isbutton(w)) werror("btnredraw: not a button"); btn = (Button*)w; tmp = allocimage(dst->display, r, RGBA32, 0, DTransparent); sz = redrawwidget(btn->content, tmp, r); pos = btsz = subpt(r.max, r.min); pos = divpt(pos, 2); pos = subpt(pos, divpt(sz, 2)); conrect = Rpt(pos, subpt(r.max, pos)); draw(dst, r, btn->pressed ? btn->fg : btn->bg, nil, ZP); draw(dst, conrect, tmp, nil, ZP); freeimage(tmp); return btsz; } int btnmouse(Widget *w, Image *dst, Rectangle rect, Mouse m, Channel *chan) { Button *btn; int pressed; Widgetmsg *msg; if(!isbutton(w)) werror("btndraw: not a button"); btn = (Button*)w; if((pressed = m.buttons & 1) != btn->pressed) { if(pressed) { msg = newmsg(btn, M_BUTTON_PRESSED); send(chan, &msg); } btn->pressed = pressed; btnredraw(btn, dst, rect); return 1; } return 0; } void btnfree(Widget *w) { Button *btn; if(!isbutton(w)) werror("btnfree: not a button"); btn = (Button*)w; freewidget(btn->content); free(btn); } Button* newbutton(Widget *w) { Button *btn; if(lightblue == nil) lightblue = allocimagemix(display, DPalebluegreen, DWhite); if(darkblue == nil) darkblue = allocimagemix(display, DPurpleblue, DPalebluegreen); btn = emalloc(sizeof(*btn)); wdefaults(btn); btn->bg = lightblue; btn->fg = darkblue; btn->kind = btnkind; btn->redraw = btnredraw; btn->cleanup = btnfree; btn->content = w; btn->mouseevent = btnmouse; return btn; } Button* newtextbutton(Font *f, char *content) { return newbutton(newtextbox(0, 0, f, content)); }