imtk

changeset 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
files src/imtk.c src/imtk.h test.c
diffstat 3 files changed, 171 insertions(+), 17 deletions(-) [+]
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 +}
     2.1 --- a/src/imtk.h	Thu Dec 30 05:22:14 2010 +0200
     2.2 +++ b/src/imtk.h	Thu Dec 30 15:10:25 2010 +0200
     2.3 @@ -1,6 +1,16 @@
     2.4  #ifndef IMTK_H_
     2.5  #define IMTK_H_
     2.6  
     2.7 +#define IMUID	(65536 + __LINE__)
     2.8 +
     2.9 +enum {
    2.10 +	IMTK_TEXT_COLOR,
    2.11 +	IMTK_BASE_COLOR,
    2.12 +	IMTK_FOCUS_COLOR,
    2.13 +	IMTK_BEVEL_LIT_COLOR,
    2.14 +	IMTK_BEVEL_SHAD_COLOR
    2.15 +};
    2.16 +
    2.17  /* key/button state enum */
    2.18  enum {
    2.19  	IMTK_UP,
    2.20 @@ -13,6 +23,8 @@
    2.21  	IMTK_RIGHT_BUTTON
    2.22  };
    2.23  
    2.24 +void imtk_set_color(int col, float r, float g, float b);
    2.25 +
    2.26  void imtk_inp_key(int key, int state);
    2.27  void imtk_inp_mouse(int bn, int state);
    2.28  void imtk_inp_motion(int x, int y);
    2.29 @@ -22,5 +34,6 @@
    2.30  void imtk_end(void);
    2.31  
    2.32  int imtk_button(int id, const char *label, int x, int y);
    2.33 +int imtk_checkbox(int id, const char *label, int x, int y, int state);
    2.34  
    2.35  #endif	/* IMTK_H_ */
     3.1 --- a/test.c	Thu Dec 30 05:22:14 2010 +0200
     3.2 +++ b/test.c	Thu Dec 30 15:10:25 2010 +0200
     3.3 @@ -8,6 +8,7 @@
     3.4  #include "imtk.h"
     3.5  
     3.6  void disp(void);
     3.7 +void gui(void);
     3.8  void reshape(int x, int y);
     3.9  void keyb(unsigned char key, int x, int y);
    3.10  void keyb_up(unsigned char key, int x, int y);
    3.11 @@ -40,20 +41,37 @@
    3.12  
    3.13  void disp(void)
    3.14  {
    3.15 +	glClearColor(0.6, 0.6, 0.6, 0.0);
    3.16  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    3.17  
    3.18 +	gui();
    3.19 +
    3.20 +	glutSwapBuffers();
    3.21 +}
    3.22 +
    3.23 +void gui(void)
    3.24 +{
    3.25 +	static int bnshow;
    3.26 +
    3.27  	imtk_begin();
    3.28  
    3.29 -	if(imtk_button(0, "foobar", 100, 100)) {
    3.30 +	if(imtk_button(IMUID, "foobar", 100, 100)) {
    3.31  		printf("clicked button 0\n");
    3.32  	}
    3.33 -	if(imtk_button(1, "xyzzy", 100, 200)) {
    3.34 +	if(imtk_button(IMUID, "xyzzy", 100, 200)) {
    3.35  		printf("clicked button 1\n");
    3.36  	}
    3.37 +	if(imtk_button(IMUID, "Quit", 100, 500)) {
    3.38 +		exit(0);
    3.39 +	}
    3.40 +
    3.41 +	if((bnshow = imtk_checkbox(IMUID, "show hidden button", 100, 260, bnshow))) {
    3.42 +		if(imtk_button(IMUID, "I was hidden!", 130, 300)) {
    3.43 +			printf("you clicked the hidden button!\n");
    3.44 +		}
    3.45 +	}
    3.46  
    3.47  	imtk_end();
    3.48 -
    3.49 -	glutSwapBuffers();
    3.50  }
    3.51  
    3.52  void reshape(int x, int y)