shithub: widget

ref: b9f2b8c6a28c2d4744119c7254767a0f1b51ed2e
dir: /libwidget/button.c/

View raw version
#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));
}