Clean up code, save more state, pan better
dkl9

dkl9 commited on 2025-181 00:45:39
Showing 1 changed files, with 78 additions and 64 deletions.

... ...
@@ -17,8 +17,7 @@
17 17
 #define DZDS 0.25
18 18
 
19 19
 struct ViewState {
20
-    /* image index */
21
-    int ci;
20
+    SDL_Texture* tex;
22 21
     /* image dimensions */
23 22
     int iw;
24 23
     int ih;
... ...
@@ -27,9 +26,6 @@ struct ViewState {
27 26
     /* pan position (centre of image) */
28 27
     int px;
29 28
     int py;
30
-    /* keep track of mouse coordinates */
31
-    int mx;
32
-    int my;
33 29
 };
34 30
 
35 31
 /* if cond is true, exit the program as a failure,
... ...
@@ -128,6 +124,35 @@ void showcoords(const SDL_MouseButtonEvent button, const struct ViewState vs) {
128 124
     fflush(stdout);
129 125
 }
130 126
 
127
+int handlekey(SDL_Keycode sym, struct ViewState* vs, int ci, int fc, int ww, int wh) {
128
+    switch (sym) {
129
+        /* bring image back into focus when Space is pressed */
130
+        case SDLK_SPACE:
131
+            vs->px = ww / 2;
132
+            vs->py = wh / 2;
133
+            return 2;
134
+            break;
135
+        /* exit when Esc is pressed */
136
+        case SDLK_ESCAPE:
137
+            return 4;
138
+            break;
139
+        /* navigate image list with arrow keys */
140
+        case SDLK_LEFT:
141
+        case SDLK_UP:
142
+            if (ci > 0) {
143
+                return -1;
144
+            }
145
+            break;
146
+        case SDLK_RIGHT:
147
+        case SDLK_DOWN:
148
+            if (ci < fc - 1) {
149
+                return 1;
150
+            }
151
+            break;
152
+    }
153
+    return 0;
154
+}
155
+
131 156
 void drawbg(SDL_Renderer* ren, const int ww, const int wh, const int cw, const int ch, SDL_Texture* act) {
132 157
     /* clear to background colour */
133 158
     cfail(SDL_RenderClear(ren), "clear screen", 1);
... ...
@@ -141,9 +166,9 @@ void drawbg(SDL_Renderer* ren, const int ww, const int wh, const int cw, const i
141 166
     }
142 167
 }
143 168
 
144
-void drawfg(SDL_Renderer* ren, const struct ViewState vs, SDL_Texture* imgtex) {
169
+void drawfg(SDL_Renderer* ren, const struct ViewState vs) {
145 170
     /* render image */
146
-    cfail(SDL_RenderCopy(ren, imgtex, NULL, &(SDL_Rect){
171
+    cfail(SDL_RenderCopy(ren, vs.tex, NULL, &(SDL_Rect){
147 172
         .x = vs.px - ZSH(vs.iw, vs.zoom - 1.0), .y = vs.py - ZSH(vs.ih, vs.zoom - 1.0),
148 173
         .w = ZSH(vs.iw, vs.zoom), .h = ZSH(vs.ih, vs.zoom)
149 174
     }), "display image", 1);
... ...
@@ -160,8 +185,9 @@ int main(int argc, char** argv) {
160 185
     cfail(optind >= argc, "find filename(s) in options", 0);
161 186
     int fc = argc - optind;
162 187
     SDL_Surface** isurf = loadimages(argv, fc);
163
-    int iw = isurf[0]->w;
164
-    int ih = isurf[0]->h;
188
+    int ci = 0;
189
+    int iw = isurf[ci]->w;
190
+    int ih = isurf[ci]->h;
165 191
 
166 192
     /* create window and renderer */
167 193
     char* title = NULL;
... ...
@@ -183,10 +209,14 @@ int main(int argc, char** argv) {
183 209
     /* make images into textures */
184 210
     int cw, ch;
185 211
     SDL_Texture* act = checker(ren, argv[0], &cw, &ch);
186
-    SDL_Texture** itex = calloc(fc, sizeof (SDL_Texture*));
212
+    struct ViewState* sl = calloc(fc, sizeof(struct ViewState));
187 213
     for (int i = 0; i < fc; i++) {
188
-        itex[i] = SDL_CreateTextureFromSurface(ren, isurf[i]);
189
-        cfail(!itex[i], "create texture", 1);
214
+        sl[i].tex = SDL_CreateTextureFromSurface(ren, isurf[i]);
215
+        cfail(!sl[i].tex, "create texture", 1);
216
+        sl[i].px = sl[i].iw = isurf[i]->w;
217
+        sl[i].px /= 2;
218
+        sl[i].py = sl[i].ih = isurf[i]->h;
219
+        sl[i].py /= 2;
190 220
         SDL_FreeSurface(isurf[i]);
191 221
     }
192 222
 
... ...
@@ -203,10 +233,8 @@ int main(int argc, char** argv) {
203 233
     /* window size */
204 234
     int ww = iw;
205 235
     int wh = ih;
206
-    struct ViewState vs = {
207
-        .ci = 0, .iw = iw, .ih = ih, .zoom = 0,
208
-        .px = iw / 2, .py = ih / 2, .mx = 0, .my = 0
209
-    };
236
+    /* mouse position */
237
+    int mx, my;
210 238
 
211 239
     while (r) {
212 240
         ef = 0;
... ...
@@ -215,52 +243,37 @@ int main(int argc, char** argv) {
215 243
 
216 244
                 case SDL_KEYUP:
217 245
                     int iic = 0;
218
-                    switch (ev.key.keysym.sym) {
219
-                        /* bring image back into focus when Space is pressed */
220
-                        case SDLK_SPACE:
221
-                            vs.px = ww / 2;
222
-                            vs.py = wh / 2;
223
-                            ef = 1;
224
-                            break;
225
-                        /* exit when Esc is pressed */
226
-                        case SDLK_ESCAPE:
246
+                    switch (handlekey(ev.key.keysym.sym, &sl[ci], ci, fc, ww, wh)) {
247
+                        case 4:
227 248
                             r = 0;
228 249
                             break;
229
-                        /* navigate image list with arrow keys */
230
-                        case SDLK_LEFT:
231
-                        case SDLK_UP:
232
-                            if (vs.ci > 0) {
233
-                                vs.ci--;
250
+                        case 2:
251
+                            ef = 1;
252
+                            break;
253
+                        case 1:
234 254
                             iic = 1;
235
-                            }
255
+                            ci++;
236 256
                             break;
237
-                        case SDLK_RIGHT:
238
-                        case SDLK_DOWN:
239
-                            if (vs.ci < fc - 1) {
240
-                                vs.ci++;
257
+                        case -1:
241 258
                             iic = 1;
242
-                            }
259
+                            ci--;
243 260
                             break;
244 261
                     }
245 262
                     if (iic) {
246
-                        cfail(SDL_QueryTexture(itex[vs.ci], NULL, NULL, &vs.iw, &vs.ih), "query texture", 1);
247
-                        vs.zoom = 0;
248
-                        vs.px = vs.iw / 2;
249
-                        vs.py = vs.ih / 2;
250 263
                         ef = 1;
251
-                        updatetitle(window, ct, &title, argv[optind + vs.ci], vs);
264
+                        updatetitle(window, ct, &title, argv[optind + ci], sl[ci]);
252 265
                     }
253 266
                     break;
254 267
 
255 268
                 case SDL_MOUSEBUTTONDOWN:
256 269
                     /* output coordinates of cursor in image on middle-click */
257 270
                     if (ev.button.button == 2) {
258
-                        showcoords(ev.button, vs);
271
+                        showcoords(ev.button, sl[ci]);
259 272
                     }
260 273
                     /* bring image back into focus on right-click */
261 274
                     if (ev.button.button == 3) {
262
-                        vs.px = ww / 2;
263
-                        vs.py = wh / 2;
275
+                        sl[ci].px = ww / 2;
276
+                        sl[ci].py = wh / 2;
264 277
                         ef = 1;
265 278
                     }
266 279
                     break;
... ...
@@ -268,31 +281,32 @@ int main(int argc, char** argv) {
268 281
                 case SDL_MOUSEMOTION:
269 282
                     /* pan-dragging if mouse is down */
270 283
                     if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(1)) {
271
-                        int sw = ZSH(vs.iw, vs.zoom - 1.0);
272
-                        int sh = ZSH(vs.ih, vs.zoom - 1.0);
273
-                        /* clamp panning to edges of window,
274
-                        unless zoomed image is bigger than window */
275
-                        if (2 * sw > ww) {
276
-                            vs.px += ev.motion.xrel;
277
-                        } else {
278
-                            vs.px = CLAMP(sw, vs.px + ev.motion.xrel, ww - sw);
279
-                        }
280
-                        if (2 * sh > wh) {
281
-                            vs.py += ev.motion.yrel;
282
-                        } else {
283
-                            vs.py = CLAMP(sh, vs.py + ev.motion.yrel, wh - sh);
284
-                        }
284
+                        int sw = ZSH(sl[ci].iw, sl[ci].zoom - 1.0);
285
+                        int sh = ZSH(sl[ci].ih, sl[ci].zoom - 1.0);
286
+                        /* clamp panning to edges of window */
287
+                        int big = 2 * sw > ww;
288
+                        sl[ci].px = CLAMP(
289
+                            big ? ww - sw : sw,
290
+                            sl[ci].px + ev.motion.xrel,
291
+                            big ? sw : ww - sw
292
+                        );
293
+                        big = 2 * sh > wh;
294
+                        sl[ci].py = CLAMP(
295
+                            big ? wh - sh : sh,
296
+                            sl[ci].py + ev.motion.yrel,
297
+                            big ? sh : wh - sh
298
+                        );
285 299
                         ef = 1;
286 300
                     }
287
-                    vs.mx = ev.motion.x;
288
-                    vs.my = ev.motion.y;
301
+                    mx = ev.motion.x;
302
+                    my = ev.motion.y;
289 303
                     break;
290 304
 
291 305
                 case SDL_MOUSEWHEEL:
292 306
                     /* scrolling changes zoom */
293
-                    vs.zoom += DZDS * ev.wheel.y;
294
-                    vs.px = vs.mx - ZSH((vs.mx - vs.px), DZDS * ev.wheel.y);
295
-                    vs.py = vs.my - ZSH((vs.my - vs.py), DZDS * ev.wheel.y);
307
+                    sl[ci].zoom += DZDS * ev.wheel.y;
308
+                    sl[ci].px = mx - ZSH((mx - sl[ci].px), DZDS * ev.wheel.y);
309
+                    sl[ci].py = my - ZSH((my - sl[ci].py), DZDS * ev.wheel.y);
296 310
                     ef = 1;
297 311
                     break;
298 312
 
... ...
@@ -323,7 +337,7 @@ int main(int argc, char** argv) {
323 337
 
324 338
         if (ef) {
325 339
             drawbg(ren, ww, wh, cw, ch, act);
326
-            drawfg(ren, vs, itex[vs.ci]);
340
+            drawfg(ren, sl[ci]);
327 341
             SDL_RenderPresent(ren);
328 342
         }
329 343
 
330 344