imtk

diff src/listbox.c @ 17:ac2a8d8fca9a

naturally I forgot to add listbox.c
author John Tsiombikas <nuclear@siggraph.org>
date Tue, 19 Apr 2011 08:36:23 +0300
parents
children 737e9047d9c9
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/listbox.c	Tue Apr 19 08:36:23 2011 +0300
     1.3 @@ -0,0 +1,129 @@
     1.4 +#include <string.h>
     1.5 +#include <stdarg.h>
     1.6 +#include <assert.h>
     1.7 +#include "imtk.h"
     1.8 +#include "state.h"
     1.9 +#include "draw.h"
    1.10 +
    1.11 +#define ITEM_HEIGHT		18
    1.12 +#define PAD				3
    1.13 +
    1.14 +static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
    1.15 +
    1.16 +int imtk_listbox(int id, const char *list, int sel, int x, int y)
    1.17 +{
    1.18 +	int i, max_width, nitems, over;
    1.19 +	const char *ptr;
    1.20 +
    1.21 +	assert(id >= 0);
    1.22 +
    1.23 +	max_width = 0;
    1.24 +	over = 0;
    1.25 +
    1.26 +	ptr = list;
    1.27 +	for(i=0; *ptr; i++) {
    1.28 +		int strsz = imtk_string_size(ptr) + 2 * PAD;
    1.29 +		if(strsz > max_width) {
    1.30 +			max_width = strsz;
    1.31 +		}
    1.32 +		ptr += strlen(ptr) + 1;
    1.33 +
    1.34 +		if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
    1.35 +			imtk_set_hot(id);
    1.36 +			over = i + 1;
    1.37 +		}
    1.38 +	}
    1.39 +	nitems = i;
    1.40 +
    1.41 +	if(imtk_button_state(IMTK_LEFT_BUTTON)) {
    1.42 +		if(over) {
    1.43 +			imtk_set_active(id);
    1.44 +		}
    1.45 +	} else {
    1.46 +		if(imtk_is_active(id)) {
    1.47 +			imtk_set_active(-1);
    1.48 +			if(imtk_is_hot(id) && over) {
    1.49 +				sel = over - 1;
    1.50 +			}
    1.51 +		}
    1.52 +	}
    1.53 +
    1.54 +	draw_listbox(id, list, sel, x, y, max_width, nitems, over);
    1.55 +	return sel;
    1.56 +}
    1.57 +
    1.58 +char *imtk_create_list(const char *first, ...)
    1.59 +{
    1.60 +	int sz;
    1.61 +	char *buf, *item;
    1.62 +	va_list ap;
    1.63 +
    1.64 +	if(!first) {
    1.65 +		return 0;
    1.66 +	}
    1.67 +
    1.68 +	sz = strlen(first) + 2;
    1.69 +	if(!(buf = malloc(sz))) {
    1.70 +		return 0;
    1.71 +	}
    1.72 +	memcpy(buf, first, sz - 2);
    1.73 +	buf[sz - 1] = buf[sz - 2] = 0;
    1.74 +
    1.75 +	va_start(ap, first);
    1.76 +	while((item = va_arg(ap, char*))) {
    1.77 +		int len = strlen(item);
    1.78 +		char *tmp = realloc(buf, sz + len + 1);
    1.79 +		if(!tmp) {
    1.80 +			free(buf);
    1.81 +			return 0;
    1.82 +		}
    1.83 +		buf = tmp;
    1.84 +
    1.85 +		memcpy(buf + sz - 1, item, len);
    1.86 +		sz += len + 1;
    1.87 +		buf[sz - 1] = buf[sz - 2] = 0;
    1.88 +	}
    1.89 +	va_end(ap);
    1.90 +
    1.91 +	return buf;
    1.92 +}
    1.93 +
    1.94 +void imtk_free_list(char *list)
    1.95 +{
    1.96 +	free(list);
    1.97 +}
    1.98 +
    1.99 +static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
   1.100 +{
   1.101 +	int i;
   1.102 +	const char *item = list;
   1.103 +
   1.104 +	glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
   1.105 +
   1.106 +	for(i=0; i<nitems; i++) {
   1.107 +		int item_y = i * ITEM_HEIGHT + y;
   1.108 +		unsigned int attr = 0;
   1.109 +		float tcol[4], bcol[4];
   1.110 +
   1.111 +		if(over - 1 == i) {
   1.112 +			attr |= IMTK_FOCUS_BIT;
   1.113 +		}
   1.114 +
   1.115 +		if(sel == i) {
   1.116 +			attr |= IMTK_SEL_BIT;
   1.117 +			memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
   1.118 +			memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
   1.119 +		} else {
   1.120 +			memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
   1.121 +			memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
   1.122 +		}
   1.123 +
   1.124 +		imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
   1.125 +
   1.126 +		glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
   1.127 +		imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
   1.128 +		item += strlen(item) + 1;
   1.129 +	}
   1.130 +
   1.131 +	imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
   1.132 +}