glamtk

diff src/imtk.c @ 1:dfbd12d1f566

finished the checkbox control, did some reorg as well.
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 30 Dec 2010 15:10:25 +0200
parents b04d49e4599c
children 3d661dd17af3
line diff
     1.1 --- a/src/imtk.c	Thu Dec 30 05:22:14 2010 +0200
     1.2 +++ b/src/imtk.c	Thu Dec 30 15:10:25 2010 +0200
     1.3 @@ -1,4 +1,5 @@
     1.4  #include <stdio.h>
     1.5 +#include <string.h>
     1.6  #include <assert.h>
     1.7  #ifndef __APPLE__
     1.8  #include <GL/glut.h>
     1.9 @@ -7,6 +8,22 @@
    1.10  #endif
    1.11  #include "imtk.h"
    1.12  
    1.13 +#define CHECKBOX_SIZE	14
    1.14 +
    1.15 +enum {
    1.16 +	FRAME_OUTSET,
    1.17 +	FRAME_INSET
    1.18 +};
    1.19 +
    1.20 +/* default colors, can be changed with imtk_set_color */
    1.21 +static float colors[][4] = {
    1.22 +	{0.0, 0.0, 0.0},	/* text color */
    1.23 +	{0.7, 0.7, 0.7},	/* base color */
    1.24 +	{0.85, 0.85, 0.85},	/* focus color */
    1.25 +	{1.0, 1.0, 1.0},	/* lit bevel */
    1.26 +	{0.3, 0.3, 0.3}		/* shadowed bevel */
    1.27 +};
    1.28 +
    1.29  static int scr_width = 1, scr_height = 1;
    1.30  static int mousex, mousey, mouse_bnmask;
    1.31  static int active = -1, hot = -1;
    1.32 @@ -15,10 +32,21 @@
    1.33  static int set_hot(int id);
    1.34  static int hit_test(int x, int y, int w, int h);
    1.35  
    1.36 -static void draw_button(int id, int x, int y, const char *label, int focused);
    1.37 +static void draw_button(int id, const char *label, int x, int y);
    1.38  static void calc_button_size(const char *label, int *wret, int *hret);
    1.39 +static void draw_checkbox(int id, const char *label, int x, int y, int state);
    1.40  static void draw_string(int x, int y, const char *str);
    1.41  static int string_size(const char *str);
    1.42 +static void draw_frame(int x, int y, int w, int h, int style);
    1.43 +
    1.44 +void imtk_set_color(int col, float r, float g, float b)
    1.45 +{
    1.46 +	assert(col >= 0 && col < sizeof colors / sizeof *colors);
    1.47 +
    1.48 +	colors[col][0] = r;
    1.49 +	colors[col][1] = g;
    1.50 +	colors[col][2] = b;
    1.51 +}
    1.52  
    1.53  void imtk_inp_key(int key, int state)
    1.54  {
    1.55 @@ -74,13 +102,10 @@
    1.56  	calc_button_size(label, &w, &h);
    1.57  
    1.58  	if(hit_test(x, y, w, h)) {
    1.59 -		if(set_hot(id)) {
    1.60 -			glutPostRedisplay();
    1.61 -		}
    1.62 +		set_hot(id);
    1.63  		over = 1;
    1.64  	}
    1.65  
    1.66 -
    1.67  	if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
    1.68  		if(over) {
    1.69  			set_active(id);
    1.70 @@ -94,10 +119,39 @@
    1.71  		}
    1.72  	}
    1.73  
    1.74 -	draw_button(id, x, y, label, over);
    1.75 +	draw_button(id, label, x, y);
    1.76  	return res;
    1.77  }
    1.78  
    1.79 +int imtk_checkbox(int id, const char *label, int x, int y, int state)
    1.80 +{
    1.81 +	int sz = CHECKBOX_SIZE;
    1.82 +	int over = 0;
    1.83 +
    1.84 +	assert(id >= 0);
    1.85 +
    1.86 +	if(hit_test(x, y, sz, sz)) {
    1.87 +		set_hot(id);
    1.88 +		over = 1;
    1.89 +	}
    1.90 +
    1.91 +	if(mouse_bnmask & (1 << IMTK_LEFT_BUTTON)) {
    1.92 +		if(over) {
    1.93 +			set_active(id);
    1.94 +		}
    1.95 +	} else { /* mouse button up */
    1.96 +		if(active == id) {
    1.97 +			set_active(-1);
    1.98 +			if(hot == id && over) {
    1.99 +				state = !state;
   1.100 +			}
   1.101 +		}
   1.102 +	}
   1.103 +
   1.104 +	draw_checkbox(id, label, x, y, state);
   1.105 +	return state;
   1.106 +}
   1.107 +
   1.108  static void set_active(int id)
   1.109  {
   1.110  	active = id;
   1.111 @@ -118,17 +172,17 @@
   1.112  		mousey >= y && mousey < (y + h);
   1.113  }
   1.114  
   1.115 -static void draw_button(int id, int x, int y, const char *label, int focused)
   1.116 +static void draw_button(int id, const char *label, int x, int y)
   1.117  {
   1.118  	int width, height;
   1.119  
   1.120  	calc_button_size(label, &width, &height);
   1.121  
   1.122  	glBegin(GL_QUADS);
   1.123 -	if(focused) {
   1.124 -		glColor3f(0.85, 0.85, 0.85);
   1.125 +	if(hit_test(x, y, width, height)) {
   1.126 +		glColor3fv(colors[IMTK_FOCUS_COLOR]);
   1.127  	} else {
   1.128 -		glColor3f(0.7, 0.7, 0.7);
   1.129 +		glColor3fv(colors[IMTK_BASE_COLOR]);
   1.130  	}
   1.131  	glVertex2f(x, y);
   1.132  	glVertex2f(x + width, y);
   1.133 @@ -136,7 +190,9 @@
   1.134  	glVertex2f(x, y + height);
   1.135  	glEnd();
   1.136  
   1.137 -	glColor3f(0, 0, 0);
   1.138 +	draw_frame(x, y, width, height, active == id ? FRAME_INSET : FRAME_OUTSET);
   1.139 +
   1.140 +	glColor3fv(colors[IMTK_TEXT_COLOR]);
   1.141  	draw_string(x + 20, y + 15, label);
   1.142  }
   1.143  
   1.144 @@ -147,15 +203,82 @@
   1.145  	if(hret) *hret = 20;
   1.146  }
   1.147  
   1.148 +static void draw_checkbox(int id, const char *label, int x, int y, int state)
   1.149 +{
   1.150 +	static const int sz = CHECKBOX_SIZE;
   1.151 +
   1.152 +	if(hit_test(x, y, sz, sz)) {
   1.153 +		glColor3fv(colors[IMTK_FOCUS_COLOR]);
   1.154 +	} else {
   1.155 +		glColor3fv(colors[IMTK_BASE_COLOR]);
   1.156 +	}
   1.157 +
   1.158 +	glBegin(GL_QUADS);
   1.159 +	glVertex2f(x, y);
   1.160 +	glVertex2f(x + sz, y);
   1.161 +	glVertex2f(x + sz, y + sz);
   1.162 +	glVertex2f(x, y + sz);
   1.163 +	glEnd();
   1.164 +
   1.165 +	draw_frame(x, y, sz, sz, FRAME_INSET);
   1.166 +
   1.167 +	glColor3fv(colors[IMTK_TEXT_COLOR]);
   1.168 +	if(state) {
   1.169 +		glPushAttrib(GL_LINE_BIT);
   1.170 +		glLineWidth(2);
   1.171 +
   1.172 +		glBegin(GL_LINES);
   1.173 +		glVertex2f(x + 2, y + 2);
   1.174 +		glVertex2f(x + sz - 2, y + sz - 2);
   1.175 +		glVertex2f(x + sz - 2, y + 2);
   1.176 +		glVertex2f(x + 2, y + sz - 2);
   1.177 +		glEnd();
   1.178 +
   1.179 +		glPopAttrib();
   1.180 +	}
   1.181 +
   1.182 +	draw_string(x + sz + 5, y + sz - 2, label);
   1.183 +}
   1.184 +
   1.185  static void draw_string(int x, int y, const char *str)
   1.186  {
   1.187  	glRasterPos2i(x, y);
   1.188  	while(*str) {
   1.189 -		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, *str++);
   1.190 +		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, *str++);
   1.191  	}
   1.192  }
   1.193  
   1.194  static int string_size(const char *str)
   1.195  {
   1.196 -	return glutBitmapLength(GLUT_BITMAP_HELVETICA_10, str);
   1.197 +	return glutBitmapLength(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)str);
   1.198  }
   1.199 +
   1.200 +static void draw_frame(int x, int y, int w, int h, int style)
   1.201 +{
   1.202 +	float tcol[3], bcol[3];
   1.203 +
   1.204 +	switch(style) {
   1.205 +	case FRAME_INSET:
   1.206 +		memcpy(tcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof tcol);
   1.207 +		memcpy(bcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof bcol);
   1.208 +		break;
   1.209 +
   1.210 +	case FRAME_OUTSET:
   1.211 +	default:
   1.212 +		memcpy(tcol, colors[IMTK_BEVEL_LIT_COLOR], sizeof tcol);
   1.213 +		memcpy(bcol, colors[IMTK_BEVEL_SHAD_COLOR], sizeof bcol);
   1.214 +	}
   1.215 +
   1.216 +	glBegin(GL_LINES);
   1.217 +	glColor3fv(tcol);
   1.218 +	glVertex2f(x, y + h);
   1.219 +	glVertex2f(x, y);
   1.220 +	glVertex2f(x, y);
   1.221 +	glVertex2f(x + w, y);
   1.222 +	glColor3fv(bcol);
   1.223 +	glVertex2f(x + w, y);
   1.224 +	glVertex2f(x + w, y + h);
   1.225 +	glVertex2f(x + w, y + h);
   1.226 +	glVertex2f(x, y + h);
   1.227 +	glEnd();
   1.228 +}