libresman

diff examples/imgthumbs/src/main.c @ 1:469ce01809bc

rudimentary imgthumbs "example program". doesn't use libresman yet
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 31 Jan 2014 03:17:24 +0200
parents
children 026cdd1737ff
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/examples/imgthumbs/src/main.c	Fri Jan 31 03:17:24 2014 +0200
     1.3 @@ -0,0 +1,232 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <assert.h>
     1.7 +#include "opengl.h"
     1.8 +#include "resman.h"
     1.9 +#include "thumbs.h"
    1.10 +
    1.11 +static int init(void);
    1.12 +static void cleanup(void);
    1.13 +static void display(void);
    1.14 +/*static void idle(void);*/
    1.15 +static void reshape(int x, int y);
    1.16 +static void keyb(unsigned char key, int x, int y);
    1.17 +static void mouse(int bn, int st, int x, int y);
    1.18 +static void motion(int x, int y);
    1.19 +static struct thumbnail *find_thumb(int x, int y);
    1.20 +
    1.21 +const char *path = ".";
    1.22 +struct resman *texman;
    1.23 +int win_width, win_height;
    1.24 +float win_aspect;
    1.25 +float pan_x, pan_y;
    1.26 +float show_pan_x, show_pan_y;
    1.27 +float show_zoom = 1.0;
    1.28 +float thumbs_size = 0.25;
    1.29 +
    1.30 +struct thumbnail *thumbs, *show_thumb;
    1.31 +
    1.32 +int main(int argc, char **argv)
    1.33 +{
    1.34 +	glutInit(&argc, argv);
    1.35 +
    1.36 +	if(argv[1]) {
    1.37 +		path = argv[1];
    1.38 +	}
    1.39 +
    1.40 +	glutInitWindowSize(800, 600);
    1.41 +	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    1.42 +	glutCreateWindow("imgthumbs");
    1.43 +
    1.44 +	glutDisplayFunc(display);
    1.45 +	glutReshapeFunc(reshape);
    1.46 +	glutKeyboardFunc(keyb);
    1.47 +	glutMouseFunc(mouse);
    1.48 +	glutMotionFunc(motion);
    1.49 +
    1.50 +	if(init() == -1) {
    1.51 +		return 1;
    1.52 +	}
    1.53 +	atexit(cleanup);
    1.54 +
    1.55 +	glutMainLoop();
    1.56 +	return 0;
    1.57 +}
    1.58 +
    1.59 +static int init(void)
    1.60 +{
    1.61 +	thumbs = create_thumbs(path);
    1.62 +	return 0;
    1.63 +}
    1.64 +
    1.65 +static void cleanup(void)
    1.66 +{
    1.67 +	free_thumbs(thumbs);
    1.68 +}
    1.69 +
    1.70 +static void display(void)
    1.71 +{
    1.72 +	glClear(GL_COLOR_BUFFER_BIT);
    1.73 +
    1.74 +	glMatrixMode(GL_MODELVIEW);
    1.75 +	glLoadIdentity();
    1.76 +
    1.77 +	if(show_thumb) {
    1.78 +		glEnable(GL_TEXTURE_2D);
    1.79 +		glBindTexture(GL_TEXTURE_2D, show_thumb->tex);
    1.80 +
    1.81 +		glScalef(show_zoom, show_zoom, 1);
    1.82 +		glTranslatef(2.0 * show_pan_x, 2.0 * show_pan_y, 0);
    1.83 +		if(show_thumb->aspect >= 1.0) {
    1.84 +			glScalef(1, 1.0 / show_thumb->aspect, 1);
    1.85 +		} else {
    1.86 +			glScalef(show_thumb->aspect, 1, 1);
    1.87 +		}
    1.88 +
    1.89 +		glBegin(GL_QUADS);
    1.90 +		glColor3f(1, 1, 1);
    1.91 +		glTexCoord2f(0, 0); glVertex2f(-1, -1);
    1.92 +		glTexCoord2f(1, 0); glVertex2f(1, -1);
    1.93 +		glTexCoord2f(1, 1); glVertex2f(1, 1);
    1.94 +		glTexCoord2f(0, 1); glVertex2f(-1, 1);
    1.95 +		glEnd();
    1.96 +
    1.97 +		glDisable(GL_TEXTURE_2D);
    1.98 +	} else {
    1.99 +		draw_thumbs(thumbs, thumbs_size, pan_y);
   1.100 +	}
   1.101 +
   1.102 +	glutSwapBuffers();
   1.103 +	assert(glGetError() == GL_NO_ERROR);
   1.104 +}
   1.105 +
   1.106 +/*
   1.107 +static void idle(void)
   1.108 +{
   1.109 +	glutPostRedisplay();
   1.110 +}
   1.111 +*/
   1.112 +
   1.113 +static void reshape(int x, int y)
   1.114 +{
   1.115 +	win_aspect = (float)x / (float)y;
   1.116 +
   1.117 +	glViewport(0, 0, x, y);
   1.118 +
   1.119 +	glMatrixMode(GL_PROJECTION);
   1.120 +	glLoadIdentity();
   1.121 +	glOrtho(-1, 1, 1.0 / win_aspect, -1.0 / win_aspect, -1, 1);
   1.122 +
   1.123 +	win_width = x;
   1.124 +	win_height = y;
   1.125 +}
   1.126 +
   1.127 +static void keyb(unsigned char key, int x, int y)
   1.128 +{
   1.129 +	switch(key) {
   1.130 +	case 27:
   1.131 +		exit(0);
   1.132 +
   1.133 +	case ' ':
   1.134 +		show_zoom = 1.0;
   1.135 +		thumbs_size = 0.25;
   1.136 +		pan_x = pan_y = show_pan_x = show_pan_y = 0;
   1.137 +		glutPostRedisplay();
   1.138 +		break;
   1.139 +	}
   1.140 +}
   1.141 +
   1.142 +static int bnstate[32];
   1.143 +static int prev_x, prev_y;
   1.144 +static int click_x[32], click_y[32];
   1.145 +
   1.146 +static void mouse(int bn, int st, int x, int y)
   1.147 +{
   1.148 +	int bidx = bn - GLUT_LEFT_BUTTON;
   1.149 +	int state = st == GLUT_DOWN ? 1 : 0;
   1.150 +
   1.151 +	bnstate[bidx] = state;
   1.152 +
   1.153 +	prev_x = x;
   1.154 +	prev_y = y;
   1.155 +
   1.156 +	if(state) {
   1.157 +		click_x[bidx] = x;
   1.158 +		click_y[bidx] = y;
   1.159 +	} else {
   1.160 +		int is_drag = abs(x - click_x[bidx]) > 3 || abs(y - click_y[bidx]) > 3;
   1.161 +
   1.162 +		if(bidx == 0) {
   1.163 +			if(!show_thumb) {
   1.164 +				if(!is_drag) {
   1.165 +					struct thumbnail *sel = find_thumb(x, y);
   1.166 +					if(sel) {
   1.167 +						show_thumb = sel;
   1.168 +						show_pan_x = show_pan_y = 0;
   1.169 +						glutPostRedisplay();
   1.170 +					}
   1.171 +				}
   1.172 +			}
   1.173 +		} else {
   1.174 +			if(!is_drag) {
   1.175 +				show_thumb = 0;
   1.176 +				glutPostRedisplay();
   1.177 +			}
   1.178 +		}
   1.179 +	}
   1.180 +}
   1.181 +
   1.182 +static void motion(int x, int y)
   1.183 +{
   1.184 +	int dx = x - prev_x;
   1.185 +	int dy = y - prev_y;
   1.186 +	prev_x = x;
   1.187 +	prev_y = y;
   1.188 +
   1.189 +	if(!dx && !dy) return;
   1.190 +
   1.191 +	if(bnstate[0]) {
   1.192 +		float fdx = dx / (float)win_width;
   1.193 +		float fdy = dy / (float)win_height / win_aspect;
   1.194 +
   1.195 +		if(show_thumb) {
   1.196 +			show_pan_x += fdx / show_zoom;
   1.197 +			show_pan_y += fdy / show_zoom;
   1.198 +		} else {
   1.199 +			pan_x += fdx;
   1.200 +			pan_y += fdy;
   1.201 +		}
   1.202 +		glutPostRedisplay();
   1.203 +	}
   1.204 +
   1.205 +	if(bnstate[2]) {
   1.206 +		if(show_thumb) {
   1.207 +			show_zoom -= dy * 0.0075;
   1.208 +			if(show_zoom <= 0) show_zoom = 0;
   1.209 +		} else {
   1.210 +			thumbs_size -= dy * 0.005;
   1.211 +			if(thumbs_size <= 0.01) thumbs_size = 0.01;
   1.212 +		}
   1.213 +		glutPostRedisplay();
   1.214 +	}
   1.215 +}
   1.216 +
   1.217 +static struct thumbnail *find_thumb(int x, int y)
   1.218 +{
   1.219 +	float fx = (float)x / (float)win_width;
   1.220 +	float fy = (float)y / (float)win_height / win_aspect;
   1.221 +	struct thumbnail *node;
   1.222 +
   1.223 +	node = thumbs;
   1.224 +	while(node) {
   1.225 +		float nx = node->layout_pos[0];
   1.226 +		float ny = node->layout_pos[1];
   1.227 +
   1.228 +		if(fx >= nx && fx < nx + node->layout_size[0] &&
   1.229 +				fy >= ny && fy < ny + node->layout_size[1]) {
   1.230 +			return node;
   1.231 +		}
   1.232 +		node = node->next;
   1.233 +	}
   1.234 +	return 0;
   1.235 +}