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 +}