imtk

annotate 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
rev   line source
nuclear@17 1 #include <string.h>
nuclear@17 2 #include <stdarg.h>
nuclear@17 3 #include <assert.h>
nuclear@17 4 #include "imtk.h"
nuclear@17 5 #include "state.h"
nuclear@17 6 #include "draw.h"
nuclear@17 7
nuclear@17 8 #define ITEM_HEIGHT 18
nuclear@17 9 #define PAD 3
nuclear@17 10
nuclear@17 11 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over);
nuclear@17 12
nuclear@17 13 int imtk_listbox(int id, const char *list, int sel, int x, int y)
nuclear@17 14 {
nuclear@17 15 int i, max_width, nitems, over;
nuclear@17 16 const char *ptr;
nuclear@17 17
nuclear@17 18 assert(id >= 0);
nuclear@17 19
nuclear@17 20 max_width = 0;
nuclear@17 21 over = 0;
nuclear@17 22
nuclear@17 23 ptr = list;
nuclear@17 24 for(i=0; *ptr; i++) {
nuclear@17 25 int strsz = imtk_string_size(ptr) + 2 * PAD;
nuclear@17 26 if(strsz > max_width) {
nuclear@17 27 max_width = strsz;
nuclear@17 28 }
nuclear@17 29 ptr += strlen(ptr) + 1;
nuclear@17 30
nuclear@17 31 if(imtk_hit_test(x, y + i * ITEM_HEIGHT, max_width, ITEM_HEIGHT)) {
nuclear@17 32 imtk_set_hot(id);
nuclear@17 33 over = i + 1;
nuclear@17 34 }
nuclear@17 35 }
nuclear@17 36 nitems = i;
nuclear@17 37
nuclear@17 38 if(imtk_button_state(IMTK_LEFT_BUTTON)) {
nuclear@17 39 if(over) {
nuclear@17 40 imtk_set_active(id);
nuclear@17 41 }
nuclear@17 42 } else {
nuclear@17 43 if(imtk_is_active(id)) {
nuclear@17 44 imtk_set_active(-1);
nuclear@17 45 if(imtk_is_hot(id) && over) {
nuclear@17 46 sel = over - 1;
nuclear@17 47 }
nuclear@17 48 }
nuclear@17 49 }
nuclear@17 50
nuclear@17 51 draw_listbox(id, list, sel, x, y, max_width, nitems, over);
nuclear@17 52 return sel;
nuclear@17 53 }
nuclear@17 54
nuclear@17 55 char *imtk_create_list(const char *first, ...)
nuclear@17 56 {
nuclear@17 57 int sz;
nuclear@17 58 char *buf, *item;
nuclear@17 59 va_list ap;
nuclear@17 60
nuclear@17 61 if(!first) {
nuclear@17 62 return 0;
nuclear@17 63 }
nuclear@17 64
nuclear@17 65 sz = strlen(first) + 2;
nuclear@17 66 if(!(buf = malloc(sz))) {
nuclear@17 67 return 0;
nuclear@17 68 }
nuclear@17 69 memcpy(buf, first, sz - 2);
nuclear@17 70 buf[sz - 1] = buf[sz - 2] = 0;
nuclear@17 71
nuclear@17 72 va_start(ap, first);
nuclear@17 73 while((item = va_arg(ap, char*))) {
nuclear@17 74 int len = strlen(item);
nuclear@17 75 char *tmp = realloc(buf, sz + len + 1);
nuclear@17 76 if(!tmp) {
nuclear@17 77 free(buf);
nuclear@17 78 return 0;
nuclear@17 79 }
nuclear@17 80 buf = tmp;
nuclear@17 81
nuclear@17 82 memcpy(buf + sz - 1, item, len);
nuclear@17 83 sz += len + 1;
nuclear@17 84 buf[sz - 1] = buf[sz - 2] = 0;
nuclear@17 85 }
nuclear@17 86 va_end(ap);
nuclear@17 87
nuclear@17 88 return buf;
nuclear@17 89 }
nuclear@17 90
nuclear@17 91 void imtk_free_list(char *list)
nuclear@17 92 {
nuclear@17 93 free(list);
nuclear@17 94 }
nuclear@17 95
nuclear@17 96 static void draw_listbox(int id, const char *list, int sel, int x, int y, int width, int nitems, int over)
nuclear@17 97 {
nuclear@17 98 int i;
nuclear@17 99 const char *item = list;
nuclear@17 100
nuclear@17 101 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
nuclear@17 102
nuclear@17 103 for(i=0; i<nitems; i++) {
nuclear@17 104 int item_y = i * ITEM_HEIGHT + y;
nuclear@17 105 unsigned int attr = 0;
nuclear@17 106 float tcol[4], bcol[4];
nuclear@17 107
nuclear@17 108 if(over - 1 == i) {
nuclear@17 109 attr |= IMTK_FOCUS_BIT;
nuclear@17 110 }
nuclear@17 111
nuclear@17 112 if(sel == i) {
nuclear@17 113 attr |= IMTK_SEL_BIT;
nuclear@17 114 memcpy(tcol, imtk_get_color(IMTK_TOP_COLOR | attr), sizeof tcol);
nuclear@17 115 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
nuclear@17 116 } else {
nuclear@17 117 memcpy(tcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof tcol);
nuclear@17 118 memcpy(bcol, imtk_get_color(IMTK_BOTTOM_COLOR | attr), sizeof bcol);
nuclear@17 119 }
nuclear@17 120
nuclear@17 121 imtk_draw_rect(x, item_y, width, ITEM_HEIGHT, tcol, bcol);
nuclear@17 122
nuclear@17 123 glColor4fv(imtk_get_color(IMTK_TEXT_COLOR));
nuclear@17 124 imtk_draw_string(x + 3, item_y + ITEM_HEIGHT - 5, item);
nuclear@17 125 item += strlen(item) + 1;
nuclear@17 126 }
nuclear@17 127
nuclear@17 128 imtk_draw_frame(x, y, width, ITEM_HEIGHT * nitems, FRAME_INSET);
nuclear@17 129 }