shithub: blie

ref: 72ea71f4d629f81f7c5eb34d31cf4b873162d06b
dir: /ask.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <event.h>
#include <keyboard.h>
#include "blie.h"

static int asklineheight = 50;
static int numberasks = 0;
static int width = 200;

static void
dodraw(Image *img, Rectangle r, Ask *asks)
{
	int i;
	Point p;
	Rectangle box;
	
	replclipr(img, 0, r);
	draw(img, r, display->white, nil, ZP);
	border(img, r, 1, display->black, ZP);
	
	box.min = ZP;
	box.max.x = width - 2*5;
	box.max.y = font->height + 4;
	
	p = r.min;
	p.x += 5; /* margin left */
	
	for (i = 0; i < numberasks; i++) {
		p.y = r.min.y + i * asklineheight;
		p.y += 8;
		string(img, p, display->black, ZP, font, asks[i].label);
		p.y += font->height + 2;
		border(img, rectaddpt(box, p), 1, display->black, ZP);
		p.y += 2;
		p.x += 3;
		string(img, p, display->black, ZP, font, asks[i].value);
		p.x -= 3;
	}
	
	replclipr(img, 0, img->r);
}

static int
handleclick(Ask *asks, Rectangle r, Mouse m)
{
	int i;
	int y;
	Mouse fm;
	
	y = m.xy.y - r.min.y;
	i = y / asklineheight;
	
	if (i >= numberasks)
		return 0;
	
	fm.xy = r.min;
	fm.xy.y += i * asklineheight;
	
	return eenter(asks[i].label, asks[i].value, asks[i].nval, &m);
}

static int
handlekeys(int kbdc)
{
	/* return values: 1: quit abort, 2: quit success, 0: NOP */
	switch (kbdc) {
	case 'q':
	case Kdel:
	case Kesc:
		return 1;
	case '\n':
		return 2;
	}
	return 0;
}

int
ask(Ask *asks, Mouse m)
{
	Image *img, *blit;
	Rectangle r;
	int height;
	int e;
	Event ev;
	Point nbl;
	Ask *a;
	int ret;
	
	asklineheight = 2*font->height + 15;
	
	numberasks = 0;
	for (a = asks; a->label; a++)
		numberasks++;
	
	height = numberasks * asklineheight + 5;
	r.min = m.xy;
	r.max = r.min;
	r.max.x += width;
	r.max.y += height;
	
	if (screen->r.max.x <= r.max.x) {
		r.max.x = screen->r.max.x;
		r.min.x = r.max.x - width;
	}
	if (screen->r.max.y <= r.max.y) {
		r.max.y = screen->r.max.y;
		r.min.y = r.max.y - height;
	}
	
	nbl = r.min;
	
	blit = allocimage(display, r, screen->chan, 0, DNofill);
	draw(blit, blit->r, screen, nil, nbl);
	
	for (;;) {
		dodraw(screen, r, asks);
Nodraw:
		switch (event(&ev)) {
		case Ekeyboard:
			if (ret = handlekeys(ev.kbdc))
				goto Out;
			goto Nodraw;
		case Emouse:
			if (ev.mouse.buttons) {
				if (handleclick(asks, r, ev.mouse))
					break;
			}
			goto Nodraw;
		}
	}
Out:
	draw(screen, blit->r, blit, nil, nbl);
	freeimage(blit);
	
	return --ret;
}