Browse code

Scroll by finger. Big image on double click

Dario Rodriguez authored on 16/03/2025 16:22:19
Showing 1 changed files
... ...
@@ -26,6 +26,7 @@
26 26
  *               Add show using all window with right button.
27 27
  *      20250316 Add android target support.
28 28
  *               Delay loading images if over fps deadline.
29
+ *               Scroll by finger. Big image on double click.
29 30
  *
30 31
  * Author: Dario Rodriguez dario@darionomono.com
31 32
  * (c) Dario Rodriguez 2025
... ...
@@ -46,7 +47,9 @@
46 47
 
47 48
 #define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */
48 49
 
50
+#ifndef ANDROID
49 51
 #define SIMANDROID
52
+#endif
50 53
 
51 54
 #define TARGETFPS 30
52 55
 
... ...
@@ -74,6 +77,8 @@
74 77
 #define FONTHUGESIZE 48
75 78
 #endif
76 79
 
80
+#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3)
81
+
77 82
 #if defined(SIMANDROID)
78 83
 #undef ROOTDIR
79 84
 #define ROOTDIR "/var/www/default/animeshot/"
... ...
@@ -192,6 +197,7 @@ typedef struct texture_t {
192 197
         int textureh;
193 198
         int has_texture;
194 199
         int has_failedload;
200
+        xywh_t source; /* be able to detect a "double click" */
195 201
 } texture_t;
196 202
 
197 203
 typedef struct body_t {
... ...
@@ -208,7 +214,9 @@ typedef struct body_t {
208 214
         font_t *ptrfontbig;
209 215
         font_t *ptrfonthuge;
210 216
         texture_t texture;
217
+        int is_displayingtexture;
211 218
         texture_t bigtexture;
219
+        int flag_drawbigtexture;
212 220
 } body_t;
213 221
 
214 222
 typedef struct im_t {
... ...
@@ -264,17 +272,23 @@ int is_imagefilename(char *filename);
264 272
 Image imutil_loadimage(const char *filename);
265 273
 void imutil_fpsreset(void);
266 274
 int imutil_fpsleft(void);
275
+long long imutil_milliseconds(void);
267 276
 
268 277
 int
269 278
 main(int argc, char *argv[])
270 279
 {
271 280
         im_t *im;
272
-        Vector2 mousepos,wheel,oldmousepos;
281
+        Vector2 mousepos,wheel,oldmousepos,scrollstartpos;
273 282
         int flag_ignorelmb;
274 283
         int lmbpressed,lmbreleased,lmbdown,rmbdown,oldlmbdown,oldrmbdown;
275 284
         int click_avail;
276 285
         int has_mousechanges;
277 286
         int needs_nextredraw;
287
+        long long scrollstart;
288
+        long long scrolllast;
289
+        int scrollspeed;
290
+        int is_scrolling;
291
+        int leftscrollposstart;
278 292
         char *sel_menu,*sel_submenu;
279 293
         if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) {
280 294
                 return(1);
... ...
@@ -283,6 +297,8 @@ main(int argc, char *argv[])
283 297
         mousepos=(Vector2) {.x=0,.y=0};
284 298
         lmbdown=rmbdown=-1;
285 299
         needs_nextredraw=1;
300
+        scrollstart=0;
301
+        is_scrolling=0;
286 302
         while(!WindowShouldClose()) {
287 303
                 imutil_fpsreset();
288 304
                 oldmousepos=mousepos;
... ...
@@ -296,21 +312,57 @@ main(int argc, char *argv[])
296 312
                 rmbdown=IsMouseButtonDown(1);
297 313
                 click_avail=1;
298 314
                 has_mousechanges=(lmbdown!=oldlmbdown || rmbdown!=oldrmbdown || mousepos.x!=oldmousepos.x || mousepos.y!=oldmousepos.y || wheel.x!=0 || wheel.y!=0)?1:0;
299
-                needs_nextredraw=(has_mousechanges==0 && needs_nextredraw==0)?0:1;
300
-                if(needs_nextredraw==0) {
301
-                        BeginDrawing();
302
-                        EndDrawing();
303
-                        continue;
304
-                }
305 315
                 needs_nextredraw=0;
316
+                /* process scrolling */
317
+                if(lmbdown==1 && oldlmbdown==0 && scrollstart==0 && mousepos.y>im->body->xywh.y) {
318
+                        scrollstart=imutil_milliseconds();
319
+                        scrollstartpos=mousepos;
320
+                        leftscrollposstart=im->body->leftscrollpos;
321
+                }
322
+                if(scrollstart!=0 && lmbdown==0) {
323
+                        scrollstart=0;
324
+                        if(is_scrolling)
325
+                                click_avail=0; /* this click is the mouseup of the scroll */
326
+                }
327
+                is_scrolling=(scrollstart==0)?0:is_scrolling;
328
+                if(is_scrolling==0 && scrollstart!=0) {
329
+                        float t;
330
+                        t=scrollstartpos.y-mousepos.y;
331
+                        t=(t<0)?-t:t;
332
+                        if(t>SCROLLTHRESHOLD) {
333
+                                is_scrolling=1;
334
+                                scrolllast=0;
335
+                        }
336
+                        t=scrollstartpos.x-mousepos.x;
337
+                        t=(t<0)?-t:t;
338
+                        if(t>SCROLLTHRESHOLD)
339
+                                is_scrolling=0,scrollstart=0;
340
+                }
341
+                if(is_scrolling) {
342
+                        long long tcur,tdif;
343
+                        long long ycur;
344
+                        tcur=imutil_milliseconds();
345
+                        tdif=tcur-scrolllast;
346
+                        ycur=scrollstartpos.y-mousepos.y;
347
+                        scrollspeed=(tdif>0)?(oldmousepos.y-mousepos.y)*100000/tdif:0;
348
+                        im->body->leftscrollpos=leftscrollposstart+ycur;
349
+                        scrolllast=tcur;
350
+                }
351
+                if(is_scrolling==0 && scrollspeed!=0) {
352
+                        scrollspeed=scrollspeed*4/5;
353
+                        im->body->leftscrollpos+=scrollspeed;
354
+                }
306 355
                 /* process clicks on menus */
307 356
                 if(click_avail) {
308 357
                         sel_menu=sel_submenu=NULL;
309 358
                         im_menubar_mouse(im->menubar, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail, &sel_menu, &sel_submenu);
310 359
                         if(sel_menu!=NULL && sel_submenu!=NULL) {
360
+
311 361
 #if 1
312 362
 fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu);
313 363
 #endif
364
+                                if(strcmp(sel_submenu,"Salir")==0)
365
+                                        break; /* exit from main loop */
314 366
                         }
315 367
                 }
316 368
                 if(click_avail)
... ...
@@ -353,6 +405,13 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu);
353 405
  }
354 406
 }
355 407
 #endif
408
+                if(has_mousechanges==0 && needs_nextredraw==0) {
409
+                        /* Wait for new events when calling EndDrawing() */
410
+                        EnableEventWaiting();
411
+                } else {
412
+                        /* EndDrawing() doesn't wait for new events, returns immediately */
413
+                        DisableEventWaiting();
414
+                }
356 415
                 EndDrawing();
357 416
         }
358 417
         im_free(im),im=NULL;
... ...
@@ -764,6 +823,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int
764 823
         char *ptr;
765 824
         dirdata_t *dirdata;
766 825
         listingdata_t *ld;
826
+        int margin;
767 827
         if(body==NULL || click_avail==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL)
768 828
                 return(-1); /* sanity check error */
769 829
         dirdata=body->dirdata[body->currentdirdata];
... ...
@@ -775,6 +835,17 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int
775 835
         /* check if we have to process a click */
776 836
         if(*click_avail==0 || lmbreleased==0)
777 837
                 return(0); /* nothing else to do */
838
+        /* show image in full screen */
839
+        if(body->flag_drawbigtexture) {
840
+                if(lmbreleased)
841
+                        body->flag_drawbigtexture=0;
842
+                return(0); /* nothing else to do */
843
+        }
844
+        margin=body->ptrfont->height/4;
845
+        if(body->is_displayingtexture && lmbreleased && is_imutil_insidexywh(mousepos,&(body->texture.source),margin)) {
846
+                body->flag_drawbigtexture=1;
847
+                return(0); /* nothing else to do */
848
+        }
778 849
         /* leftside backbutton */
779 850
         if(is_imutil_insidexywh(mousepos,&(body->backxywh),0)) {
780 851
                 static char sep[]={SEP};
... ...
@@ -845,6 +916,25 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo
845 916
         fonthuge=body->ptrfonthuge;
846 917
         FILLXYWH(body->backxywh,0,0,0,0);
847 918
         margin=font->height/4;
919
+        body->is_displayingtexture=0;
920
+        /* if we are displaying a full screenimage... */
921
+        if(body->flag_drawbigtexture && body->texture.has_texture) {
922
+                /* draw image in full screen */
923
+                int maxw,maxh;
924
+                maxw=windowwidth;
925
+                maxh=windowheight-body->xywh.y;
926
+                if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0)
927
+                        texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh);
928
+                if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,body->texture.currentpath)==0) {
929
+                        int x0,y0;
930
+                        x0=0;
931
+                        y0=body->xywh.y;
932
+                        texture_draw(&(body->bigtexture),x0,y0,maxw,maxh);
933
+                        return(0); /* all done */
934
+                } else {
935
+                        body->flag_drawbigtexture=0; /* error loading big texture, draw screen normally */
936
+                }
937
+        }
848 938
         /* calculate positions */
849 939
         for(i=0;i<body->sizedirdata;i++) {
850 940
                 if(body->dirdata[i]==NULL)
... ...
@@ -1011,7 +1101,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel
1011 1101
                                                 DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE);
1012 1102
                                                 has_imagedrawn=1;
1013 1103
                                                 lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff;
1014
-                                                if(is_leftside && lmbdown==0 && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) {
1104
+                                                if(is_leftside && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) {
1015 1105
                                                         /* draw image in rightside */
1016 1106
                                                         char fullpath[2048];
1017 1107
                                                         int maxw,maxh;
... ...
@@ -1029,31 +1119,11 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel
1029 1119
                                                                 x0=body->leftsize-DEFAULTDIRDATATRIANGLEW;
1030 1120
                                                                 y0=body->xywh.y;
1031 1121
                                                                 texture_draw(&(body->texture),x0,y0,maxw,maxh);
1122
+                                                                body->is_displayingtexture=1;
1123
+                                                                memcpy(&(body->texture.source),&(thumb->screenxywh),sizeof(body->texture.source));
1032 1124
                                                                 flag_skiprightside=1;
1033 1125
                                                         }
1034 1126
                                                 }
1035
-                                                if(is_leftside && lmbdown==0 && rmbdown!=0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) {
1036
-                                                        /* draw image in full screen */
1037
-                                                        char fullpath[2048];
1038
-                                                        int maxw,maxh;
1039
-                                                        maxw=windowwidth;
1040
-                                                        maxh=windowheight-body->xywh.y;
1041
-                                                        snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1);
1042
-                                                        fullpath[sizeof(fullpath)-1]='\0';
1043
-                                                        if((body->bigtexture.has_texture==0 && !(body->bigtexture.has_failedload && strcmp(body->bigtexture.currentpath,fullpath)==0))
1044
-                                                          || strcmp(body->bigtexture.currentpath,fullpath)!=0
1045
-                                                        ) {
1046
-                                                                texture_load(&(body->bigtexture),fullpath,maxw,maxh);
1047
-                                                        }
1048
-                                                        if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,fullpath)==0) {
1049
-                                                                int x0,y0;
1050
-                                                                x0=0;
1051
-                                                                y0=body->xywh.y;
1052
-                                                                texture_draw(&(body->bigtexture),x0,y0,maxw,maxh);
1053
-                                                                flag_skipall=1;
1054
-                                                                break;
1055
-                                                        }
1056
-                                                }
1057 1127
                                         }
1058 1128
                                 }
1059 1129
                                 if(has_imagedrawn==0) {
... ...
@@ -1639,3 +1709,13 @@ imutil_fpsleft(void)
1639 1709
         return(1);
1640 1710
 }
1641 1711
 
1712
+long long
1713
+imutil_milliseconds(void)
1714
+{
1715
+        long long res;
1716
+        struct timeval now;
1717
+        gettimeofday(&now,NULL);
1718
+        res=((long long) (now.tv_sec))*1000000L+((long long) (now.tv_usec));
1719
+        return(res);
1720
+}
1721
+