libresman

annotate examples/imgthumbs/src/main.c @ 13:a42888d26839

bit more progress...
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 08 Feb 2014 07:41:39 +0200
parents 410c19c735b2
children 0a789208498d
rev   line source
nuclear@1 1 #include <stdio.h>
nuclear@1 2 #include <stdlib.h>
nuclear@1 3 #include <assert.h>
nuclear@11 4 #include <imago2.h>
nuclear@1 5 #include "opengl.h"
nuclear@1 6 #include "resman.h"
nuclear@1 7 #include "thumbs.h"
nuclear@1 8
nuclear@1 9 static int init(void);
nuclear@1 10 static void cleanup(void);
nuclear@1 11 static void display(void);
nuclear@1 12 /*static void idle(void);*/
nuclear@1 13 static void reshape(int x, int y);
nuclear@1 14 static void keyb(unsigned char key, int x, int y);
nuclear@1 15 static void mouse(int bn, int st, int x, int y);
nuclear@1 16 static void motion(int x, int y);
nuclear@2 17 static void sball_motion(int x, int y, int z);
nuclear@1 18 static struct thumbnail *find_thumb(int x, int y);
nuclear@1 19
nuclear@1 20 const char *path = ".";
nuclear@1 21 int win_width, win_height;
nuclear@1 22 float win_aspect;
nuclear@1 23 float pan_x, pan_y;
nuclear@1 24 float show_pan_x, show_pan_y;
nuclear@1 25 float show_zoom = 1.0;
nuclear@1 26 float thumbs_size = 0.25;
nuclear@1 27
nuclear@1 28 struct thumbnail *thumbs, *show_thumb;
nuclear@1 29
nuclear@1 30 int main(int argc, char **argv)
nuclear@1 31 {
nuclear@4 32 glutInitWindowSize(1024, 768);
nuclear@1 33 glutInit(&argc, argv);
nuclear@1 34
nuclear@1 35 if(argv[1]) {
nuclear@1 36 path = argv[1];
nuclear@1 37 }
nuclear@1 38
nuclear@1 39 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
nuclear@1 40 glutCreateWindow("imgthumbs");
nuclear@1 41
nuclear@1 42 glutDisplayFunc(display);
nuclear@11 43 glutIdleFunc(glutPostRedisplay);
nuclear@1 44 glutReshapeFunc(reshape);
nuclear@1 45 glutKeyboardFunc(keyb);
nuclear@1 46 glutMouseFunc(mouse);
nuclear@1 47 glutMotionFunc(motion);
nuclear@2 48 glutSpaceballMotionFunc(sball_motion);
nuclear@1 49
nuclear@1 50 if(init() == -1) {
nuclear@1 51 return 1;
nuclear@1 52 }
nuclear@1 53 atexit(cleanup);
nuclear@1 54
nuclear@1 55 glutMainLoop();
nuclear@1 56 return 0;
nuclear@1 57 }
nuclear@1 58
nuclear@1 59 static int init(void)
nuclear@1 60 {
nuclear@1 61 thumbs = create_thumbs(path);
nuclear@1 62 return 0;
nuclear@1 63 }
nuclear@1 64
nuclear@1 65 static void cleanup(void)
nuclear@1 66 {
nuclear@1 67 free_thumbs(thumbs);
nuclear@1 68 }
nuclear@1 69
nuclear@1 70 static void display(void)
nuclear@1 71 {
nuclear@11 72 update_thumbs();
nuclear@11 73
nuclear@1 74 glClear(GL_COLOR_BUFFER_BIT);
nuclear@1 75
nuclear@1 76 glMatrixMode(GL_MODELVIEW);
nuclear@1 77 glLoadIdentity();
nuclear@1 78
nuclear@1 79 if(show_thumb) {
nuclear@1 80 glEnable(GL_TEXTURE_2D);
nuclear@1 81 glBindTexture(GL_TEXTURE_2D, show_thumb->tex);
nuclear@1 82
nuclear@1 83 glScalef(show_zoom, show_zoom, 1);
nuclear@1 84 glTranslatef(2.0 * show_pan_x, 2.0 * show_pan_y, 0);
nuclear@4 85 if(show_thumb->aspect >= win_aspect) {
nuclear@1 86 glScalef(1, 1.0 / show_thumb->aspect, 1);
nuclear@1 87 } else {
nuclear@3 88 glScalef(show_thumb->aspect / win_aspect, 1.0 / win_aspect, 1);
nuclear@1 89 }
nuclear@1 90
nuclear@1 91 glBegin(GL_QUADS);
nuclear@1 92 glColor3f(1, 1, 1);
nuclear@1 93 glTexCoord2f(0, 0); glVertex2f(-1, -1);
nuclear@1 94 glTexCoord2f(1, 0); glVertex2f(1, -1);
nuclear@1 95 glTexCoord2f(1, 1); glVertex2f(1, 1);
nuclear@1 96 glTexCoord2f(0, 1); glVertex2f(-1, 1);
nuclear@1 97 glEnd();
nuclear@1 98
nuclear@1 99 glDisable(GL_TEXTURE_2D);
nuclear@1 100 } else {
nuclear@1 101 draw_thumbs(thumbs, thumbs_size, pan_y);
nuclear@1 102 }
nuclear@1 103
nuclear@1 104 glutSwapBuffers();
nuclear@1 105 assert(glGetError() == GL_NO_ERROR);
nuclear@1 106 }
nuclear@1 107
nuclear@1 108 /*
nuclear@1 109 static void idle(void)
nuclear@1 110 {
nuclear@1 111 glutPostRedisplay();
nuclear@1 112 }
nuclear@1 113 */
nuclear@1 114
nuclear@1 115 static void reshape(int x, int y)
nuclear@1 116 {
nuclear@1 117 win_aspect = (float)x / (float)y;
nuclear@1 118
nuclear@1 119 glViewport(0, 0, x, y);
nuclear@1 120
nuclear@1 121 glMatrixMode(GL_PROJECTION);
nuclear@1 122 glLoadIdentity();
nuclear@1 123 glOrtho(-1, 1, 1.0 / win_aspect, -1.0 / win_aspect, -1, 1);
nuclear@1 124
nuclear@1 125 win_width = x;
nuclear@1 126 win_height = y;
nuclear@1 127 }
nuclear@1 128
nuclear@1 129 static void keyb(unsigned char key, int x, int y)
nuclear@1 130 {
nuclear@1 131 switch(key) {
nuclear@1 132 case 27:
nuclear@3 133 if(show_thumb) {
nuclear@3 134 show_thumb = 0;
nuclear@3 135 glutPostRedisplay();
nuclear@3 136 } else {
nuclear@3 137 exit(0);
nuclear@3 138 }
nuclear@3 139 break;
nuclear@1 140
nuclear@1 141 case ' ':
nuclear@1 142 show_zoom = 1.0;
nuclear@1 143 thumbs_size = 0.25;
nuclear@1 144 pan_x = pan_y = show_pan_x = show_pan_y = 0;
nuclear@1 145 glutPostRedisplay();
nuclear@1 146 break;
nuclear@1 147 }
nuclear@1 148 }
nuclear@1 149
nuclear@1 150 static int bnstate[32];
nuclear@1 151 static int prev_x, prev_y;
nuclear@1 152 static int click_x[32], click_y[32];
nuclear@1 153
nuclear@1 154 static void mouse(int bn, int st, int x, int y)
nuclear@1 155 {
nuclear@1 156 int bidx = bn - GLUT_LEFT_BUTTON;
nuclear@1 157 int state = st == GLUT_DOWN ? 1 : 0;
nuclear@1 158
nuclear@1 159 bnstate[bidx] = state;
nuclear@1 160
nuclear@1 161 prev_x = x;
nuclear@1 162 prev_y = y;
nuclear@1 163
nuclear@1 164 if(state) {
nuclear@1 165 click_x[bidx] = x;
nuclear@1 166 click_y[bidx] = y;
nuclear@1 167 } else {
nuclear@1 168 int is_drag = abs(x - click_x[bidx]) > 3 || abs(y - click_y[bidx]) > 3;
nuclear@1 169
nuclear@1 170 if(bidx == 0) {
nuclear@1 171 if(!show_thumb) {
nuclear@1 172 if(!is_drag) {
nuclear@1 173 struct thumbnail *sel = find_thumb(x, y);
nuclear@1 174 if(sel) {
nuclear@1 175 show_thumb = sel;
nuclear@1 176 show_pan_x = show_pan_y = 0;
nuclear@1 177 glutPostRedisplay();
nuclear@1 178 }
nuclear@1 179 }
nuclear@1 180 }
nuclear@1 181 } else {
nuclear@1 182 if(!is_drag) {
nuclear@1 183 show_thumb = 0;
nuclear@1 184 glutPostRedisplay();
nuclear@1 185 }
nuclear@1 186 }
nuclear@1 187 }
nuclear@1 188 }
nuclear@1 189
nuclear@1 190 static void motion(int x, int y)
nuclear@1 191 {
nuclear@1 192 int dx = x - prev_x;
nuclear@1 193 int dy = y - prev_y;
nuclear@1 194 prev_x = x;
nuclear@1 195 prev_y = y;
nuclear@1 196
nuclear@1 197 if(!dx && !dy) return;
nuclear@1 198
nuclear@1 199 if(bnstate[0]) {
nuclear@1 200 float fdx = dx / (float)win_width;
nuclear@1 201 float fdy = dy / (float)win_height / win_aspect;
nuclear@1 202
nuclear@1 203 if(show_thumb) {
nuclear@1 204 show_pan_x += fdx / show_zoom;
nuclear@1 205 show_pan_y += fdy / show_zoom;
nuclear@1 206 } else {
nuclear@1 207 pan_x += fdx;
nuclear@1 208 pan_y += fdy;
nuclear@1 209 }
nuclear@1 210 glutPostRedisplay();
nuclear@1 211 }
nuclear@1 212
nuclear@1 213 if(bnstate[2]) {
nuclear@1 214 if(show_thumb) {
nuclear@1 215 show_zoom -= dy * 0.0075;
nuclear@1 216 if(show_zoom <= 0) show_zoom = 0;
nuclear@1 217 } else {
nuclear@1 218 thumbs_size -= dy * 0.005;
nuclear@1 219 if(thumbs_size <= 0.01) thumbs_size = 0.01;
nuclear@1 220 }
nuclear@1 221 glutPostRedisplay();
nuclear@1 222 }
nuclear@1 223 }
nuclear@1 224
nuclear@2 225 static void sball_motion(int x, int y, int z)
nuclear@2 226 {
nuclear@2 227 float fx = -x * 0.0004;
nuclear@2 228 float fy = z * 0.0004;
nuclear@2 229 float fz = -y * 0.0005;
nuclear@2 230
nuclear@2 231 if(show_thumb) {
nuclear@2 232 show_pan_x += fx / show_zoom;
nuclear@2 233 show_pan_y += fy / show_zoom;
nuclear@2 234 show_zoom += fz;
nuclear@2 235 if(show_zoom <= 0) show_zoom = 0;
nuclear@2 236 } else {
nuclear@2 237 pan_x += fx;
nuclear@2 238 pan_y += fy;
nuclear@2 239 thumbs_size += fz;
nuclear@2 240 if(thumbs_size <= 0.01) thumbs_size = 0.01;
nuclear@2 241 }
nuclear@2 242 glutPostRedisplay();
nuclear@2 243 }
nuclear@2 244
nuclear@1 245 static struct thumbnail *find_thumb(int x, int y)
nuclear@1 246 {
nuclear@1 247 float fx = (float)x / (float)win_width;
nuclear@1 248 float fy = (float)y / (float)win_height / win_aspect;
nuclear@1 249 struct thumbnail *node;
nuclear@1 250
nuclear@1 251 node = thumbs;
nuclear@1 252 while(node) {
nuclear@1 253 float nx = node->layout_pos[0];
nuclear@1 254 float ny = node->layout_pos[1];
nuclear@1 255
nuclear@1 256 if(fx >= nx && fx < nx + node->layout_size[0] &&
nuclear@1 257 fy >= ny && fy < ny + node->layout_size[1]) {
nuclear@1 258 return node;
nuclear@1 259 }
nuclear@1 260 node = node->next;
nuclear@1 261 }
nuclear@1 262 return 0;
nuclear@1 263 }