... | ... |
@@ -520,8 +520,13 @@ im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowhe |
520 | 520 |
IMDEBUG("begin draw"); |
521 | 521 |
maxw=windowwidth; |
522 | 522 |
maxh=windowheight-body->whxy.y; |
523 |
- if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0) |
|
523 |
+ if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0) { |
|
524 |
+#if 1 |
|
525 |
+fprintf(stderr,"~~~ TEXTURE_LOAD FOR BIGTEXTURE \"%s\"\n",body->texture.currentpath); |
|
526 |
+#endif |
|
527 |
+ bg_add(body->bg,body->texture.currentpath,1); |
|
524 | 528 |
texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh,body->bg); |
529 |
+ } |
|
525 | 530 |
if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,body->texture.currentpath)==0) { |
526 | 531 |
int x0,y0; |
527 | 532 |
x0=0; |
... | ... |
@@ -529,7 +534,10 @@ im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowhe |
529 | 534 |
texture_draw(&(body->bigtexture),x0,y0,maxw,maxh); |
530 | 535 |
return(0); /* all done */ |
531 | 536 |
} else { |
537 |
+#if 0 |
|
538 |
+#warning TEMP |
|
532 | 539 |
body->flag_drawbigtexture=0; /* error loading big texture, draw screen normally */ |
540 |
+#endif |
|
533 | 541 |
} |
534 | 542 |
} |
535 | 543 |
/* calculate positions */ |
... | ... |
@@ -716,7 +724,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
716 | 724 |
thumb->has_failedload=1; |
717 | 725 |
} |
718 | 726 |
} else if(bgload==NULL) { |
719 |
- bg_add(body->bg,fullpath); |
|
727 |
+ bg_add(body->bg,fullpath,0); |
|
720 | 728 |
} |
721 | 729 |
} |
722 | 730 |
if(thumb->has_texture!=0) { |
... | ... |
@@ -784,7 +792,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
784 | 792 |
} |
785 | 793 |
} |
786 | 794 |
if(imageundermouse[0]!='\0') |
787 |
- bg_add(body->bg,imageundermouse); /* to prioritise loading this image */ |
|
795 |
+ bg_add(body->bg,imageundermouse,0); /* to prioritise loading this image */ |
|
788 | 796 |
for(;k<dirdata->listing.usedelems;k++) { |
789 | 797 |
elem=dirdata->listing.elems+k; |
790 | 798 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
... | ... |
@@ -1124,11 +1132,15 @@ texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg) |
1124 | 1132 |
texture->has_texture=0; |
1125 | 1133 |
texture->has_failedload=0; |
1126 | 1134 |
} |
1127 |
- texture->currentpath[0]='\0'; |
|
1128 | 1135 |
if(bg!=NULL && (bgload=bg_get(bg,texture->currentpath))!=NULL && bgload->has_data!=0) { |
1129 | 1136 |
im=ImageCopy(bgload->image); |
1130 | 1137 |
} else { |
1138 |
+#if 0 |
|
1139 |
+#warning TEST CODE |
|
1140 |
+ return(-1); /* if not loaded in background, return -1 to indicate "not ready" */ |
|
1141 |
+#else |
|
1131 | 1142 |
im=global_loadimage(fullpath); |
1143 |
+#endif |
|
1132 | 1144 |
} |
1133 | 1145 |
if(IsImageValid(im)) { |
1134 | 1146 |
imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
... | ... |
@@ -35,7 +35,7 @@ |
35 | 35 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
36 | 36 |
#define WHEELSTEP LEFTIMAGESIDELEN |
37 | 37 |
#define SEP '/' |
38 |
-#define SIZEBGLOAD 256 |
|
38 |
+#define SIZEBGLOAD (3*((DEFAULTWIDTH+(LEFTIMAGESIDELEN-1))/LEFTIMAGESIDELEN)*((DEFAULTHEIGHT+(LEFTIMAGESIDELEN-1))/LEFTIMAGESIDELEN)) |
|
39 | 39 |
#define DEFAULTDIRDATAHEIGHT 492 |
40 | 40 |
#define ADDREMOVEDIRDATAHEIGHT 128 |
41 | 41 |
#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
... | ... |
@@ -45,7 +45,13 @@ |
45 | 45 |
#define BLOCKDIRDATA 16 |
46 | 46 |
|
47 | 47 |
#define MYFUNC "UNKNOWN" |
48 |
+#if 0 |
|
48 | 49 |
#define IMDEBUG(a) fprintf(stderr,"%s:%i: %s: %s\n",__FILE__,__LINE__,MYFUNC,a) |
50 |
+#define IMDEBUG2(a) fprintf(stderr,"%s:%i: %s: ",__FILE__,__LINE__,MYFUNC),fprintf a |
|
51 |
+#else |
|
52 |
+#define IMDEBUG(a) |
|
53 |
+#define IMDEBUG2(a) |
|
54 |
+#endif |
|
49 | 55 |
|
50 | 56 |
// RIGHTSIDEMARGIN=FONTBIGSIZE/2 |
51 | 57 |
|
... | ... |
@@ -495,6 +501,7 @@ im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowhe |
495 | 501 |
int xoff,yoff; |
496 | 502 |
thumb_t *thumb; |
497 | 503 |
char statustooltip[1024]; |
504 |
+ char imageundermouse[1024]; |
|
498 | 505 |
thumb_t *selectedthumb; |
499 | 506 |
IMDEBUG("Pre-sanitycheck"); |
500 | 507 |
if(body==NULL) |
... | ... |
@@ -549,18 +556,15 @@ im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowhe |
549 | 556 |
rayui_scrollablerectadd(body->rayui,mousedata,&whxy,"body.leftside",body->dirdata[body->currentdirdata]->leftscrollpos,(int (*)(void *, Vector2))im_body_tryselect,body,SCROLLTHRESHOLD); |
550 | 557 |
} |
551 | 558 |
DrawRectangle(body->whxy.x,body->whxy.y,body->leftsize, body->whxy.h, (Color){ 215, 215, 215, 255 } ); |
552 |
-fprintf(stderr,"%ix%i+%i+%i\n",body->leftsize, body->whxy.h,body->whxy.x,body->whxy.y); |
|
559 |
+ IMDEBUG2((stderr,"%ix%i+%i+%i\n",body->leftsize, body->whxy.h,body->whxy.x,body->whxy.y)); |
|
553 | 560 |
/* draw right side background */ |
554 |
-#if 1 |
|
555 |
-fprintf(stderr,"body->whxy:%ix%i+%i+%i\n",UNROLLWHXY(body->whxy)); |
|
556 |
-fprintf(stderr,"body->leftsize:%i\n",body->leftsize); |
|
557 |
-#endif |
|
561 |
+ IMDEBUG2((stderr,"body->whxy:%ix%i+%i+%i\n",UNROLLWHXY(body->whxy))); |
|
562 |
+ IMDEBUG2((stderr,"body->leftsize:%i\n",body->leftsize)); |
|
558 | 563 |
IMDEBUG("draw right bg"); |
559 | 564 |
DrawRectangle(body->whxy.x+body->leftsize,body->whxy.y,body->whxy.w-body->leftsize, body->whxy.h, (Color){ 227, 227, 227, 255 } ); |
560 |
-fprintf(stderr,"DrawRectangle(body->whxy.x(%i)+body->leftsize(%i),body->whxy.y(%i),body->whxy.w(%i)-body->leftsize(%i), body->whxy.h(%i), (Color){ 227, 227, 227, 255 } );\n" |
|
561 |
- ,body->whxy.x,body->leftsize,body->whxy.y,body->whxy.w,body->leftsize, body->whxy.h); |
|
562 |
- |
|
563 |
-fprintf(stderr,"%ix%i+%i+%i\n",body->whxy.w-body->leftsize, body->whxy.h,body->whxy.x+body->leftsize,body->whxy.y); |
|
565 |
+ IMDEBUG2((stderr,"DrawRectangle(body->whxy.x(%i)+body->leftsize(%i),body->whxy.y(%i),body->whxy.w(%i)-body->leftsize(%i), body->whxy.h(%i), (Color){ 227, 227, 227, 255 } );\n" |
|
566 |
+ ,body->whxy.x,body->leftsize,body->whxy.y,body->whxy.w,body->leftsize, body->whxy.h)); |
|
567 |
+ IMDEBUG2((stderr,"%ix%i+%i+%i\n",body->whxy.w-body->leftsize, body->whxy.h,body->whxy.x+body->leftsize,body->whxy.y)); |
|
564 | 568 |
/* reset lazy load marks */ |
565 | 569 |
bg_resetmarks(body->bg); |
566 | 570 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
... | ... |
@@ -648,6 +652,7 @@ DrawRectangle(UNROLLXYWH(body->backwhxy),((Color){ 0,255,0,255 })); /* hit zone |
648 | 652 |
FILLWHXY(thumb->screenwhxy,0,0,0,0); |
649 | 653 |
} |
650 | 654 |
/* files */ |
655 |
+ imageundermouse[0]='\0'; |
|
651 | 656 |
for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
652 | 657 |
Texture2D *te; |
653 | 658 |
whxy_t *whxy; |
... | ... |
@@ -669,6 +674,10 @@ DrawRectangle(UNROLLXYWH(body->backwhxy),((Color){ 0,255,0,255 })); /* hit zone |
669 | 674 |
/* show image */ |
670 | 675 |
has_imagedrawn=0; |
671 | 676 |
if(is_imagefilename(elem->name+1) && !(thumb->screenwhxy.y>(body->whxy.y+body->whxy.h) || (thumb->screenwhxy.y+thumb->screenwhxy.h)<body->whxy.y)) { |
677 |
+ if(is_global_insidewhxy(mousedata->mousepos,&(thumb->screenwhxy),0)) { |
|
678 |
+ snprintf(imageundermouse,sizeof(imageundermouse),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
679 |
+ imageundermouse[sizeof(imageundermouse)-1]='\0'; |
|
680 |
+ } |
|
672 | 681 |
if(thumb->has_texture==0 && thumb->has_failedload==0) { |
673 | 682 |
bgload_t *bgload; |
674 | 683 |
char fullpath[2048]; |
... | ... |
@@ -774,6 +783,8 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
774 | 783 |
selectedthumb=thumb; |
775 | 784 |
} |
776 | 785 |
} |
786 |
+ if(imageundermouse[0]!='\0') |
|
787 |
+ bg_add(body->bg,imageundermouse); /* to prioritise loading this image */ |
|
777 | 788 |
for(;k<dirdata->listing.usedelems;k++) { |
778 | 789 |
elem=dirdata->listing.elems+k; |
779 | 790 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
... | ... |
@@ -30,7 +30,8 @@ |
30 | 30 |
|
31 | 31 |
#define DEFAULTWIDTH 1280 |
32 | 32 |
#define DEFAULTHEIGHT 768 |
33 |
-#define LEFTIMAGESIDELEN 326 |
|
33 |
+//#define LEFTIMAGESIDELEN 326 |
|
34 |
+#define LEFTIMAGESIDELEN 64 |
|
34 | 35 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
35 | 36 |
#define WHEELSTEP LEFTIMAGESIDELEN |
36 | 37 |
#define SEP '/' |
... | ... |
@@ -1,40 +1,11 @@ |
1 | 1 |
/* |
2 | 2 |
* imgmover.c |
3 | 3 |
* |
4 |
- * Simple C application using raylib to move images between directories. |
|
4 |
+ * Simple C application using raylib to cselect/rotate/classify/arrange photos. |
|
5 | 5 |
* |
6 | 6 |
* History: |
7 |
- * 20250119 Creation. Menu bar. |
|
8 |
- * 20250123 Load font. |
|
9 |
- * 20250213 Support sticky drop-down menus. |
|
10 |
- * 20250216 Modularize menu handling. |
|
11 |
- * 20250222 Able to list files. |
|
12 |
- * 20250223 Draw pane titles and main dir list. |
|
13 |
- * 20250224 Draw right dir list and store elem positions. |
|
14 |
- * 20250225 Draw image placeholders |
|
15 |
- * 20250226 Fix rightside positions |
|
16 |
- * 20250228 Navigate directories |
|
17 |
- * 20250301 Aesthetic fixes for leftside. |
|
18 |
- * Basic image loading. |
|
19 |
- * Show big image on hover. |
|
20 |
- * Preserve aspect ratio of big image. |
|
21 |
- * 20250305 Scrollable left pane. |
|
22 |
- * 20250308 Show statustooltip on image hover. |
|
23 |
- * Scrollwheel support for leftside. |
|
24 |
- * Fix thumb aspect ratio. |
|
25 |
- * 20250311 Fix bug because of stray CloseWindow() call. |
|
26 |
- * Add show using all window with right button. |
|
27 |
- * 20250316 Add android target support. |
|
28 |
- * Delay loading images if over fps deadline. |
|
29 |
- * Scroll by finger. Big image on double click. |
|
30 |
- * 20250319 Add-dirdata button. |
|
31 |
- * 20250320 Fix add-dirdata button appearance. |
|
32 |
- * Dirdata colors. Select dirdata. |
|
33 |
- * 20250329 Background loading of thumbnails. |
|
34 |
- * 20250330 Refine background loading. |
|
35 |
- * 20250413 Background loading for windows target. |
|
36 |
- * 20250420 Fix background loading for windows target. |
|
37 |
- * 20250427 Start move image functionality. |
|
7 |
+ * 20250902 Rewrite using parts of old prototype. |
|
8 |
+ * 20250920 Reimplemented all scroll functionality. |
|
38 | 9 |
* |
39 | 10 |
* Author: Dario Rodriguez dario@darionomono.com |
40 | 11 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -54,152 +25,32 @@ |
54 | 25 |
#include "win32_pipe.h" |
55 | 26 |
#endif |
56 | 27 |
|
57 |
-#include "raylib.h" |
|
58 |
-#include "roboto_regular.c" |
|
28 |
+#include "rayui.h" |
|
29 |
+#include "bg.h" |
|
59 | 30 |
|
60 |
-#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
|
61 |
- |
|
62 |
-//#ifndef ANDROID |
|
63 |
-//#define SIMANDROID |
|
64 |
-//#endif |
|
65 |
- |
|
66 |
-#define TARGETFPS 30 |
|
67 |
- |
|
68 |
-#if defined(ANDROID) || defined(SIMANDROID) |
|
69 |
-#define ROOTDIR "/sdcard/" |
|
70 |
-#define DEFAULTWIDTH 2400 |
|
71 |
-#define DEFAULTHEIGHT 1080 |
|
72 |
-#define LEFTSIZE 1600 |
|
73 |
-#define DEFAULTDIRDATAHEIGHT 492 |
|
74 |
-#define DEFAULTDIRDATATRIANGLEW 100 |
|
75 |
-#define LEFTIMAGESIDELEN 326 |
|
76 |
-#define FONTSIZE 64 |
|
77 |
-#define FONTBIGSIZE 96 |
|
78 |
-#define FONTHUGESIZE 128 |
|
79 |
-#define ADDREMOVEDIRDATAHEIGHT 128 |
|
80 |
-#else |
|
81 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
82 |
-#define ROOTDIR "Z:\\" |
|
83 |
-#define SEP "\\" |
|
84 |
-#else |
|
85 |
-//#define ROOTDIR "/var/www/default/animeshot/" |
|
86 |
-#define ROOTDIR "/" |
|
87 |
-#define SEP "/" |
|
88 |
-#endif |
|
89 | 31 |
#define DEFAULTWIDTH 1280 |
90 | 32 |
#define DEFAULTHEIGHT 768 |
91 |
-#define LEFTSIZE 720 |
|
92 |
-#define DEFAULTDIRDATAHEIGHT 150 |
|
93 |
-#define DEFAULTDIRDATATRIANGLEW 35 |
|
94 |
-#define LEFTIMAGESIDELEN 125 |
|
95 |
-#define FONTSIZE 18 |
|
96 |
-#define FONTBIGSIZE 32 |
|
97 |
-#define FONTHUGESIZE 48 |
|
98 |
-#define ADDREMOVEDIRDATAHEIGHT 128 |
|
99 |
-#endif |
|
100 |
- |
|
33 |
+#define LEFTIMAGESIDELEN 326 |
|
101 | 34 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
102 |
- |
|
103 |
- |
|
104 |
-#if defined(SIMANDROID) |
|
105 |
-#undef ROOTDIR |
|
106 |
-#define ROOTDIR "/var/www/default/animeshot/" |
|
107 |
-#endif |
|
108 |
- |
|
109 | 35 |
#define WHEELSTEP LEFTIMAGESIDELEN |
110 |
- |
|
111 |
- |
|
36 |
+#define SEP '/' |
|
37 |
+#define SIZEBGLOAD 256 |
|
38 |
+#define DEFAULTDIRDATAHEIGHT 492 |
|
39 |
+#define ADDREMOVEDIRDATAHEIGHT 128 |
|
40 |
+#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
|
41 |
+#define DEFAULTDIRDATATRIANGLEW 35 |
|
112 | 42 |
#define BLOCKLISTINGBUF 2048 |
113 | 43 |
#define BLOCKLISTINGELEMS 1024 |
114 | 44 |
#define BLOCKDIRDATA 16 |
115 |
-#define SIZEBGLOAD 256 |
|
116 | 45 |
|
117 |
-#ifndef FILLXY |
|
118 |
-#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
|
119 |
-#endif |
|
46 |
+#define MYFUNC "UNKNOWN" |
|
47 |
+#define IMDEBUG(a) fprintf(stderr,"%s:%i: %s: %s\n",__FILE__,__LINE__,MYFUNC,a) |
|
120 | 48 |
|
121 |
-#ifndef FILLWH |
|
122 |
-#define FILLWH(xywh,valw,valh) (xywh).w=(valw),(xywh).h=(valh) |
|
123 |
-#endif |
|
124 |
- |
|
125 |
-#ifndef FILLXYWH |
|
126 |
-#define FILLXYWH(xywh,valx,valy,valw,valh) (xywh).x=(valx),(xywh).y=(valy),(xywh).w=(valw),(xywh).h=(valh) |
|
127 |
-#endif |
|
128 |
- |
|
129 |
-#ifndef UNROLLXYWH |
|
130 |
-#define UNROLLXYWH(xywh) (xywh).x,(xywh).y,(xywh).w,(xywh).h |
|
131 |
-#endif |
|
132 |
- |
|
133 |
-#ifndef UNROLLWHXY |
|
134 |
-#define UNROLLWHXY(xywh) (xywh).w,(xywh).h,(xywh).x,(xywh).y |
|
135 |
-#endif |
|
136 |
- |
|
137 |
-#ifndef RD |
|
138 |
-#define RD 0 |
|
139 |
-#endif |
|
140 |
- |
|
141 |
-#ifndef WR |
|
142 |
-#define WR 1 |
|
143 |
-#endif |
|
144 |
- |
|
145 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
146 |
-int MessageBoxA(void *hWnd,void *lpText,void *lpCaption,unsigned int uType); |
|
147 |
-#define messagebox(str) MessageBoxA(NULL,str,"imgmover",0); |
|
148 |
-#else |
|
149 |
-#define messagebox(str) fprintf(stderr,"%s\n",str); |
|
150 |
-#endif |
|
151 |
- |
|
152 |
- |
|
153 |
- |
|
154 |
-#if !defined(__linux__) && !defined(ANDROID) && RAYLIB_VERSION_MAJOR==5 && RAYLIB_VERSION_MINOR==0 |
|
155 |
-/* the old raylib used in the windows build lacks this function */ |
|
156 |
-bool IsImageValid(Image image) |
|
157 |
-{ |
|
158 |
- bool result = false; |
|
159 |
- |
|
160 |
- if ((image.data != NULL) && // Validate pixel data available |
|
161 |
- (image.width > 0) && // Validate image width |
|
162 |
- (image.height > 0) && // Validate image height |
|
163 |
- (image.format > 0) && // Validate image format |
|
164 |
- (image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level) |
|
165 |
- |
|
166 |
- return result; |
|
167 |
-} |
|
168 |
-#endif |
|
169 |
- |
|
170 |
-typedef struct xywh_t { |
|
171 |
- int x; |
|
172 |
- int y; |
|
173 |
- int w; |
|
174 |
- int h; |
|
175 |
-} xywh_t; |
|
176 |
- |
|
177 |
-typedef struct font_t { |
|
178 |
- Font font; |
|
179 |
- int height; |
|
180 |
-} font_t; |
|
181 |
- |
|
182 |
-typedef struct menudata_t { |
|
183 |
- char *title; |
|
184 |
- xywh_t xywh; |
|
185 |
- int sizeoptions; |
|
186 |
- char **options; |
|
187 |
- xywh_t optionsxywh; |
|
188 |
- int flag_open; |
|
189 |
- int flag_stickyopen; |
|
190 |
- int currentoption; |
|
191 |
-} menudata_t; |
|
192 |
- |
|
193 |
-typedef struct menubar_t { |
|
194 |
- int height; |
|
195 |
- int sizemenudata; |
|
196 |
- menudata_t **menudata; |
|
197 |
- font_t *ptrfont; |
|
198 |
-} menubar_t; |
|
49 |
+// RIGHTSIDEMARGIN=FONTBIGSIZE/2 |
|
199 | 50 |
|
200 | 51 |
typedef struct thumb_t { |
201 |
- xywh_t xywh; |
|
202 |
- xywh_t screenxywh; |
|
52 |
+ whxy_t whxy; |
|
53 |
+ whxy_t screenwhxy; |
|
203 | 54 |
Texture2D texture; |
204 | 55 |
int has_texture; |
205 | 56 |
int has_failedload; |
... | ... |
@@ -218,9 +69,9 @@ typedef struct listing_t { |
218 | 69 |
int sizebuf; |
219 | 70 |
int usedbuf; |
220 | 71 |
char *buf; |
221 |
- int has_leftxywh; |
|
222 |
- int has_rightxywh; |
|
223 |
- xywh_t lastleftxywh; |
|
72 |
+ int has_leftwhxy; |
|
73 |
+ int has_rightwhxy; |
|
74 |
+ whxy_t lastleftwhxy; |
|
224 | 75 |
} listing_t; |
225 | 76 |
|
226 | 77 |
typedef struct dirdata_t { |
... | ... |
@@ -237,35 +88,14 @@ typedef struct texture_t { |
237 | 88 |
int textureh; |
238 | 89 |
int has_texture; |
239 | 90 |
int has_failedload; |
240 |
- xywh_t source; /* be able to detect a "double click" */ |
|
91 |
+ whxy_t source; /* be able to detect a "double click" */ |
|
241 | 92 |
} texture_t; |
242 | 93 |
|
243 |
-typedef struct bgload_t { |
|
244 |
- /* main/thread ownership management */ |
|
245 |
- int lended_to_thread; // written from main, read from thread |
|
246 |
- int thread_finished; // written from thread, read from main |
|
247 |
- int is_todo; // written from main, read from thread |
|
248 |
- int has_mark; // written/read from main |
|
249 |
- /* data only accessed from owner */ |
|
250 |
- char path[1024]; // to use only from owner |
|
251 |
- Image image; // to use only from owner |
|
252 |
- int has_data; // to use only from owner |
|
253 |
- int has_failedload; // to use only from owner |
|
254 |
-} bgload_t; |
|
255 |
- |
|
256 |
-typedef struct bg_t { |
|
257 |
- int sizebgload; |
|
258 |
- bgload_t *bgload; |
|
259 |
- int pipe[2]; |
|
260 |
- pthread_t thread; |
|
261 |
- pthread_attr_t tattr; |
|
262 |
- int flag_threadstarted; |
|
263 |
-} bg_t; |
|
264 |
- |
|
265 | 94 |
typedef struct body_t { |
95 |
+ rayui_t *rayui; |
|
266 | 96 |
char *rootdir; |
267 |
- xywh_t xywh; |
|
268 |
- xywh_t backxywh; |
|
97 |
+ whxy_t whxy; |
|
98 |
+ whxy_t backwhxy; |
|
269 | 99 |
int leftsize; |
270 | 100 |
int sizedirdata; |
271 | 101 |
dirdata_t **dirdata; |
... | ... |
@@ -278,223 +108,74 @@ typedef struct body_t { |
278 | 108 |
int is_displayingtexture; |
279 | 109 |
texture_t bigtexture; |
280 | 110 |
int flag_drawbigtexture; |
281 |
- xywh_t dirdataadd; |
|
111 |
+ whxy_t dirdataadd; |
|
282 | 112 |
Font roundedbox; |
283 | 113 |
bg_t *bg; |
284 | 114 |
char selectedpath[2048]; |
285 | 115 |
} body_t; |
286 | 116 |
|
117 |
+ |
|
287 | 118 |
typedef struct im_t { |
288 |
- int windowinit; |
|
289 |
- int w; |
|
290 |
- int h; |
|
291 |
- menubar_t *menubar; |
|
119 |
+ rayui_t *rayui; |
|
120 |
+ mousedata_t mousedata; |
|
292 | 121 |
body_t *body; |
293 |
- font_t *font; |
|
294 |
- font_t *fontbig; |
|
295 |
- font_t *fonthuge; |
|
296 | 122 |
} im_t; |
297 | 123 |
|
298 |
- |
|
299 |
-im_t *im_init(char *menus, char *rootdir); |
|
124 |
+im_t *im_init(char *rootdir); |
|
300 | 125 |
void im_free(im_t *im); |
301 | 126 |
|
302 |
-font_t *im_font_init(int size); |
|
303 |
-void im_font_free(font_t *font); |
|
304 |
- |
|
305 |
-menubar_t *im_menubar_init(char *menus, font_t *font); |
|
306 |
-void im_menubar_free(menubar_t *menubar); |
|
307 |
- |
|
308 |
-int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
|
309 |
-int im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight, int *needs_nextredraw); |
|
310 |
- |
|
311 |
-body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight); |
|
127 |
+body_t *im_body_init(rayui_t *rayui, int w, int h, int x, int y, int leftsidesize, char *rootdir); |
|
312 | 128 |
void im_body_free(body_t *body); |
313 | 129 |
|
314 | 130 |
int im_body_add(body_t *body,char *dir); |
315 | 131 |
int im_body_tryselect(body_t *body, Vector2 mousepos); |
316 | 132 |
|
133 |
+int im_body_mouse(body_t *body, mousedata_t *mousedata); |
|
134 |
+int im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowheight, int *needs_nextredraw); |
|
317 | 135 |
|
318 |
-int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
|
319 |
-int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw, int scrollspeed); |
|
320 |
- |
|
136 |
+static int strptrcmp(void *a,void *b); |
|
321 | 137 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
322 | 138 |
void listing_freedata(listing_t *listing); |
323 |
-int listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_left); |
|
139 |
+int listing_fillwhxy(listing_t *listing, font_t *font, int w, int sidelen, int is_left, int rightsidemargin); |
|
140 |
+ |
|
141 |
+int is_imagefilename(char *filename); |
|
324 | 142 |
|
325 | 143 |
int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg); |
326 | 144 |
int texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh); |
327 | 145 |
int texture_freedata(texture_t *texture); |
328 | 146 |
|
329 |
-int imutil_menu_count(char *menus); |
|
330 |
-char *imutil_menu_get(char *menus, int targetn, int *len); |
|
331 |
-int imutil_submenu_count(char *menus); |
|
332 |
-char *imutil_submenu_get(char *menus, int targetn, int *len); |
|
333 |
-char *imutil_strduplen(char *str, int len); |
|
334 |
-int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin); |
|
335 | 147 |
int imutil_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh); |
336 |
-int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
|
337 |
-int *getcodepoints(int *sizecodepoints); |
|
338 |
-int is_imagefilename(char *filename); |
|
339 |
-Image imutil_loadimage(const char *filename); |
|
340 |
-void imutil_fpsreset(void); |
|
341 |
-int imutil_fpsleft(void); |
|
342 |
-long long imutil_milliseconds(void); |
|
343 |
- |
|
344 |
-bg_t *bg_init(int sizebgload); |
|
345 |
-void bg_free(bg_t *bg); |
|
346 |
-int bg_resetmarks(bg_t *bg); |
|
347 |
-bgload_t *bg_get(bg_t *bg, char *path); |
|
348 |
-int bg_add(bg_t *bg, char *path); |
|
349 |
-int bg_freeunmarked(bg_t *bg); |
|
350 | 148 |
|
351 |
-void *bg_thread(void *); |
|
352 |
- |
|
353 |
-static int mypipe(int fds[2]); |
|
354 |
-static int mypiperead(int fd, char *buf, int count); |
|
355 |
-static int mypipewrite(int fd, char *buf, int count); |
|
356 | 149 |
|
357 | 150 |
int |
358 | 151 |
main(int argc, char *argv[]) |
359 | 152 |
{ |
360 | 153 |
im_t *im; |
361 |
- Vector2 mousepos,wheel,oldmousepos,scrollstartpos; |
|
362 |
- int flag_ignorelmb; |
|
363 |
- int lmbpressed,lmbreleased,lmbdown,rmbdown,oldlmbdown,oldrmbdown; |
|
364 |
- int click_avail; |
|
365 |
- int has_mousechanges; |
|
154 |
+ char *rootdir; |
|
366 | 155 |
int needs_nextredraw; |
367 |
- long long scrollstart; |
|
368 |
- long long scrolllast; |
|
369 |
- int scrollspeed; |
|
370 |
- int is_scrolling; |
|
371 |
- int leftscrollposstart; |
|
372 |
- char *sel_menu,*sel_submenu; |
|
373 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
374 |
- win32pipe_init(); |
|
375 |
-#endif |
|
376 |
- if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
|
377 |
- messagebox("Couldn't init interface"); |
|
156 |
+ if(argc<2 || strcmp(argv[argc-1],"--help")==0) { |
|
157 |
+ global_messagebox("imgmover\n\nSyntax: %s <rootdirectory>\n",(argc>0)?argv[0]:"imgmover"); |
|
158 |
+ return(1); |
|
159 |
+ } |
|
160 |
+ rootdir=argv[1]; |
|
161 |
+ bg_staticinit(); |
|
162 |
+ if((im=im_init(rootdir))==NULL) { |
|
163 |
+ global_messagebox("%s","Couldn't init"); |
|
378 | 164 |
return(1); |
379 | 165 |
} |
380 |
- flag_ignorelmb=0; |
|
381 |
- mousepos=(Vector2) {.x=0,.y=0}; |
|
382 |
- lmbdown=rmbdown=-1; |
|
383 |
- needs_nextredraw=1; |
|
384 |
- scrollstart=0; |
|
385 |
- is_scrolling=0; |
|
386 |
- im->body->selectedpath[0]='\0'; |
|
387 | 166 |
while(!WindowShouldClose()) { |
388 |
- imutil_fpsreset(); |
|
389 |
- oldmousepos=mousepos; |
|
390 |
- mousepos=GetMousePosition(); |
|
391 |
- wheel=GetMouseWheelMoveV(); |
|
392 |
- lmbpressed=IsMouseButtonPressed(0); |
|
393 |
- lmbreleased=IsMouseButtonReleased(0); |
|
394 |
- oldlmbdown=lmbdown; |
|
395 |
- lmbdown=IsMouseButtonDown(0); |
|
396 |
- oldrmbdown=rmbdown; |
|
397 |
- rmbdown=IsMouseButtonDown(1); |
|
398 |
- click_avail=1; |
|
399 |
- has_mousechanges=(lmbdown!=oldlmbdown || rmbdown!=oldrmbdown || mousepos.x!=oldmousepos.x || mousepos.y!=oldmousepos.y || wheel.x!=0 || wheel.y!=0)?1:0; |
|
167 |
+ rayui_timereset(im->rayui); |
|
400 | 168 |
needs_nextredraw=0; |
401 |
- /* mouse process scrolling */ |
|
402 |
- if(lmbdown==1 && oldlmbdown==0 && scrollstart==0 && mousepos.y>im->body->xywh.y) { |
|
403 |
- scrollstart=imutil_milliseconds(); |
|
404 |
- scrollstartpos=mousepos; |
|
405 |
- leftscrollposstart=im->body->dirdata[im->body->currentdirdata]->leftscrollpos; |
|
406 |
- } |
|
407 |
- if(scrollstart!=0 && lmbdown==0) { |
|
408 |
- scrollstart=0; |
|
409 |
- if(is_scrolling) |
|
410 |
- click_avail=0; /* this click is the mouseup of the scroll */ |
|
411 |
- } |
|
412 |
- is_scrolling=(scrollstart==0)?0:is_scrolling; |
|
413 |
- if(is_scrolling==0 && scrollstart!=0) { |
|
414 |
- float t; |
|
415 |
- t=scrollstartpos.y-mousepos.y; |
|
416 |
- t=(t<0)?-t:t; |
|
417 |
- if(t>SCROLLTHRESHOLD) { |
|
418 |
- is_scrolling=1; |
|
419 |
- scrolllast=0; |
|
420 |
- } |
|
421 |
- t=scrollstartpos.x-mousepos.x; |
|
422 |
- t=(t<0)?-t:t; |
|
423 |
- if(t>SCROLLTHRESHOLD) { |
|
424 |
- is_scrolling=0,scrollstart=0; |
|
425 |
- im_body_tryselect(im->body,scrollstartpos); |
|
426 |
- if(im->body->selectedpath[0]!='\0') |
|
427 |
- click_avail=0; |
|
428 |
- } |
|
429 |
- } |
|
430 |
- if(is_scrolling) { |
|
431 |
- long long tcur,tdif; |
|
432 |
- long long ycur; |
|
433 |
- tcur=imutil_milliseconds(); |
|
434 |
- tdif=tcur-scrolllast; |
|
435 |
- ycur=scrollstartpos.y-mousepos.y; |
|
436 |
- scrollspeed=(tdif>0)?(oldmousepos.y-mousepos.y)*100000/tdif:0; |
|
437 |
- im->body->dirdata[im->body->currentdirdata]->leftscrollpos=leftscrollposstart+ycur; |
|
438 |
- scrolllast=tcur; |
|
439 |
- } |
|
440 |
- if(is_scrolling==0 && scrollspeed!=0) { |
|
441 |
- scrollspeed=scrollspeed*4/5; |
|
442 |
- im->body->dirdata[im->body->currentdirdata]->leftscrollpos+=scrollspeed; |
|
443 |
- } |
|
444 |
- /* mouse process clicks on menus */ |
|
445 |
- if(click_avail) { |
|
446 |
- sel_menu=sel_submenu=NULL; |
|
447 |
- im_menubar_mouse(im->menubar, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail, &sel_menu, &sel_submenu); |
|
448 |
- if(sel_menu!=NULL && sel_submenu!=NULL) { |
|
449 |
- |
|
450 |
-#if 1 |
|
451 |
-fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
|
452 |
-#endif |
|
453 |
- if(strcmp(sel_submenu,"Salir")==0) |
|
454 |
- break; /* exit from main loop */ |
|
455 |
- } |
|
456 |
- } |
|
457 |
- if(click_avail) |
|
458 |
- im_body_mouse(im->body, mousepos, wheel, lmbpressed, lmbreleased, lmbdown, &click_avail); |
|
169 |
+ rayui_getmousedata(im->rayui,&(im->mousedata)); |
|
170 |
+ /* process mouse actions */ |
|
171 |
+ if(im->mousedata.click_avail) |
|
172 |
+ im_body_mouse(im->body, &(im->mousedata)); |
|
459 | 173 |
/* draw screen contents */ |
460 | 174 |
BeginDrawing(); |
461 | 175 |
ClearBackground(RAYWHITE); |
462 |
- im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h,&needs_nextredraw,scrollspeed); |
|
463 |
- im_menubar_draw(im->menubar,im->w,im->h,&needs_nextredraw); |
|
464 |
-#if 0 |
|
465 |
-{ |
|
466 |
- int i,j; |
|
467 |
- Vector2 v2; |
|
468 |
- listing_t listing={0}; |
|
469 |
- if(listing_get(&listing,"..",".",1)==0) { |
|
470 |
- i=2; |
|
471 |
- v2.x=(float) (im->font->height/2); |
|
472 |
- v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
|
473 |
- DrawTextEx(im->font->font |
|
474 |
- ,SEP |
|
475 |
- ,v2 |
|
476 |
- ,im->font->height |
|
477 |
- ,0 |
|
478 |
- ,((Color){ 45, 45, 45, 255 }) |
|
479 |
- ); |
|
480 |
- for(j=0;j<listing.usedelems;j++) { |
|
481 |
- Color c; |
|
482 |
- i++; |
|
483 |
- c=((Color){ 45, 45, 45, 255 }); |
|
484 |
- v2.x=(float) (im->font->height/2); |
|
485 |
- v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
|
486 |
- DrawTextEx(im->font->font |
|
487 |
- ,listing.elems[j].name |
|
488 |
- ,v2 |
|
489 |
- ,im->font->height |
|
490 |
- ,0 |
|
491 |
- ,c |
|
492 |
- ); |
|
493 |
- } |
|
494 |
- } |
|
495 |
-} |
|
496 |
-#endif |
|
497 |
- if(has_mousechanges==0 && needs_nextredraw==0 && scrollspeed==0) { |
|
176 |
+ rayui_scrollablerectreset(im->rayui,&(im->mousedata)); |
|
177 |
+ im_body_draw(im->body,&(im->mousedata),im->rayui->w,im->rayui->h,&needs_nextredraw); |
|
178 |
+ if(needs_nextredraw==0 && im->mousedata.has_mousechanges==0 && im->mousedata.scrollspeed==0) { |
|
498 | 179 |
/* Wait for new events when calling EndDrawing() */ |
499 | 180 |
EnableEventWaiting(); |
500 | 181 |
} else { |
... | ... |
@@ -504,39 +185,26 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
504 | 185 |
EndDrawing(); |
505 | 186 |
} |
506 | 187 |
im_free(im),im=NULL; |
507 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
508 |
- win32pipe_fini(); |
|
509 |
-#endif |
|
188 |
+ bg_staticfini(); |
|
510 | 189 |
return(0); |
511 | 190 |
} |
512 | 191 |
|
192 |
+ |
|
513 | 193 |
im_t * |
514 |
-im_init(char *menus, char *rootdir) |
|
194 |
+im_init(char *rootdir) |
|
515 | 195 |
{ |
516 | 196 |
im_t *im; |
517 | 197 |
char *errstr; |
518 |
- if(menus==NULL) |
|
519 |
- return(NULL); /* sanity check failed */ |
|
520 | 198 |
if((im=calloc(1,sizeof(im_t)))==NULL) { |
521 | 199 |
im_free(im),im=NULL; |
522 | 200 |
return(NULL); /* insuf. mem. */ |
523 | 201 |
} |
524 |
- /* init window */ |
|
525 |
- SetTraceLogLevel(LOG_ERROR); |
|
526 |
- InitWindow((im->w=DEFAULTWIDTH),(im->h=DEFAULTHEIGHT),"Image Mover"); |
|
527 |
- im->windowinit=1; |
|
528 |
- SetTargetFPS(30); |
|
529 |
- /* init fonts and contents */ |
|
530 |
- if((errstr="Couldn't init font")==NULL |
|
531 |
- || (im->font=im_font_init(FONTSIZE))==NULL |
|
532 |
- || (im->fontbig=im_font_init(FONTBIGSIZE))==NULL |
|
533 |
- || (im->fonthuge=im_font_init(FONTHUGESIZE))==NULL |
|
534 |
- || (errstr="Couldn't init menus")==NULL |
|
535 |
- || (im->menubar=im_menubar_init(menus,im->font))==NULL |
|
202 |
+ if((errstr="init interface")==NULL |
|
203 |
+ || (im->rayui=rayui_init(DEFAULTWIDTH,DEFAULTHEIGHT,"Image Mover",NULL))==NULL |
|
536 | 204 |
|| (errstr="Couldn't init interface data")==NULL |
537 |
- || (im->body=im_body_init(0,im->menubar->height, im->font, im->fontbig, im->fonthuge, LEFTSIZE, rootdir,im->w,im->h))==NULL |
|
205 |
+ || (im->body=im_body_init(im->rayui,im->rayui->w,im->rayui->h, 0, 0, im->rayui->w*2/3, rootdir))==NULL |
|
538 | 206 |
) { |
539 |
- messagebox(errstr); |
|
207 |
+ global_messagebox("Couldn't %s",errstr); |
|
540 | 208 |
im_free(im),im=NULL; |
541 | 209 |
return(NULL); /* insuf. mem. */ |
542 | 210 |
} |
... | ... |
@@ -550,299 +218,21 @@ im_free(im_t *im) |
550 | 218 |
{ |
551 | 219 |
if(im==NULL) |
552 | 220 |
return; |
553 |
- if(im->menubar!=NULL) |
|
554 |
- im_menubar_free(im->menubar),im->menubar=NULL; |
|
555 | 221 |
if(im->body!=NULL) |
556 | 222 |
im_body_free(im->body),im->body=NULL; |
557 |
- if(im->font!=NULL) |
|
558 |
- im_font_free(im->font),im->font=NULL; |
|
559 |
- if(im->fontbig!=NULL) |
|
560 |
- im_font_free(im->fontbig),im->fontbig=NULL; |
|
561 |
- if(im->fonthuge!=NULL) |
|
562 |
- im_font_free(im->fonthuge),im->fonthuge=NULL; |
|
563 |
- if(im->windowinit) |
|
564 |
- CloseWindow(),im->windowinit=0; |
|
223 |
+ if(im->rayui!=NULL) |
|
224 |
+ rayui_free(im->rayui),im->rayui=NULL; |
|
565 | 225 |
free(im),im=NULL; |
566 |
- return; |
|
567 |
-} |
|
568 |
- |
|
569 |
-font_t * |
|
570 |
-im_font_init(int size) |
|
571 |
-{ |
|
572 |
- font_t *font; |
|
573 |
- int sizecodepoints; |
|
574 |
- int *codepoints; |
|
575 |
- if((font=calloc(1,sizeof(font_t)))==NULL) |
|
576 |
- return(NULL); /* insuf. mem. */ |
|
577 |
- font->height=size; |
|
578 |
- codepoints=getcodepoints(&sizecodepoints); |
|
579 |
- font->font=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,font->height,codepoints,sizecodepoints); |
|
580 |
- return(font); |
|
581 |
-} |
|
582 |
- |
|
583 |
-void |
|
584 |
-im_font_free(font_t *font) |
|
585 |
-{ |
|
586 |
- if(font==NULL) |
|
587 |
- return; |
|
588 |
- /* NOTE: Cannot call UnloadFont(font->font) as the data was not malloc'd; see https://github.com/raysan5/raylib/blob/master/examples/others/embedded_files_loading.c */ |
|
589 |
- free(font),font=NULL; |
|
590 |
- return; |
|
591 |
-} |
|
592 |
- |
|
593 |
-menubar_t * |
|
594 |
-im_menubar_init(char *menus, font_t *font) |
|
595 |
-{ |
|
596 |
- int i,j; |
|
597 |
- char *str,*substr; |
|
598 |
- int len,sublen; |
|
599 |
- menubar_t *menubar; |
|
600 |
- menudata_t *menudata; |
|
601 |
- if(menus==NULL || font==NULL) |
|
602 |
- return(NULL); /* sanity check failed */ |
|
603 |
- if((menubar=calloc(1,sizeof(menubar_t)))==NULL |
|
604 |
- || (menubar->sizemenudata=imutil_menu_count(menus))<=0 |
|
605 |
- || (menubar->menudata=calloc(menubar->sizemenudata,sizeof(menudata_t)))==NULL |
|
606 |
- ) { |
|
607 |
- im_menubar_free(menubar),menubar=NULL; |
|
608 |
- return(NULL); /* insuf. mem. */ |
|
609 |
- } |
|
610 |
- menubar->ptrfont=font; |
|
611 |
- menubar->height=font->height+font->height/2; |
|
612 |
- /* init menus */ |
|
613 |
- for(i=0;i<menubar->sizemenudata;i++) { |
|
614 |
- if((menudata=menubar->menudata[i]=calloc(1,sizeof(menudata_t)))==NULL |
|
615 |
- || (str=imutil_menu_get(menus,i,&len))==NULL |
|
616 |
- || (menudata->title=imutil_strduplen(str,len))==NULL |
|
617 |
- || (menudata->sizeoptions=imutil_submenu_count(str))<=0 |
|
618 |
- || (menudata->options=calloc(menudata->sizeoptions,sizeof(char *)))==NULL |
|
619 |
- ) { |
|
620 |
- im_menubar_free(menubar),menubar=NULL; |
|
621 |
- return(NULL); /* insuf. mem. */ |
|
622 |
- } |
|
623 |
- for(j=0;j<menudata->sizeoptions;j++) { |
|
624 |
- if((substr=imutil_submenu_get(str,j,&sublen))==NULL |
|
625 |
- || (menudata->options[j]=imutil_strduplen(substr,sublen))==NULL |
|
626 |
- ) { |
|
627 |
- im_menubar_free(menubar),menubar=NULL; |
|
628 |
- return(NULL); /* insuf. mem. */ |
|
629 |
- } |
|
630 |
- } |
|
631 |
- } |
|
632 |
-#if 0 |
|
633 |
- /* test imutil_menu_xxx */ |
|
634 |
- int n,m,l,ml,len,mlen; |
|
635 |
- char *ptr,*mptr; |
|
636 |
- for(n=0,l=imutil_menu_count(menus);n<l;n++) { |
|
637 |
- ptr=imutil_menu_get(menus,n,&len); |
|
638 |
- fprintf(stderr,"menu[%i]:\"",n); |
|
639 |
- fwrite(ptr,1,len,stderr); |
|
640 |
- fprintf(stderr,"\"->"); |
|
641 |
- for(m=0,ml=imutil_submenu_count(ptr);m<ml;m++) { |
|
642 |
- mptr=imutil_submenu_get(ptr,m,&mlen); |
|
643 |
- fprintf(stderr,"|\""); |
|
644 |
- fwrite(mptr,1,mlen,stderr); |
|
645 |
- fprintf(stderr,"\""); |
|
646 |
- } |
|
647 |
- fprintf(stderr,"\n"); |
|
648 |
- } |
|
649 |
-#endif |
|
650 |
-#if 0 |
|
651 |
- /* test menudata */ |
|
652 |
- for(i=0;i<menubar->sizemenudata;i++) { |
|
653 |
- fprintf(stderr,"menu[%i]:\"%s\"->",i,menubar->menudata[i]->title); |
|
654 |
- for(j=0;j<menubar->menudata[i]->sizeoptions;j++) |
|
655 |
- fprintf(stderr,"|\"%s\"",menubar->menudata[i]->options[j]); |
|
656 |
- fprintf(stderr,"\n"); |
|
657 |
- } |
|
658 |
-#endif |
|
659 |
- return(menubar); |
|
660 |
-} |
|
661 |
- |
|
662 |
-void |
|
663 |
-im_menubar_free(menubar_t *menubar) |
|
664 |
-{ |
|
665 |
- int i,j; |
|
666 |
- menudata_t *menudata; |
|
667 |
- if(menubar==NULL) |
|
668 |
- return; |
|
669 |
- if(menubar->menudata!=NULL) { |
|
670 |
- for(i=0;i<menubar->sizemenudata;i++) { |
|
671 |
- if((menudata=menubar->menudata[i])==NULL) |
|
672 |
- continue; |
|
673 |
- if(menudata->title!=NULL) |
|
674 |
- free(menudata->title),menudata->title=NULL; |
|
675 |
- if(menudata->options!=NULL) { |
|
676 |
- for(j=0;j<menudata->sizeoptions;j++) { |
|
677 |
- if(menudata->options[j]!=NULL) |
|
678 |
- free(menudata->options[j]),menudata->options[j]=NULL; |
|
679 |
- } |
|
680 |
- free(menudata->options),menudata->options=NULL,menudata->sizeoptions=0; |
|
681 |
- } |
|
682 |
- free(menubar->menudata[i]),menubar->menudata[i]=NULL,menudata=NULL; |
|
683 |
- } |
|
684 |
- free(menubar->menudata),menubar->menudata=NULL,menubar->sizemenudata=0; |
|
685 |
- } |
|
686 |
- free(menubar),menubar=NULL; |
|
687 |
- return; |
|
688 |
-} |
|
689 |
- |
|
690 |
-int |
|
691 |
-im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu) |
|
692 |
-{ |
|
693 |
- int flag_outsideall; |
|
694 |
- int i,j; |
|
695 |
- if(menubar==NULL || click_avail==NULL || sel_menu==NULL || sel_submenu==NULL) |
|
696 |
- return(-1); |
|
697 |
- *click_avail=1; |
|
698 |
- *sel_menu=NULL; |
|
699 |
- *sel_submenu=NULL; |
|
700 |
- flag_outsideall=1; |
|
701 |
-#if 0 |
|
702 |
-if(lmbpressed || lmbdown) |
|
703 |
- fprintf(stderr,"in_menubar_mouse: lmbpressed:%i lmbdown:%i\n",lmbpressed,lmbdown); |
|
704 |
-#endif |
|
705 |
- for(i=0;i<menubar->sizemenudata;i++) { |
|
706 |
- int insidetitle,currentoption; |
|
707 |
- insidetitle=is_imutil_insidexywh(mousepos,&(menubar->menudata[i]->xywh),0); |
|
708 |
- currentoption=menudata_pos2option(menubar->menudata[i],mousepos); |
|
709 |
- flag_outsideall=(currentoption!=-1 || insidetitle)?0:flag_outsideall; |
|
710 |
- if(lmbreleased && insidetitle) { |
|
711 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
712 |
- menubar->menudata[j]->flag_stickyopen=(j==i)?1:0; |
|
713 |
- menubar->menudata[j]->flag_open=0; |
|
714 |
- menubar->menudata[j]->currentoption=-1; |
|
715 |
- } |
|
716 |
- } else if((lmbpressed || lmbdown) && insidetitle) { |
|
717 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
718 |
- menubar->menudata[j]->flag_open=(j==i)?1:0; |
|
719 |
- menubar->menudata[j]->flag_stickyopen=0; |
|
720 |
- menubar->menudata[j]->currentoption=-1; |
|
721 |
- } |
|
722 |
- } else if((lmbdown || menubar->menudata[i]->flag_stickyopen) && currentoption!=-1) { |
|
723 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
724 |
- if(lmbreleased==0 || j!=i || menubar->menudata[i]->flag_stickyopen==0) { |
|
725 |
- menubar->menudata[j]->flag_open=(j==i)?menubar->menudata[i]->flag_open:0; |
|
726 |
- menubar->menudata[j]->flag_stickyopen=(j==i)?menubar->menudata[i]->flag_stickyopen:0; |
|
727 |
- menubar->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
728 |
- } else { |
|
729 |
- menubar->menudata[j]->flag_open=0; |
|
730 |
- menubar->menudata[j]->flag_stickyopen=0; |
|
731 |
- menubar->menudata[j]->currentoption=-1; |
|
732 |
- /* has selected this submenu */ |
|
733 |
- *click_avail=0; |
|
734 |
- *sel_menu=menubar->menudata[j]->title; |
|
735 |
- *sel_submenu=menubar->menudata[j]->options[currentoption]; |
|
736 |
- } |
|
737 |
- } |
|
738 |
- } else if(menubar->menudata[i]->flag_stickyopen && currentoption==-1) { |
|
739 |
- if(lmbreleased) { |
|
740 |
- menubar->menudata[i]->flag_open=0; |
|
741 |
- menubar->menudata[i]->flag_stickyopen=0; |
|
742 |
- } |
|
743 |
- menubar->menudata[i]->currentoption=-1; |
|
744 |
- } else if(lmbreleased && currentoption!=-1) { |
|
745 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
746 |
- menubar->menudata[j]->flag_open=0; |
|
747 |
- menubar->menudata[j]->flag_stickyopen=0; |
|
748 |
- menubar->menudata[j]->currentoption=-1; |
|
749 |
- } |
|
750 |
- /* has selected this submenu */ |
|
751 |
- *click_avail=0; |
|
752 |
- *sel_menu=menubar->menudata[i]->title; |
|
753 |
- *sel_submenu=menubar->menudata[i]->options[currentoption]; |
|
754 |
- } else if(lmbdown==0) { |
|
755 |
- menubar->menudata[i]->flag_open=0; |
|
756 |
- menubar->menudata[i]->flag_stickyopen=0; |
|
757 |
- menubar->menudata[i]->currentoption=-1; |
|
758 |
- } |
|
759 |
- } |
|
760 |
- if(flag_outsideall) { |
|
761 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
762 |
- menubar->menudata[j]->currentoption=-1; |
|
763 |
- } |
|
764 |
- } |
|
765 |
- /* update click_avail */ |
|
766 |
- for(j=0;j<menubar->sizemenudata;j++) { |
|
767 |
- if(menubar->menudata[j]->flag_open || menubar->menudata[j]->flag_stickyopen) { |
|
768 |
- *click_avail=0; |
|
769 |
- break; |
|
770 |
- } |
|
771 |
- } |
|
772 |
- return(0); |
|
773 |
-} |
|
774 |
- |
|
775 |
-int |
|
776 |
-im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight, int *needs_nextredraw) |
|
777 |
-{ |
|
778 |
- int i,j,k,x; |
|
779 |
- menudata_t *menudata; |
|
780 |
- font_t *font; |
|
781 |
- if(menubar==NULL) |
|
782 |
- return(-1); /* sanity check failed */ |
|
783 |
- font=menubar->ptrfont; |
|
784 |
- DrawRectangle(0,0,windowwidth, font->height+font->height/2, (Color){ 235, 235, 235, 235 } ); |
|
785 |
- for(i=0,x=0;i<menubar->sizemenudata;i++) { |
|
786 |
- Vector2 v2; |
|
787 |
- menudata=menubar->menudata[i]; |
|
788 |
- v2=MeasureTextEx(font->font,menudata->title,font->height,0); |
|
789 |
- FILLXYWH(menudata->xywh,x,0,((int)v2.x)+font->height,font->height+font->height/2); |
|
790 |
- v2.x=(float) (menudata->xywh.x+font->height/2); |
|
791 |
- v2.y=(float) (menudata->xywh.y+font->height/4); |
|
792 |
- DrawTextEx(font->font |
|
793 |
- ,menudata->title |
|
794 |
- ,v2 |
|
795 |
- ,font->height |
|
796 |
- ,0 |
|
797 |
- ,(Color){ 45, 45, 45, 255 } |
|
798 |
- ); |
|
799 |
- if(menudata->flag_open || menudata->flag_stickyopen) { |
|
800 |
- int underline_height=3; |
|
801 |
- int maxw; |
|
802 |
- DrawRectangle(menudata->xywh.x,menudata->xywh.y+menudata->xywh.h-underline_height,menudata->xywh.w,underline_height, (Color){ 53,132,228,255 } ); |
|
803 |
- for(j=0,maxw=0;j<menudata->sizeoptions;j++) { |
|
804 |
- v2=MeasureTextEx(font->font,menudata->options[j],font->height,0); |
|
805 |
- maxw=(((int)(v2.x))>maxw)?((int)(v2.x)):maxw; |
|
806 |
- } |
|
807 |
- maxw=(maxw<(menudata->xywh.w+font->height))?(menudata->xywh.w+font->height):maxw; |
|
808 |
- maxw+=font->height; |
|
809 |
- FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(font->height+font->height/2)*menudata->sizeoptions); |
|
810 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y-2,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y-2,(Color){ 255,255,255,255 } ); |
|
811 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y,menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 255,255,255,255 } ); |
|
812 |
- DrawLine(menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
813 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
814 |
- DrawRectangle(menudata->optionsxywh.x,menudata->optionsxywh.y,menudata->optionsxywh.w,menudata->optionsxywh.h,(Color){ 235, 235, 235, 235 }); |
|
815 |
- for(k=0;k<menudata->sizeoptions;k++) { |
|
816 |
- Color c; |
|
817 |
- c=(k==menudata->currentoption)?((Color){ 255,255,255,255 }):((Color){ 45, 45, 45, 255 }); |
|
818 |
- if(k==menudata->currentoption) |
|
819 |
- DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(font->height+(font->height/2))*k,menudata->optionsxywh.w-2,font->height+font->height/2,(Color){ 53,132,228,255 }); |
|
820 |
- v2.x=(float) (menudata->optionsxywh.x+font->height/2); |
|
821 |
- v2.y=(float) (menudata->optionsxywh.y+(font->height/4)+(font->height+(font->height/2))*k); |
|
822 |
- DrawTextEx(font->font |
|
823 |
- ,menudata->options[k] |
|
824 |
- ,v2 |
|
825 |
- ,font->height |
|
826 |
- ,0 |
|
827 |
- ,c |
|
828 |
- ); |
|
829 |
- } |
|
830 |
- } else { |
|
831 |
- FILLXYWH(menudata->optionsxywh,0,0,0,0); |
|
832 |
- } |
|
833 |
- x=menudata->xywh.x+menudata->xywh.w; |
|
834 |
- } |
|
835 |
- return(0); |
|
836 | 226 |
} |
837 | 227 |
|
838 | 228 |
body_t * |
839 |
-im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight) |
|
229 |
+im_body_init(rayui_t *rayui, int w, int h, int x, int y, int leftsidesize, char *rootdir) |
|
840 | 230 |
{ |
841 | 231 |
body_t *body; |
842 | 232 |
char *errstr; |
843 |
- static char sep[]={SEP}; |
|
844 |
- if(font==NULL || fontbig==NULL || fonthuge==NULL || rootdir==NULL) { |
|
845 |
- messagebox("im_body_init sanity check failed"); |
|
233 |
+ static char sep[]={SEP,'\0'}; |
|
234 |
+ if(rayui->font==NULL || rayui->fontbig==NULL || rayui->fonthuge==NULL || rootdir==NULL) { |
|
235 |
+ global_messagebox("im_body_init sanity check failed"); |
|
846 | 236 |
return(NULL); /* sanity check failed */ |
847 | 237 |
} |
848 | 238 |
if((errstr="Insuf. mem. for body")==NULL |
... | ... |
@@ -852,21 +242,25 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
852 | 242 |
|| (errstr="Error init bg")==NULL |
853 | 243 |
|| (body->bg=bg_init(SIZEBGLOAD))==NULL |
854 | 244 |
) { |
855 |
- messagebox(errstr); |
|
245 |
+ global_messagebox("%s",errstr); |
|
856 | 246 |
im_body_free(body),body=NULL; |
857 | 247 |
return(NULL); |
858 | 248 |
} |
859 |
- FILLXYWH(body->xywh,x,y,windowwidth-x,windowheight-y); |
|
860 |
- body->leftsize=leftsize; |
|
861 |
- body->ptrfont=font; |
|
862 |
- body->ptrfontbig=fontbig; |
|
863 |
- body->ptrfonthuge=fonthuge; |
|
864 |
- if(body->rootdir[0]!='\0' && strcmp(body->rootdir,SEP)!=0 && body->rootdir[strlen(body->rootdir)-1]==sep[0]) |
|
249 |
+ body->rayui=rayui; |
|
250 |
+ FILLWHXY(body->whxy,w,h,x,y); |
|
251 |
+#if 1 |
|
252 |
+fprintf(stderr,"im_body_init: %ix%i+%i+%i\n",UNROLLWHXY(body->whxy)); |
|
253 |
+#endif |
|
254 |
+ body->leftsize=leftsidesize; |
|
255 |
+ body->ptrfont=rayui->font; |
|
256 |
+ body->ptrfontbig=rayui->fontbig; |
|
257 |
+ body->ptrfonthuge=rayui->fonthuge; |
|
258 |
+ if(body->rootdir[0]!='\0' && strcmp(body->rootdir,sep)!=0 && body->rootdir[strlen(body->rootdir)-1]==sep[0]) |
|
865 | 259 |
body->rootdir[strlen(body->rootdir)-1]='\0'; /* rootdir doesn't need the final '/' */ |
866 | 260 |
/* init rounded box glyph (a really big zero) */ |
867 | 261 |
{ |
868 | 262 |
int codepoints[]={'O','+','-'}; |
869 |
- body->roundedbox=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,ADDREMOVEDIRDATAHEIGHT*4,codepoints,sizeof(codepoints)/sizeof(codepoints[0])); |
|
263 |
+ body->roundedbox=LoadFontFromMemory(".ttf",rayui->defaultfontdata,rayui->sizedefaultfontdata,ADDREMOVEDIRDATAHEIGHT*4,codepoints,sizeof(codepoints)/sizeof(codepoints[0])); |
|
870 | 264 |
} |
871 | 265 |
return(body); |
872 | 266 |
} |
... | ... |
@@ -942,12 +336,12 @@ im_body_tryselect(body_t *body, Vector2 mousepos) |
942 | 336 |
if(body==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL || body->currentdirdata>=body->sizedirdata) |
943 | 337 |
return(-1); /* sanity check failed */ |
944 | 338 |
body->selectedpath[0]='\0'; |
945 |
- if(!is_imutil_insidexywh(mousepos,&(body->xywh),0) || mousepos.x>body->leftsize) |
|
339 |
+ if(!is_global_insidewhxy(mousepos,&(body->whxy),0) || mousepos.x>body->leftsize) |
|
946 | 340 |
return(-1); /* outside leftside */ |
947 | 341 |
listing=&(body->dirdata[body->currentdirdata]->listing); |
948 | 342 |
for(i=0;i<listing->usedelems;i++) { |
949 | 343 |
elem=listing->elems+i; |
950 |
- if(is_imutil_insidexywh(mousepos,&(elem->left.screenxywh),0)) { |
|
344 |
+ if(is_global_insidewhxy(mousepos,&(elem->left.screenwhxy),0)) { |
|
951 | 345 |
strncpy(body->selectedpath,elem->name,sizeof(body->selectedpath)); |
952 | 346 |
body->selectedpath[sizeof(body->selectedpath)-1]='\0'; |
953 | 347 |
return(0); /* found */ |
... | ... |
@@ -956,39 +350,40 @@ im_body_tryselect(body_t *body, Vector2 mousepos) |
956 | 350 |
return(-1); /* no thumbnail found for pos */ |
957 | 351 |
} |
958 | 352 |
|
959 |
- |
|
960 | 353 |
int |
961 |
-im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
|
354 |
+im_body_mouse(body_t *body, mousedata_t *mousedata) |
|
962 | 355 |
{ |
963 | 356 |
int i; |
964 | 357 |
char *ptr; |
965 | 358 |
dirdata_t *dirdata; |
966 | 359 |
listingdata_t *ld; |
967 | 360 |
int margin; |
968 |
- if(body==NULL || click_avail==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL) |
|
361 |
+ if(body==NULL || mousedata==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL) |
|
969 | 362 |
return(-1); /* sanity check error */ |
970 | 363 |
dirdata=body->dirdata[body->currentdirdata]; |
971 | 364 |
/* wheel */ |
972 |
- body->dirdata[body->currentdirdata]->leftscrollpos-=(int)wheel.y*WHEELSTEP; |
|
365 |
+ body->dirdata[body->currentdirdata]->leftscrollpos-=(int)mousedata->wheel.y*WHEELSTEP; |
|
366 |
+ if(is_rayui_scrolling(body->rayui,mousedata,"body.leftside",&(body->dirdata[body->currentdirdata]->leftscrollpos))) |
|
367 |
+ fprintf(stderr,"SCROLLING bosy.leftside newscrollpos:%i\n",body->dirdata[body->currentdirdata]->leftscrollpos); /* nothing to do, will fix coors for both wheel and scrolling in the next lines */ |
|
973 | 368 |
body->dirdata[body->currentdirdata]->leftscrollpos=(body->dirdata[body->currentdirdata]->leftscrollpos<0)?0:body->dirdata[body->currentdirdata]->leftscrollpos; |
974 |
- if(body->dirdata[body->currentdirdata]->leftscrollpos>dirdata->listing.lastleftxywh.y) |
|
975 |
- body->dirdata[body->currentdirdata]->leftscrollpos=dirdata->listing.lastleftxywh.y; |
|
369 |
+ if(body->dirdata[body->currentdirdata]->leftscrollpos>dirdata->listing.lastleftwhxy.y) |
|
370 |
+ body->dirdata[body->currentdirdata]->leftscrollpos=dirdata->listing.lastleftwhxy.y; |
|
976 | 371 |
/* check if we have to process a click */ |
977 |
- if(*click_avail==0 || lmbreleased==0) |
|
372 |
+ if(mousedata->click_avail==0 || mousedata->lmbreleased==0) |
|
978 | 373 |
return(0); /* nothing else to do */ |
979 | 374 |
/* show image in full screen */ |
980 | 375 |
if(body->flag_drawbigtexture) { |
981 |
- if(lmbreleased) |
|
376 |
+ if(mousedata->lmbreleased) |
|
982 | 377 |
body->flag_drawbigtexture=0; |
983 | 378 |
return(0); /* nothing else to do */ |
984 | 379 |
} |
985 | 380 |
margin=body->ptrfont->height/4; |
986 |
- if(body->is_displayingtexture && lmbreleased && is_imutil_insidexywh(mousepos,&(body->texture.source),margin) && body->selectedpath[0]=='\0') { |
|
381 |
+ if(body->is_displayingtexture && mousedata->lmbreleased && is_global_insidewhxy(mousedata->mousepos,&(body->texture.source),margin) && body->selectedpath[0]=='\0') { |
|
987 | 382 |
body->flag_drawbigtexture=1; |
988 | 383 |
return(0); /* nothing else to do */ |
989 | 384 |
} |
990 | 385 |
/* leftside backbutton */ |
991 |
- if(is_imutil_insidexywh(mousepos,&(body->backxywh),0)) { |
|
386 |
+ if(is_global_insidewhxy(mousedata->mousepos,&(body->backwhxy),0)) { |
|
992 | 387 |
static char sep[]={SEP}; |
993 | 388 |
if((ptr=strrchr(dirdata->dirname,sep[0]))!=NULL) { |
994 | 389 |
/* previous dir */ |
... | ... |
@@ -999,7 +394,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
999 | 394 |
} |
1000 | 395 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
1001 | 396 |
body->dirdata[body->currentdirdata]->leftscrollpos=0; |
1002 |
- *click_avail=0; |
|
397 |
+ mousedata->click_avail=0; |
|
1003 | 398 |
return(0); |
1004 | 399 |
} |
1005 | 400 |
/* leftside directories */ |
... | ... |
@@ -1007,11 +402,11 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
1007 | 402 |
ld=dirdata->listing.elems+i; |
1008 | 403 |
if(ld->name[0]!='d') |
1009 | 404 |
continue; |
1010 |
- if(is_imutil_insidexywh(mousepos,&(ld->left.screenxywh),0)) { |
|
405 |
+ if(is_global_insidewhxy(mousedata->mousepos,&(ld->left.screenwhxy),0)) { |
|
1011 | 406 |
char *newname,*oldprefix; |
1012 | 407 |
int l,l0,l1; |
1013 | 408 |
static char sep[]={SEP}; |
1014 |
- oldprefix=(strcmp(dirdata->dirname,SEP)==0)?"":dirdata->dirname; |
|
409 |
+ oldprefix=(dirdata->dirname[0]==SEP && dirdata->dirname[1]=='\0')?"":dirdata->dirname; |
|
1015 | 410 |
l0=strlen(oldprefix); |
1016 | 411 |
l1=strlen(ld->name+1); |
1017 | 412 |
l=l0+((l0>0)?1:0)+l1+1; |
... | ... |
@@ -1027,48 +422,48 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
1027 | 422 |
dirdata->dirname=newname; |
1028 | 423 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
1029 | 424 |
body->dirdata[body->currentdirdata]->leftscrollpos=0; |
1030 |
- *click_avail=0; |
|
425 |
+ mousedata->click_avail=0; |
|
1031 | 426 |
return(0); |
1032 | 427 |
} |
1033 | 428 |
} |
1034 | 429 |
/* dirdata processing */ |
1035 | 430 |
if(body->selectedpath[0]=='\0') { |
1036 | 431 |
/* dirdata select */ |
1037 |
- if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
432 |
+ if(mousedata->mousepos.x>body->leftsize && mousedata->mousepos.y>body->whxy.y) { |
|
1038 | 433 |
int righty; |
1039 |
- for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
434 |
+ for(righty=body->whxy.y,i=0;i<body->sizedirdata;i++) { |
|
1040 | 435 |
if(body->dirdata[i]==NULL) |
1041 | 436 |
continue; |
1042 |
- if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata) { |
|
437 |
+ if(mousedata->mousepos.y>=righty && mousedata->mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata) { |
|
1043 | 438 |
body->currentdirdata=i; |
1044 |
- *click_avail=0; |
|
439 |
+ mousedata->click_avail=0; |
|
1045 | 440 |
return(0); |
1046 | 441 |
} |
1047 | 442 |
righty+=body->dirdata[i]->height; |
1048 | 443 |
} |
1049 | 444 |
} |
1050 | 445 |
/* detect click on "add dirdata" button */ |
1051 |
- if(is_imutil_insidexywh(mousepos,&(body->dirdataadd),0)) { |
|
446 |
+ if(is_global_insidewhxy(mousedata->mousepos,&(body->dirdataadd),0)) { |
|
1052 | 447 |
im_body_add(body,body->dirdata[body->currentdirdata]->dirname); |
1053 |
- *click_avail=0; |
|
448 |
+ mousedata->click_avail=0; |
|
1054 | 449 |
return(0); |
1055 | 450 |
} |
1056 | 451 |
/* dirdata remove */ |
1057 | 452 |
#warning TODO |
1058 | 453 |
} |
1059 | 454 |
/* unselect selectedpath */ |
1060 |
- if(lmbpressed==0 && body->selectedpath[0]!='\0') { |
|
1061 |
- if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
455 |
+ if(mousedata->lmbpressed==0 && body->selectedpath[0]!='\0') { |
|
456 |
+ if(mousedata->mousepos.x>body->leftsize && mousedata->mousepos.y>body->whxy.y) { |
|
1062 | 457 |
int righty; |
1063 |
- for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
458 |
+ for(righty=body->whxy.y,i=0;i<body->sizedirdata;i++) { |
|
1064 | 459 |
if(body->dirdata[i]==NULL) |
1065 | 460 |
continue; |
1066 |
- if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
461 |
+ if(mousedata->mousepos.y>=righty && mousedata->mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
1067 | 462 |
#warning TODO |
1068 | 463 |
#if 1 |
1069 | 464 |
fprintf(stderr,"WOULD MOVE \"%s/%s\" to \"%s\"\n",body->dirdata[body->currentdirdata]->dirname,body->selectedpath+1,body->dirdata[i]->dirname); |
1070 | 465 |
#endif |
1071 |
- *click_avail=0; |
|
466 |
+ mousedata->click_avail=0; |
|
1072 | 467 |
break; |
1073 | 468 |
} |
1074 | 469 |
righty+=body->dirdata[i]->height; |
... | ... |
@@ -1079,8 +474,13 @@ fprintf(stderr,"WOULD MOVE \"%s/%s\" to \"%s\"\n",body->dirdata[body->currentdir |
1079 | 474 |
return(0); |
1080 | 475 |
} |
1081 | 476 |
|
477 |
+#ifdef MYFUNC |
|
478 |
+#undef MYFUNC |
|
479 |
+#define MYFUNC "im_body_draw" |
|
480 |
+#endif |
|
481 |
+ |
|
1082 | 482 |
int |
1083 |
-im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw, int scrollspeed) |
|
483 |
+im_body_draw(body_t *body, mousedata_t *mousedata, int windowwidth, int windowheight, int *needs_nextredraw) |
|
1084 | 484 |
{ |
1085 | 485 |
int i,k,margin,righty; |
1086 | 486 |
int lastx,lasty; |
... | ... |
@@ -1095,12 +495,13 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1095 | 495 |
thumb_t *thumb; |
1096 | 496 |
char statustooltip[1024]; |
1097 | 497 |
thumb_t *selectedthumb; |
498 |
+ IMDEBUG("Pre-sanitycheck"); |
|
1098 | 499 |
if(body==NULL) |
1099 | 500 |
return(-1); |
1100 | 501 |
font=body->ptrfont; |
1101 | 502 |
fontbig=body->ptrfontbig; |
1102 | 503 |
fonthuge=body->ptrfonthuge; |
1103 |
- FILLXYWH(body->backxywh,0,0,0,0); |
|
504 |
+ FILLWHXY(body->backwhxy,0,0,0,0); |
|
1104 | 505 |
margin=font->height/4; |
1105 | 506 |
body->is_displayingtexture=0; |
1106 | 507 |
selectedthumb=NULL; |
... | ... |
@@ -1108,14 +509,15 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1108 | 509 |
if(body->flag_drawbigtexture && body->texture.has_texture) { |
1109 | 510 |
/* draw image in full screen */ |
1110 | 511 |
int maxw,maxh; |
512 |
+ IMDEBUG("begin draw"); |
|
1111 | 513 |
maxw=windowwidth; |
1112 |
- maxh=windowheight-body->xywh.y; |
|
514 |
+ maxh=windowheight-body->whxy.y; |
|
1113 | 515 |
if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0) |
1114 | 516 |
texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh,body->bg); |
1115 | 517 |
if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,body->texture.currentpath)==0) { |
1116 | 518 |
int x0,y0; |
1117 | 519 |
x0=0; |
1118 |
- y0=body->xywh.y; |
|
520 |
+ y0=body->whxy.y; |
|
1119 | 521 |
texture_draw(&(body->bigtexture),x0,y0,maxw,maxh); |
1120 | 522 |
return(0); /* all done */ |
1121 | 523 |
} else { |
... | ... |
@@ -1123,30 +525,47 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1123 | 525 |
} |
1124 | 526 |
} |
1125 | 527 |
/* calculate positions */ |
528 |
+ IMDEBUG("calculate positions"); |
|
1126 | 529 |
for(i=0;i<body->sizedirdata;i++) { |
1127 | 530 |
if(body->dirdata[i]==NULL) |
1128 | 531 |
continue; |
1129 |
- if(body->dirdata[i]->listing.has_rightxywh==0) { |
|
532 |
+ if(body->dirdata[i]->listing.has_rightwhxy==0) { |
|
1130 | 533 |
int sidelen; |
1131 | 534 |
sidelen=body->dirdata[i]->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
1132 |
- listing_fillxywh(&(body->dirdata[i]->listing),body->ptrfont,body->xywh.w-(body->xywh.x+body->leftsize),sidelen,0); |
|
1133 |
- body->dirdata[i]->listing.has_rightxywh=1; |
|
535 |
+ listing_fillwhxy(&(body->dirdata[i]->listing),body->ptrfont,body->whxy.w-(body->whxy.x+body->leftsize),sidelen,0,0); |
|
536 |
+ body->dirdata[i]->listing.has_rightwhxy=1; |
|
1134 | 537 |
} |
1135 |
- if(i==body->currentdirdata && body->dirdata[i]->listing.has_leftxywh==0) { |
|
1136 |
- listing_fillxywh(&(body->dirdata[i]->listing),body->ptrfont,body->leftsize,LEFTIMAGESIDELEN,1); |
|
1137 |
- body->dirdata[i]->listing.has_leftxywh=1; |
|
538 |
+ if(i==body->currentdirdata && body->dirdata[i]->listing.has_leftwhxy==0) { |
|
539 |
+ listing_fillwhxy(&(body->dirdata[i]->listing),body->ptrfont,body->leftsize,LEFTIMAGESIDELEN,1,0); |
|
540 |
+ body->dirdata[i]->listing.has_leftwhxy=1; |
|
1138 | 541 |
} |
1139 | 542 |
} |
1140 | 543 |
/* draw left side background */ |
1141 |
- DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
|
544 |
+ IMDEBUG("draw left bg"); |
|
545 |
+ { |
|
546 |
+ whxy_t whxy; |
|
547 |
+ FILLWHXY(whxy,body->leftsize, body->whxy.h,body->whxy.x,body->whxy.y); |
|
548 |
+ rayui_scrollablerectadd(body->rayui,mousedata,&whxy,"body.leftside",body->dirdata[body->currentdirdata]->leftscrollpos,(int (*)(void *, Vector2))im_body_tryselect,body,SCROLLTHRESHOLD); |
|
549 |
+ } |
|
550 |
+ DrawRectangle(body->whxy.x,body->whxy.y,body->leftsize, body->whxy.h, (Color){ 215, 215, 215, 255 } ); |
|
551 |
+fprintf(stderr,"%ix%i+%i+%i\n",body->leftsize, body->whxy.h,body->whxy.x,body->whxy.y); |
|
1142 | 552 |
/* draw right side background */ |
1143 |
- DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
|
553 |
+#if 1 |
|
554 |
+fprintf(stderr,"body->whxy:%ix%i+%i+%i\n",UNROLLWHXY(body->whxy)); |
|
555 |
+fprintf(stderr,"body->leftsize:%i\n",body->leftsize); |
|
556 |
+#endif |
|
557 |
+ IMDEBUG("draw right bg"); |
|
558 |
+ DrawRectangle(body->whxy.x+body->leftsize,body->whxy.y,body->whxy.w-body->leftsize, body->whxy.h, (Color){ 227, 227, 227, 255 } ); |
|
559 |
+fprintf(stderr,"DrawRectangle(body->whxy.x(%i)+body->leftsize(%i),body->whxy.y(%i),body->whxy.w(%i)-body->leftsize(%i), body->whxy.h(%i), (Color){ 227, 227, 227, 255 } );\n" |
|
560 |
+ ,body->whxy.x,body->leftsize,body->whxy.y,body->whxy.w,body->leftsize, body->whxy.h); |
|
561 |
+ |
|
562 |
+fprintf(stderr,"%ix%i+%i+%i\n",body->whxy.w-body->leftsize, body->whxy.h,body->whxy.x+body->leftsize,body->whxy.y); |
|
1144 | 563 |
/* reset lazy load marks */ |
1145 | 564 |
bg_resetmarks(body->bg); |
1146 | 565 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
1147 | 566 |
statustooltip[0]='\0'; |
1148 | 567 |
for(is_leftside=1,flag_skiprightside=flag_skipall=0;is_leftside>=0 && flag_skiprightside==0 && flag_skipall==0;is_leftside--) { |
1149 |
- for(i=(is_leftside)?body->currentdirdata:0,righty=body->xywh.y;flag_skipall==0 && ((is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata));i++) { |
|
568 |
+ for(i=(is_leftside)?body->currentdirdata:0,righty=body->whxy.y;flag_skipall==0 && ((is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata));i++) { |
|
1150 | 569 |
int sidelen; |
1151 | 570 |
if((dirdata=body->dirdata[i])==NULL) |
1152 | 571 |
continue; |
... | ... |
@@ -1154,24 +573,24 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1154 | 573 |
continue; /* this element is not in leftside */ |
1155 | 574 |
sidelen=(is_leftside)?LEFTIMAGESIDELEN:dirdata->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
1156 | 575 |
/* draw left side back arrow if is_leftside and not in root dir */ |
1157 |
- if(is_leftside && !(dirdata->dirname[0]=='\0' || strcmp(dirdata->dirname,SEP)==0)) { |
|
576 |
+ if(is_leftside && !(dirdata->dirname[0]=='\0' || (dirdata->dirname[0]==SEP && dirdata->dirname[1]=='\0'))) { |
|
1158 | 577 |
m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
1159 |
- v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
1160 |
- v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2)-body->dirdata[body->currentdirdata]->leftscrollpos; |
|
1161 |
- FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
|
578 |
+ v2.x=(float) (body->whxy.x+fontbig->height/2); |
|
579 |
+ v2.y=(float) (body->whxy.y+fontbig->height/4+(fontbig->height-v2.x)/2)-body->dirdata[body->currentdirdata]->leftscrollpos; |
|
580 |
+ FILLWHXY(body->backwhxy,m2.x+fontbig->height/4,m2.x+fontbig->height/4,v2.x-fontbig->height/4,v2.y-fontbig->height/8); |
|
1162 | 581 |
#if 0 |
1163 | 582 |
DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
1164 |
-DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone */ |
|
583 |
+DrawRectangle(UNROLLXYWH(body->backwhxy),((Color){ 0,255,0,255 })); /* hit zone */ |
|
1165 | 584 |
#endif |
1166 | 585 |
if((v2.y+fontbig->height)>=0) |
1167 | 586 |
DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
1168 | 587 |
} |
1169 | 588 |
if(is_leftside) { |
1170 | 589 |
/* ...dirname */ |
1171 |
- v2.y=(float) (body->xywh.y+fontbig->height/4-body->dirdata[body->currentdirdata]->leftscrollpos); |
|
590 |
+ v2.y=(float) (body->whxy.y+fontbig->height/4-body->dirdata[body->currentdirdata]->leftscrollpos); |
|
1172 | 591 |
if((v2.y+fontbig->height)>=0) { |
1173 | 592 |
m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
1174 |
- v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
593 |
+ v2.x=(float) (body->whxy.x+fontbig->height/2)+(body->leftsize-(body->whxy.x+fontbig->height)-m2.x)/2; |
|
1175 | 594 |
DrawTextEx(fontbig->font |
1176 | 595 |
,dirdata->dirname |
1177 | 596 |
,v2 |
... | ... |
@@ -1182,13 +601,13 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1182 | 601 |
} |
1183 | 602 |
} else { /* rightside */ |
1184 | 603 |
/* ...bg */ |
1185 |
- DrawRectangle(body->xywh.x+body->leftsize,righty,body->xywh.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
|
604 |
+ DrawRectangle(body->whxy.x+body->leftsize,righty,body->whxy.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
|
1186 | 605 |
/* ...bottom separator */ |
1187 |
- DrawRectangle(body->xywh.x+body->leftsize,righty+dirdata->height-1,body->xywh.w-body->leftsize, 1, (Color){ 221, 221, 221, 255 } ); |
|
606 |
+ DrawRectangle(body->whxy.x+body->leftsize,righty+dirdata->height-1,body->whxy.w-body->leftsize, 1, (Color){ 221, 221, 221, 255 } ); |
|
1188 | 607 |
/* ...dirname */ |
1189 | 608 |
DrawTextEx(fontbig->font |
1190 | 609 |
,dirdata->dirname |
1191 |
- ,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
|
610 |
+ ,(Vector2) {body->whxy.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
|
1192 | 611 |
,fontbig->height |
1193 | 612 |
,0 |
1194 | 613 |
,(i==body->currentdirdata)?((Color){ 240, 240, 240, 255 }):((Color){ 65, 65, 65, 255 }) |
... | ... |
@@ -1196,7 +615,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1196 | 615 |
} |
1197 | 616 |
/* directories */ |
1198 | 617 |
xoff=((is_leftside)?0:body->leftsize); |
1199 |
- yoff=((is_leftside)?body->xywh.y:righty)+fontbig->height/4+fontbig->height+font->height/4-(is_leftside?body->dirdata[body->currentdirdata]->leftscrollpos:0); |
|
618 |
+ yoff=((is_leftside)?body->whxy.y:righty)+fontbig->height/4+fontbig->height+font->height/4-(is_leftside?body->dirdata[body->currentdirdata]->leftscrollpos:0); |
|
1200 | 619 |
if(is_leftside && dirdata->dirname[0]=='\0') |
1201 | 620 |
yoff-=fontbig->height/4+fontbig->height; |
1202 | 621 |
for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
... | ... |
@@ -1204,51 +623,51 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1204 | 623 |
thumb=(is_leftside)?&(elem->left):&(elem->right); |
1205 | 624 |
if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) { |
1206 | 625 |
if(elem->name[0]=='d') |
1207 |
- FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
626 |
+ FILLWHXY(thumb->screenwhxy,0,0,0,0); |
|
1208 | 627 |
continue; |
1209 | 628 |
} |
1210 |
- if((thumb->xywh.y+yoff)>(body->xywh.y+body->xywh.h) || thumb->xywh.w==0 || thumb->xywh.h==0) { |
|
629 |
+ if((thumb->whxy.y+yoff)>(body->whxy.y+body->whxy.h) || thumb->whxy.w==0 || thumb->whxy.h==0) { |
|
1211 | 630 |
#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
1212 | 631 |
break; |
1213 | 632 |
} |
1214 |
- if((thumb->xywh.y+yoff+thumb->xywh.h)<0) { |
|
1215 |
- FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
633 |
+ if((thumb->whxy.y+yoff+thumb->whxy.h)<0) { |
|
634 |
+ FILLWHXY(thumb->screenwhxy,0,0,0,0); |
|
1216 | 635 |
continue; |
1217 | 636 |
} |
1218 |
- FILLXYWH(thumb->screenxywh,thumb->xywh.x+xoff,thumb->xywh.y+yoff,thumb->xywh.w,thumb->xywh.h); |
|
1219 |
- DrawRectangleLines(UNROLLXYWH(thumb->screenxywh),((Color){ 65, 65, 65, 255 })); |
|
1220 |
- DrawTextEx(font->font,elem->name+1,(Vector2){thumb->screenxywh.x+margin,thumb->screenxywh.y+margin},font->height,0,((Color){ 65, 65, 65, 255 })); |
|
1221 |
- lastx=thumb->screenxywh.x+thumb->screenxywh.w,lasty=thumb->screenxywh.y+thumb->screenxywh.h; |
|
637 |
+ FILLWHXY(thumb->screenwhxy,thumb->whxy.w,thumb->whxy.h,thumb->whxy.x+xoff,thumb->whxy.y+yoff); |
|
638 |
+ DrawRectangleLines(thumb->screenwhxy.x,thumb->screenwhxy.y,thumb->screenwhxy.w,thumb->screenwhxy.h,((Color){ 65, 65, 65, 255 })); |
|
639 |
+ DrawTextEx(font->font,elem->name+1,(Vector2){thumb->screenwhxy.x+margin,thumb->screenwhxy.y+margin},font->height,0,((Color){ 65, 65, 65, 255 })); |
|
640 |
+ lastx=thumb->screenwhxy.x+thumb->screenwhxy.w,lasty=thumb->screenwhxy.y+thumb->screenwhxy.h; |
|
1222 | 641 |
} |
1223 | 642 |
for(;k<dirdata->listing.usedelems;k++) { |
1224 | 643 |
elem=dirdata->listing.elems+k; |
1225 | 644 |
if(elem->name[0]!='d') |
1226 | 645 |
continue; |
1227 | 646 |
thumb=(is_leftside)?&(elem->left):&(elem->right); |
1228 |
- FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
647 |
+ FILLWHXY(thumb->screenwhxy,0,0,0,0); |
|
1229 | 648 |
} |
1230 | 649 |
/* files */ |
1231 | 650 |
for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
1232 | 651 |
Texture2D *te; |
1233 |
- xywh_t *xywh; |
|
652 |
+ whxy_t *whxy; |
|
1234 | 653 |
elem=dirdata->listing.elems+k; |
1235 | 654 |
thumb=(is_leftside)?&(elem->left):&(elem->right); |
1236 |
- xywh=&(thumb->xywh); |
|
655 |
+ whxy=&(thumb->whxy); |
|
1237 | 656 |
te=&(thumb->texture); |
1238 | 657 |
int has_imagedrawn; |
1239 | 658 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
1240 | 659 |
continue; |
1241 |
- if((xywh->y+yoff)>(body->xywh.y+body->xywh.h) || xywh->w==0 || xywh->h==0) { |
|
660 |
+ if((whxy->y+yoff)>(body->whxy.y+body->whxy.h) || whxy->w==0 || whxy->h==0) { |
|
1242 | 661 |
#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
1243 | 662 |
break; |
1244 | 663 |
} |
1245 |
- if(is_leftside && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
664 |
+ if(is_leftside && is_global_insidewhxy(mousedata->mousepos,&(thumb->screenwhxy),margin)) { |
|
1246 | 665 |
strncpy(statustooltip,elem->name+1,sizeof(statustooltip)); |
1247 | 666 |
statustooltip[sizeof(statustooltip)-1]='\0'; |
1248 | 667 |
} |
1249 | 668 |
/* show image */ |
1250 | 669 |
has_imagedrawn=0; |
1251 |
- if(is_imagefilename(elem->name+1) && !(thumb->screenxywh.y>(body->xywh.y+body->xywh.h) || (thumb->screenxywh.y+thumb->screenxywh.h)<body->xywh.y)) { |
|
670 |
+ if(is_imagefilename(elem->name+1) && !(thumb->screenwhxy.y>(body->whxy.y+body->whxy.h) || (thumb->screenwhxy.y+thumb->screenwhxy.h)<body->whxy.y)) { |
|
1252 | 671 |
if(thumb->has_texture==0 && thumb->has_failedload==0) { |
1253 | 672 |
bgload_t *bgload; |
1254 | 673 |
char fullpath[2048]; |
... | ... |
@@ -1291,16 +710,16 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1291 | 710 |
} |
1292 | 711 |
} |
1293 | 712 |
if(thumb->has_texture!=0) { |
1294 |
- FILLXYWH(thumb->screenxywh,xywh->x+xoff,xywh->y+yoff,xywh->w,xywh->h); |
|
1295 |
- DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE); |
|
713 |
+ FILLWHXY(thumb->screenwhxy,whxy->w,whxy->h,whxy->x+xoff,whxy->y+yoff); |
|
714 |
+ DrawTexture(*te,thumb->screenwhxy.x,thumb->screenwhxy.y,WHITE); |
|
1296 | 715 |
has_imagedrawn=1; |
1297 |
- lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff; |
|
1298 |
- if(is_leftside && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin) && scrollspeed==0) { |
|
716 |
+ lastx=whxy->x+whxy->w,lasty=whxy->y+whxy->h+yoff; |
|
717 |
+ if(is_leftside && mousedata->rmbdown==0 && is_global_insidewhxy(mousedata->mousepos,&(thumb->screenwhxy),margin) && mousedata->scrollspeed==0) { |
|
1299 | 718 |
/* draw image in rightside */ |
1300 | 719 |
char fullpath[2048]; |
1301 | 720 |
int maxw,maxh; |
1302 | 721 |
maxw=windowwidth-(body->leftsize-DEFAULTDIRDATATRIANGLEW); |
1303 |
- maxh=windowheight-body->xywh.y; |
|
722 |
+ maxh=windowheight-body->whxy.y; |
|
1304 | 723 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
1305 | 724 |
fullpath[sizeof(fullpath)-1]='\0'; |
1306 | 725 |
if((body->texture.has_texture==0 && !(body->texture.has_failedload && strcmp(body->texture.currentpath,fullpath)==0)) |
... | ... |
@@ -1311,10 +730,10 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1311 | 730 |
if(body->texture.has_texture && strcmp(body->texture.currentpath,fullpath)==0) { |
1312 | 731 |
int x0,y0; |
1313 | 732 |
x0=body->leftsize-DEFAULTDIRDATATRIANGLEW; |
1314 |
- y0=body->xywh.y; |
|
733 |
+ y0=body->whxy.y; |
|
1315 | 734 |
texture_draw(&(body->texture),x0,y0,maxw,maxh); |
1316 | 735 |
body->is_displayingtexture=1; |
1317 |
- memcpy(&(body->texture.source),&(thumb->screenxywh),sizeof(body->texture.source)); |
|
736 |
+ memcpy(&(body->texture.source),&(thumb->screenwhxy),sizeof(body->texture.source)); |
|
1318 | 737 |
flag_skiprightside=1; |
1319 | 738 |
} |
1320 | 739 |
} |
... | ... |
@@ -1323,15 +742,15 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1323 | 742 |
if(has_imagedrawn==0) { |
1324 | 743 |
char *ptr; |
1325 | 744 |
char shortname[1024]; |
1326 |
- xywh_t *pos; |
|
745 |
+ whxy_t *pos; |
|
1327 | 746 |
int l; |
1328 | 747 |
font_t *myfont=(is_leftside)?fonthuge:font; |
1329 |
- pos=is_leftside?&(elem->left.xywh):&(elem->right.xywh); |
|
1330 |
- FILLXYWH(thumb->screenxywh,xywh->x+xoff,xywh->y+yoff,xywh->w,xywh->h); |
|
1331 |
- DrawRectangle(UNROLLXYWH(thumb->screenxywh),((Color){0,0,0,64})); |
|
748 |
+ pos=is_leftside?&(elem->left.whxy):&(elem->right.whxy); |
|
749 |
+ FILLWHXY(thumb->screenwhxy,whxy->w,whxy->h,whxy->x+xoff,whxy->y+yoff); |
|
750 |
+ DrawRectangle(thumb->screenwhxy.x,thumb->screenwhxy.y,thumb->screenwhxy.w,thumb->screenwhxy.h,((Color){0,0,0,64})); |
|
1332 | 751 |
if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
1333 | 752 |
m2=MeasureTextEx(myfont->font,ptr,myfont->height,0); |
1334 |
- DrawTextEx(myfont->font,ptr,(Vector2){xywh->x+xoff+(sidelen-m2.x)/2,xywh->y+yoff+(font->height)/2+(xywh->w-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
|
753 |
+ DrawTextEx(myfont->font,ptr,(Vector2){whxy->x+xoff+(sidelen-m2.x)/2,whxy->y+yoff+(font->height)/2+(whxy->w-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
|
1335 | 754 |
} |
1336 | 755 |
ptr=(ptr==NULL)?elem->name+1:ptr; |
1337 | 756 |
l=(ptr-(elem->name+1)); |
... | ... |
@@ -1340,17 +759,17 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1340 | 759 |
shortname[l]='\0'; |
1341 | 760 |
DrawRectangle(pos->x+xoff,pos->y+yoff,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
1342 | 761 |
DrawTextEx(font->font,shortname,(Vector2){pos->x+xoff+font->height/4,pos->y+yoff+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
1343 |
- lastx=xywh->x+xoff+xywh->w,lasty=xywh->y+yoff+xywh->h; |
|
762 |
+ lastx=whxy->x+xoff+whxy->w,lasty=whxy->y+yoff+whxy->h; |
|
1344 | 763 |
} |
1345 | 764 |
/* show selected rectangle */ |
1346 | 765 |
if(is_leftside && strcmp(body->selectedpath,elem->name)==0) { |
1347 | 766 |
Color c=((Color){0,0,255,64}); |
1348 |
- DrawRectangle(UNROLLXYWH(thumb->screenxywh),c); |
|
767 |
+ DrawRectangle(thumb->screenwhxy.x,thumb->screenwhxy.y,thumb->screenwhxy.w,thumb->screenwhxy.h,c); |
|
1349 | 768 |
c=((Color){0,0,255,255}); |
1350 |
- DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y,thumb->screenxywh.w,2,c); |
|
1351 |
- DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y+2,2,thumb->screenxywh.h-4,c); |
|
1352 |
- DrawRectangle(thumb->screenxywh.x+thumb->screenxywh.w-2,thumb->screenxywh.y+2,2,thumb->screenxywh.h-4,c); |
|
1353 |
- DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y+thumb->screenxywh.h-2,thumb->screenxywh.w,2,c); |
|
769 |
+ DrawRectangle(thumb->screenwhxy.x,thumb->screenwhxy.y,thumb->screenwhxy.w,2,c); |
|
770 |
+ DrawRectangle(thumb->screenwhxy.x,thumb->screenwhxy.y+2,2,thumb->screenwhxy.h-4,c); |
|
771 |
+ DrawRectangle(thumb->screenwhxy.x+thumb->screenwhxy.w-2,thumb->screenwhxy.y+2,2,thumb->screenwhxy.h-4,c); |
|
772 |
+ DrawRectangle(thumb->screenwhxy.x,thumb->screenwhxy.y+thumb->screenwhxy.h-2,thumb->screenwhxy.w,2,c); |
|
1354 | 773 |
selectedthumb=thumb; |
1355 | 774 |
} |
1356 | 775 |
} |
... | ... |
@@ -1359,7 +778,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1359 | 778 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
1360 | 779 |
continue; |
1361 | 780 |
thumb=(is_leftside)?&(elem->left):&(elem->right); |
1362 |
- FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
781 |
+ FILLWHXY(thumb->screenwhxy,0,0,0,0); |
|
1363 | 782 |
} |
1364 | 783 |
/* ...finishing touchs */ |
1365 | 784 |
if(is_leftside) { |
... | ... |
@@ -1367,29 +786,29 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1367 | 786 |
} else { |
1368 | 787 |
if(i==body->currentdirdata) { |
1369 | 788 |
/* draw right side "current" marker inside left side area */ |
1370 |
- DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
1371 |
- } else if(body->selectedpath[0]!='\0' && mousepos.x>body->leftsize && mousepos.y>=righty && mousepos.y<(righty+dirdata->height) && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
1372 |
- xywh_t xywh; |
|
789 |
+ DrawTriangle((Vector2){((float)body->whxy.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->whxy.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->whxy.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
790 |
+ } else if(body->selectedpath[0]!='\0' && mousedata->mousepos.x>body->leftsize && mousedata->mousepos.y>=righty && mousedata->mousepos.y<(righty+dirdata->height) && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
791 |
+ whxy_t whxy; |
|
1373 | 792 |
Color c=((Color){0,0,255,64}); |
1374 |
- FILLXYWH(xywh,body->leftsize,righty,body->xywh.w-body->leftsize,dirdata->height); |
|
1375 |
- DrawRectangle(UNROLLXYWH(xywh),c); |
|
793 |
+ FILLWHXY(whxy,body->whxy.w-body->leftsize,dirdata->height,body->leftsize,righty); |
|
794 |
+ DrawRectangle(whxy.x,whxy.y,whxy.w,whxy.h,c); |
|
1376 | 795 |
c=((Color){0,0,255,255}); |
1377 |
- DrawRectangle(xywh.x,xywh.y,xywh.w,2,c); |
|
1378 |
- DrawRectangle(xywh.x,xywh.y+2,2,xywh.h-4,c); |
|
1379 |
- DrawRectangle(xywh.x+xywh.w-2,xywh.y+2,2,xywh.h-4,c); |
|
1380 |
- DrawRectangle(xywh.x,xywh.y+xywh.h-2,xywh.w,2,c); |
|
796 |
+ DrawRectangle(whxy.x,whxy.y,whxy.w,2,c); |
|
797 |
+ DrawRectangle(whxy.x,whxy.y+2,2,whxy.h-4,c); |
|
798 |
+ DrawRectangle(whxy.x+whxy.w-2,whxy.y+2,2,whxy.h-4,c); |
|
799 |
+ DrawRectangle(whxy.x,whxy.y+whxy.h-2,whxy.w,2,c); |
|
1381 | 800 |
} |
1382 | 801 |
/* advance to next element */ |
1383 | 802 |
righty+=dirdata->height; |
1384 | 803 |
} |
1385 | 804 |
} |
1386 | 805 |
} |
1387 |
- if(flag_skiprightside==0 && (righty+DEFAULTDIRDATAHEIGHT)<=(body->xywh.y+body->xywh.h)) { |
|
806 |
+ if(flag_skiprightside==0 && (righty+DEFAULTDIRDATAHEIGHT)<=(body->whxy.y+body->whxy.h)) { |
|
1388 | 807 |
GlyphInfo gi; |
1389 | 808 |
int xoff; |
1390 | 809 |
int margin; |
1391 | 810 |
margin=20; |
1392 |
- FILLXYWH(body->dirdataadd,(body->xywh.x+body->xywh.w-ADDREMOVEDIRDATAHEIGHT-margin),righty+margin,ADDREMOVEDIRDATAHEIGHT,ADDREMOVEDIRDATAHEIGHT); |
|
811 |
+ FILLWHXY(body->dirdataadd,(body->whxy.x+body->whxy.w-ADDREMOVEDIRDATAHEIGHT-margin),righty+margin,ADDREMOVEDIRDATAHEIGHT,ADDREMOVEDIRDATAHEIGHT); |
|
1393 | 812 |
gi=GetGlyphInfo(body->roundedbox,'O'); |
1394 | 813 |
xoff=0; |
1395 | 814 |
DrawTexturePro(body->roundedbox.texture |
... | ... |
@@ -1413,10 +832,10 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1413 | 832 |
} else { |
1414 | 833 |
memset(&(body->dirdataadd),0,sizeof(body->dirdataadd)); |
1415 | 834 |
} |
1416 |
- /* if moving elem, show line from orig to mousepos */ |
|
835 |
+ /* if moving elem, show line from orig to mousedata->mousepos */ |
|
1417 | 836 |
if(body->selectedpath[0]!='\0' && selectedthumb!=NULL) { |
1418 | 837 |
Color c=((Color){0,0,255,255}); |
1419 |
- DrawLineEx((Vector2){(float)(selectedthumb->screenxywh.x+selectedthumb->screenxywh.w/2),(float)(selectedthumb->screenxywh.y+selectedthumb->screenxywh.h/2)},mousepos,2.0,c); |
|
838 |
+ DrawLineEx((Vector2){(float)(selectedthumb->screenwhxy.x+selectedthumb->screenwhxy.w/2),(float)(selectedthumb->screenwhxy.y+selectedthumb->screenwhxy.h/2)},mousedata->mousepos,2.0,c); |
|
1420 | 839 |
} |
1421 | 840 |
/* show tooltip */ |
1422 | 841 |
if(statustooltip[0]!='\0') { |
... | ... |
@@ -1425,242 +844,21 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1425 | 844 |
DrawTextEx(font->font,statustooltip,(Vector2){margin,windowheight-1-margin-font->height},font->height,0,(Color){ 255,255,255,128 }); |
1426 | 845 |
} |
1427 | 846 |
/* free not used bg load items (only if idle, as it takes time) */ |
1428 |
- if(scrollspeed==0 && *needs_nextredraw==0) |
|
847 |
+ if(mousedata->scrollspeed==0 && *needs_nextredraw==0) |
|
1429 | 848 |
bg_freeunmarked(body->bg); |
1430 | 849 |
return(0); |
1431 | 850 |
} |
1432 | 851 |
|
1433 |
-int |
|
1434 |
-texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg) |
|
1435 |
-{ |
|
1436 |
- Image im; |
|
1437 |
- int neww,newh; |
|
1438 |
- bgload_t *bgload; |
|
1439 |
- if(texture==NULL || fullpath==NULL) |
|
1440 |
- return(-1); /* sanity check failed */ |
|
1441 |
- if(texture->has_texture) { |
|
1442 |
- UnloadTexture(texture->texture); |
|
1443 |
- texture->currentpath[0]='\0'; |
|
1444 |
- texture->has_texture=0; |
|
1445 |
- texture->has_failedload=0; |
|
1446 |
- } |
|
1447 |
- texture->currentpath[0]='\0'; |
|
1448 |
- if(bg!=NULL && (bgload=bg_get(bg,texture->currentpath))!=NULL && bgload->has_data!=0) { |
|
1449 |
- im=ImageCopy(bgload->image); |
|
1450 |
- } else { |
|
1451 |
- im=imutil_loadimage(fullpath); |
|
1452 |
- } |
|
1453 |
- if(IsImageValid(im)) { |
|
1454 |
- imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
1455 |
- ImageResize(&im,neww,newh); |
|
1456 |
- texture->texture=LoadTextureFromImage(im); |
|
1457 |
- UnloadImage(im); |
|
1458 |
- strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1459 |
- texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1460 |
- texture->has_texture=1; |
|
1461 |
- texture->has_failedload=0; |
|
1462 |
- texture->texturew=neww; |
|
1463 |
- texture->textureh=newh; |
|
1464 |
- } else { |
|
1465 |
- strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1466 |
- texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1467 |
- texture->has_texture=0; |
|
1468 |
- texture->has_failedload=1; |
|
1469 |
- } |
|
1470 |
- return(0); |
|
1471 |
-} |
|
1472 |
- |
|
1473 |
-int |
|
1474 |
-texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh) |
|
1475 |
-{ |
|
1476 |
- if(texture==NULL || texture->has_texture==0) |
|
1477 |
- return(-1); /* sanity check failed */ |
|
1478 |
- DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
1479 |
- DrawTexture(texture->texture,x0+(maxw-texture->texturew)/2,y0+(maxh-texture->textureh)/2,WHITE); |
|
1480 |
- return(0); |
|
1481 |
-} |
|
1482 |
- |
|
1483 |
-int |
|
1484 |
-texture_freedata(texture_t *texture) |
|
1485 |
-{ |
|
1486 |
- if(texture==NULL) |
|
1487 |
- return(-1); /* sanity check failed */ |
|
1488 |
- if(texture->has_texture) { |
|
1489 |
- UnloadTexture(texture->texture); |
|
1490 |
- texture->currentpath[0]='\0'; |
|
1491 |
- texture->has_texture=0; |
|
1492 |
- texture->has_failedload=0; |
|
1493 |
- } |
|
1494 |
- return(0); |
|
1495 |
-} |
|
1496 |
- |
|
1497 |
-int |
|
1498 |
-imutil_menu_count(char *menus) |
|
1499 |
-{ |
|
1500 |
- int n; |
|
1501 |
- char *ptr,*next; |
|
1502 |
- if(menus==NULL) |
|
1503 |
- return(0); /* sanity check error */ |
|
1504 |
- for(ptr=menus,n=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
1505 |
- if(next[1]=='\n') { |
|
1506 |
- next++; |
|
1507 |
- n++; |
|
1508 |
- } |
|
1509 |
- } |
|
1510 |
- return(n); |
|
1511 |
-} |
|
1512 |
- |
|
1513 |
-char * |
|
1514 |
-imutil_menu_get(char *menus, int targetn, int *len) |
|
1515 |
-{ |
|
1516 |
- int n; |
|
1517 |
- char *ptr,*next,*end; |
|
1518 |
- int is_title; |
|
1519 |
- if(len!=NULL) |
|
1520 |
- *len=0; |
|
1521 |
- if(menus==NULL || targetn<0) |
|
1522 |
- return(NULL); /* sanity check error */ |
|
1523 |
- end=menus+strlen(menus); |
|
1524 |
- for(ptr=menus,is_title=1,n=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
1525 |
- if(targetn==n && is_title==1) { |
|
1526 |
- if(len!=NULL) |
|
1527 |
- *len=next-ptr; |
|
1528 |
- return(ptr); /* found, return start of menu string */ |
|
1529 |
- } |
|
1530 |
- is_title=0; |
|
1531 |
- if(next[1]=='\n') { |
|
1532 |
- n++; |
|
1533 |
- next++; |
|
1534 |
- is_title=1; |
|
1535 |
- } |
|
1536 |
- } |
|
1537 |
- return(end); /* not found, return end of menus */ |
|
1538 |
-} |
|
1539 |
- |
|
1540 |
-int |
|
1541 |
-imutil_submenu_count(char *menus) |
|
1542 |
-{ |
|
1543 |
- int subn; |
|
1544 |
- char *ptr,*next; |
|
1545 |
- if(menus==NULL) |
|
1546 |
- return(0); /* sanity check error */ |
|
1547 |
- next=strchr(menus,'\n'); |
|
1548 |
- if(next==NULL) |
|
1549 |
- return(0); /* no title */ |
|
1550 |
- for(subn=0,ptr=next+1;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
1551 |
- subn++; |
|
1552 |
- if(next[1]=='\n') |
|
1553 |
- break; |
|
1554 |
- } |
|
1555 |
- return(subn); |
|
1556 |
-} |
|
1557 |
- |
|
1558 |
-char * |
|
1559 |
-imutil_submenu_get(char *menus, int targetsubn, int *len) |
|
1560 |
-{ |
|
1561 |
- char *ptr,*next,*end; |
|
1562 |
- int subn; |
|
1563 |
- if(len!=NULL) |
|
1564 |
- *len=0; |
|
1565 |
- if(menus==NULL || targetsubn<0) |
|
1566 |
- return(NULL); /* sanity check error */ |
|
1567 |
- end=menus+strlen(menus); |
|
1568 |
- next=strchr(menus,'\n'); |
|
1569 |
- if(next==NULL) |
|
1570 |
- return(end); /* no title */ |
|
1571 |
- for(ptr=next+1,subn=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1,subn++) { |
|
1572 |
- if(targetsubn==subn) { |
|
1573 |
- if(len!=NULL) |
|
1574 |
- *len=next-ptr; |
|
1575 |
- return(ptr); |
|
1576 |
- } |
|
1577 |
- if(next[1]=='\n') |
|
1578 |
- break; /* "\n\n" marks the end of submenus */ |
|
1579 |
- } |
|
1580 |
- return(end); |
|
1581 |
-} |
|
1582 |
- |
|
1583 |
-char * |
|
1584 |
-imutil_strduplen(char *str, int len) |
|
1585 |
-{ |
|
1586 |
- char *res; |
|
1587 |
- if(len<0 || (str==NULL && len!=0)) |
|
1588 |
- return(NULL); |
|
1589 |
- if((res=malloc(len+1))==NULL) |
|
1590 |
- return(NULL); |
|
1591 |
- memcpy(res,str,len); |
|
1592 |
- res[len]='\0'; |
|
1593 |
- return(res); |
|
1594 |
-} |
|
1595 |
- |
|
1596 |
-int |
|
1597 |
-is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin) |
|
1598 |
-{ |
|
1599 |
- if(xywh==NULL) |
|
1600 |
- return(0); /* sanity check error */ |
|
1601 |
- if(pos.x>=(float)(xywh->x-margin) |
|
1602 |
- && pos.x<=(float)(xywh->x+xywh->w+margin) |
|
1603 |
- && pos.y>=(float)(xywh->y-margin) |
|
1604 |
- && pos.y<=(float)(xywh->y+xywh->h+margin) |
|
1605 |
- ) { |
|
1606 |
- return(1); |
|
1607 |
- } |
|
1608 |
- return(0); |
|
1609 |
-} |
|
1610 |
- |
|
1611 |
-int |
|
1612 |
-imutil_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
|
1613 |
-{ |
|
1614 |
- if(neww==NULL || newh==NULL || w==0 || h==0 || maxw==0 || maxh==0) |
|
1615 |
- return(-1); |
|
1616 |
- if((w/h)>(maxw/maxh) || (maxw==maxh && w>h)) { |
|
1617 |
- *neww=maxw; |
|
1618 |
- *newh=h*maxw/w; |
|
1619 |
- } else { /* (w/h)<=(maxw/maxh) */ |
|
1620 |
- *newh=maxh; |
|
1621 |
- *neww=w*maxh/h; |
|
1622 |
- } |
|
1623 |
- return(0); |
|
1624 |
-} |
|
1625 |
- |
|
1626 |
- |
|
1627 |
-int |
|
1628 |
-menudata_pos2option(menudata_t *menudata, Vector2 pos) |
|
1629 |
-{ |
|
1630 |
- int n,h; |
|
1631 |
- if(menudata==NULL |
|
1632 |
- || (menudata->flag_open==0 && menudata->flag_stickyopen==0) |
|
1633 |
- || is_imutil_insidexywh(pos, &(menudata->optionsxywh),0)==0 |
|
1634 |
- ) { |
|
1635 |
- return(-1); |
|
1636 |
- } |
|
1637 |
- h=(menudata->sizeoptions==0)?0:menudata->optionsxywh.h/menudata->sizeoptions; |
|
1638 |
- n=(((int)pos.y)-menudata->optionsxywh.y)/h; |
|
1639 |
- return(n); |
|
1640 |
-} |
|
1641 |
- |
|
1642 |
-int * |
|
1643 |
-getcodepoints(int *sizecodepoints) |
|
1644 |
-{ |
|
1645 |
- static int codepoints[]={ |
|
1646 |
-/* Basic Latin */ |
|
1647 |
-32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, |
|
1648 |
-/* Latin-1 Supplement */ |
|
1649 |
-160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, |
|
1650 |
-/* down arrow (U+2186 -- this font doesn't have arrows, this is old roman numeral 50 */ |
|
1651 |
-(0x21<<8)|0x86, |
|
1652 |
-}; |
|
1653 |
- if(sizecodepoints!=NULL) |
|
1654 |
- *sizecodepoints=(int) (sizeof(codepoints)/sizeof(codepoints[0])); |
|
1655 |
- return(codepoints); |
|
1656 |
-} |
|
1657 |
- |
|
1658 | 852 |
static int |
1659 | 853 |
strptrcmp(void *a,void *b) |
1660 | 854 |
{ |
1661 | 855 |
return(strcmp(((listingdata_t *)a)->name,((listingdata_t *)b)->name)); |
1662 | 856 |
} |
1663 | 857 |
|
858 |
+#ifdef MYFUNC |
|
859 |
+#undef MYFUNC |
|
860 |
+#define MYFUNC "listing_get" |
|
861 |
+#endif |
|
1664 | 862 |
int |
1665 | 863 |
listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort) |
1666 | 864 |
{ |
... | ... |
@@ -1689,11 +887,11 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1689 | 887 |
/* reset struct */ |
1690 | 888 |
listing->usedelems=listing->usedbuf=0; |
1691 | 889 |
memset(listing->elems,0,sizeof(listingdata_t)*listing->sizeelems); |
1692 |
- listing->has_leftxywh=listing->has_rightxywh=0; |
|
890 |
+ listing->has_leftwhxy=listing->has_rightwhxy=0; |
|
1693 | 891 |
/* fill listing */ |
1694 | 892 |
if(pathprefix==NULL && parampath==NULL) |
1695 | 893 |
return(-1); /* nothing to fill */ |
1696 |
- snprintf(path,sizeof(path),"%s%s%s",(pathprefix!=NULL)?pathprefix:"",SEP,(parampath!=NULL)?parampath:""); |
|
894 |
+ snprintf(path,sizeof(path),"%s%c%s",(pathprefix!=NULL)?pathprefix:"",SEP,(parampath!=NULL)?parampath:""); |
|
1697 | 895 |
path[sizeof(path)-1]='\0'; |
1698 | 896 |
if((d=opendir(path))==NULL) |
1699 | 897 |
return(-1); /* dir not found */ |
... | ... |
@@ -1714,7 +912,7 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1714 | 912 |
char stpath[2048]; |
1715 | 913 |
struct stat st; |
1716 | 914 |
mode_t m; |
1717 |
- snprintf(stpath,sizeof(stpath),"%s%s%s",path,SEP,de->d_name); |
|
915 |
+ snprintf(stpath,sizeof(stpath),"%s%c%s",path,SEP,de->d_name); |
|
1718 | 916 |
stpath[sizeof(stpath)-1]='\0'; |
1719 | 917 |
if(stat(stpath,&st)==0 && (m=(st.st_mode&S_IFMT))!=0) { |
1720 | 918 |
dtype=(m==S_IFBLK)?'b' |
... | ... |
@@ -1767,6 +965,7 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1767 | 965 |
listing->elems[listing->usedelems++].name=listing->buf+listing->usedbuf; |
1768 | 966 |
listing->buf[listing->usedbuf++]=dtype; |
1769 | 967 |
memcpy(listing->buf+listing->usedbuf,de->d_name,l+1); |
968 |
+IMDEBUG(listing->buf+listing->usedbuf); |
|
1770 | 969 |
listing->usedbuf+=l+1; |
1771 | 970 |
} |
1772 | 971 |
closedir(d),d=NULL; |
... | ... |
@@ -1804,7 +1003,7 @@ listing_freedata(listing_t *listing) |
1804 | 1003 |
} |
1805 | 1004 |
|
1806 | 1005 |
int |
1807 |
-listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_leftside) |
|
1006 |
+listing_fillwhxy(listing_t *listing, font_t *font, int w, int sidelen, int is_leftside, int rightsidemargin) |
|
1808 | 1007 |
{ |
1809 | 1008 |
int x0,y0,x1; |
1810 | 1009 |
int k,x,y; |
... | ... |
@@ -1816,14 +1015,14 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1816 | 1015 |
return(-1); /* sanity check failed */ |
1817 | 1016 |
margin=font->height/4; |
1818 | 1017 |
if(is_leftside) |
1819 |
- memset(&(listing->lastleftxywh),0,sizeof(listing->lastleftxywh)); |
|
1018 |
+ memset(&(listing->lastleftwhxy),0,sizeof(listing->lastleftwhxy)); |
|
1820 | 1019 |
/* directories */ |
1821 | 1020 |
if(is_leftside) { |
1822 | 1021 |
x0=font->height/2; |
1823 | 1022 |
x1=w-DEFAULTDIRDATATRIANGLEW-font->height/2; |
1824 | 1023 |
y0=0; |
1825 | 1024 |
} else { |
1826 |
- x0=FONTBIGSIZE/2; |
|
1025 |
+ x0=rightsidemargin; |
|
1827 | 1026 |
x1=w-font->height/2; |
1828 | 1027 |
y0=0; |
1829 | 1028 |
} |
... | ... |
@@ -1836,12 +1035,12 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1836 | 1035 |
if((x+margin*2+m2.x)>x1 && !(is_leftside==0 && y>y0)) |
1837 | 1036 |
x=x0,y+=font->height+margin*2+font->height/4; |
1838 | 1037 |
if(is_leftside==0 && y>y0) { |
1839 |
- FILLXYWH(thumb->xywh,0,0,0,0); |
|
1038 |
+ FILLWHXY(thumb->whxy,0,0,0,0); |
|
1840 | 1039 |
continue; |
1841 | 1040 |
} |
1842 |
- FILLXYWH(thumb->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
1843 |
- if(is_leftside && (thumb->xywh.y+thumb->xywh.h)>(listing->lastleftxywh.y+listing->lastleftxywh.h)) |
|
1844 |
- memcpy(&(listing->lastleftxywh),&(thumb->xywh),sizeof(xywh_t)); |
|
1041 |
+ FILLWHXY(thumb->whxy,margin*2+m2.x,margin*2+font->height,x,y); |
|
1042 |
+ if(is_leftside && (thumb->whxy.y+thumb->whxy.h)>(listing->lastleftwhxy.y+listing->lastleftwhxy.h)) |
|
1043 |
+ memcpy(&(listing->lastleftwhxy),&(thumb->whxy),sizeof(whxy_t)); |
|
1845 | 1044 |
x+=margin*2+m2.x+font->height/4; |
1846 | 1045 |
} |
1847 | 1046 |
y+=((x==x0)?0:font->height+margin*2+font->height/4); |
... | ... |
@@ -1856,18 +1055,18 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1856 | 1055 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
1857 | 1056 |
continue; |
1858 | 1057 |
if(!is_leftside && y>y0) { |
1859 |
- FILLXYWH(thumb->xywh,0,0,0,0); |
|
1058 |
+ FILLWHXY(thumb->whxy,0,0,0,0); |
|
1860 | 1059 |
continue; |
1861 | 1060 |
} |
1862 | 1061 |
if((x+margin*2+sidelen)>x1 && !(is_leftside==0 && y>y0)) |
1863 | 1062 |
x=x0,y+=sidelen+margin*2; |
1864 | 1063 |
if(is_leftside==0 && y>y0) { |
1865 |
- FILLXYWH(thumb->xywh,0,0,0,0); |
|
1064 |
+ FILLWHXY(thumb->whxy,0,0,0,0); |
|
1866 | 1065 |
continue; |
1867 | 1066 |
} |
1868 |
- FILLXYWH(thumb->xywh,x,y,sidelen,sidelen); |
|
1869 |
- if(is_leftside && (thumb->xywh.y+thumb->xywh.h)>(listing->lastleftxywh.y+listing->lastleftxywh.h)) |
|
1870 |
- memcpy(&(listing->lastleftxywh),&(thumb->xywh),sizeof(xywh_t)); |
|
1067 |
+ FILLWHXY(thumb->whxy,sidelen,sidelen,x,y); |
|
1068 |
+ if(is_leftside && (thumb->whxy.y+thumb->whxy.h)>(listing->lastleftwhxy.y+listing->lastleftwhxy.h)) |
|
1069 |
+ memcpy(&(listing->lastleftwhxy),&(thumb->whxy),sizeof(whxy_t)); |
|
1871 | 1070 |
x+=margin*2+sidelen; |
1872 | 1071 |
} |
1873 | 1072 |
return(0); |
... | ... |
@@ -1899,313 +1098,82 @@ is_imagefilename(char *filename) |
1899 | 1098 |
return(0); /* not in the knownext list */ |
1900 | 1099 |
} |
1901 | 1100 |
|
1902 |
-#ifdef ANDROID |
|
1903 |
-Image |
|
1904 |
-imutil_loadimage(const char *filename) |
|
1905 |
-{ |
|
1906 |
- unsigned char *filedata=NULL; |
|
1907 |
- FILE *f=NULL; |
|
1908 |
- struct stat st; |
|
1909 |
- Image img; |
|
1910 |
- char *ext; |
|
1911 |
- if((f=fopen(filename,"r"))==NULL |
|
1912 |
- || fstat(fileno(f),&st)!=0 |
|
1913 |
- || st.st_size<=0 |
|
1914 |
- || (filedata=(unsigned char *)malloc(st.st_size))==NULL |
|
1915 |
- || fread(filedata,1,st.st_size,f)!=st.st_size |
|
1916 |
- ) { |
|
1917 |
- if(f!=NULL) |
|
1918 |
- fclose(f),f=NULL; |
|
1919 |
- if(filedata!=NULL) |
|
1920 |
- free(filedata),filedata=NULL; |
|
1921 |
- return((Image){0}); |
|
1922 |
- } |
|
1923 |
- fclose(f); |
|
1924 |
- ext=strchr(filename,'.'); |
|
1925 |
- ext=(ext==NULL)?filename+strlen(filename):ext; |
|
1926 |
- img=LoadImageFromMemory(ext,filedata,st.st_size); |
|
1927 |
- free(filedata),filedata=NULL; |
|
1928 |
- return(img); |
|
1929 |
-} |
|
1930 |
-#else |
|
1931 |
-Image |
|
1932 |
-imutil_loadimage(const char *filename) |
|
1933 |
-{ |
|
1934 |
- return(LoadImage(filename)); |
|
1935 |
-} |
|
1936 |
-#endif |
|
1937 |
- |
|
1938 |
-static void |
|
1939 |
-intimutil_fpsdata(struct timeval **deadline) |
|
1940 |
-{ |
|
1941 |
- static struct timeval mydeadline; |
|
1942 |
- *deadline=&(mydeadline); |
|
1943 |
- return; |
|
1944 |
-} |
|
1945 |
- |
|
1946 |
-void |
|
1947 |
-imutil_fpsreset(void) |
|
1948 |
-{ |
|
1949 |
- struct timeval *deadline; |
|
1950 |
- long deadlineincr; |
|
1951 |
- intimutil_fpsdata(&deadline); |
|
1952 |
- gettimeofday(deadline,NULL); |
|
1953 |
- deadlineincr=1000000L/TARGETFPS; |
|
1954 |
- deadline->tv_usec+=deadlineincr; |
|
1955 |
- deadline->tv_sec+=(deadline->tv_usec)/1000000L; |
|
1956 |
- deadline->tv_usec%=1000000L; |
|
1957 |
-} |
|
1958 |
- |
|
1959 | 1101 |
int |
1960 |
-imutil_fpsleft(void) |
|
1961 |
-{ |
|
1962 |
- struct timeval *deadline,now; |
|
1963 |
- intimutil_fpsdata(&deadline); |
|
1964 |
- gettimeofday(&now,NULL); |
|
1965 |
- if(deadline->tv_sec<now.tv_sec || (deadline->tv_sec==now.tv_sec && deadline->tv_usec<now.tv_usec)) |
|
1966 |
- return(0); |
|
1967 |
- return(1); |
|
1968 |
-} |
|
1969 |
- |
|
1970 |
-long long |
|
1971 |
-imutil_milliseconds(void) |
|
1972 |
-{ |
|
1973 |
- long long res; |
|
1974 |
- struct timeval now; |
|
1975 |
- gettimeofday(&now,NULL); |
|
1976 |
- res=((long long) (now.tv_sec))*1000000L+((long long) (now.tv_usec)); |
|
1977 |
- return(res); |
|
1978 |
-} |
|
1979 |
- |
|
1980 |
-bg_t * |
|
1981 |
-bg_init(int sizebgload) |
|
1102 |
+texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg) |
|
1982 | 1103 |
{ |
1983 |
- bg_t *bg; |
|
1984 |
- char *errstr; |
|
1985 |
- bg=NULL; |
|
1986 |
- if((errstr="Insuf. mem. for bg")==NULL |
|
1987 |
- || (bg=calloc(1,sizeof(bg_t)))==NULL |
|
1988 |
- || (errstr="Error init pipes (please check program is not blocked in firewall)")==NULL |
|
1989 |
- || (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
|
1990 |
- || mypipe(bg->pipe)!=0 |
|
1991 |
- || (errstr="Insuf mem bgload")==NULL |
|
1992 |
- || (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
|
1993 |
- || (bg->sizebgload=sizebgload)!=sizebgload |
|
1994 |
- || (errstr="pthread attr init error")==NULL |
|
1995 |
- || pthread_attr_init(&(bg->tattr))!=0 |
|
1996 |
- || (errstr="pthread create error")==NULL |
|
1997 |
- || pthread_create(&(bg->thread),&(bg->tattr),bg_thread,(void *)bg)!=0 |
|
1998 |
- || (bg->flag_threadstarted=1)!=1 |
|
1999 |
- ) { |
|
2000 |
- messagebox(errstr); |
|
2001 |
- bg_free(bg); |
|
2002 |
- return(NULL); |
|
1104 |
+ Image im; |
|
1105 |
+ int neww,newh; |
|
1106 |
+ bgload_t *bgload; |
|
1107 |
+ if(texture==NULL || fullpath==NULL) |
|
1108 |
+ return(-1); /* sanity check failed */ |
|
1109 |
+ if(texture->has_texture) { |
|
1110 |
+ UnloadTexture(texture->texture); |
|
1111 |
+ texture->currentpath[0]='\0'; |
|
1112 |
+ texture->has_texture=0; |
|
1113 |
+ texture->has_failedload=0; |
|
2003 | 1114 |
} |
2004 |
- return(bg); |
|
2005 |
-} |
|
2006 |
- |
|
2007 |
- |
|
2008 |
-void |
|
2009 |
-bg_free(bg_t *bg) |
|
2010 |
-{ |
|
2011 |
- int i; |
|
2012 |
- if(bg==NULL) |
|
2013 |
- return; /* nothing to do */ |
|
2014 |
- if(bg->flag_threadstarted) { |
|
2015 |
- char dummy=1; |
|
2016 |
-#if 1 |
|
2017 |
-fprintf(stderr,"bg_free: notifying thread to exit\n"); |
|
2018 |
-#endif |
|
2019 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
2020 |
-#if 1 |
|
2021 |
-fprintf(stderr,"bg_free: joining thread\n"); |
|
2022 |
-#endif |
|
2023 |
- pthread_join(bg->thread,NULL); |
|
2024 |
-#if 1 |
|
2025 |
-fprintf(stderr,"bg_free: thread joined OK\n"); |
|
2026 |
-#endif |
|
2027 |
- bg->flag_threadstarted=0; |
|
1115 |
+ texture->currentpath[0]='\0'; |
|
1116 |
+ if(bg!=NULL && (bgload=bg_get(bg,texture->currentpath))!=NULL && bgload->has_data!=0) { |
|
1117 |
+ im=ImageCopy(bgload->image); |
|
1118 |
+ } else { |
|
1119 |
+ im=global_loadimage(fullpath); |
|
2028 | 1120 |
} |
2029 |
- if(bg->pipe[0]!=-1) |
|
2030 |
- close(bg->pipe[0]),bg->pipe[0]=-1; |
|
2031 |
- if(bg->pipe[1]!=-1) |
|
2032 |
- close(bg->pipe[1]),bg->pipe[1]=-1; |
|
2033 |
- if(bg->bgload!=NULL) { |
|
2034 |
- bgload_t *bgload; |
|
2035 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2036 |
- if(bgload->has_data) { |
|
2037 |
- UnloadImage(bgload->image); |
|
2038 |
- bgload->has_data=0; |
|
2039 |
- } |
|
2040 |
- } |
|
2041 |
- free(bg->bgload),bg->bgload=NULL,bg->sizebgload=0; |
|
1121 |
+ if(IsImageValid(im)) { |
|
1122 |
+ imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
1123 |
+ ImageResize(&im,neww,newh); |
|
1124 |
+ texture->texture=LoadTextureFromImage(im); |
|
1125 |
+ UnloadImage(im); |
|
1126 |
+ strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1127 |
+ texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1128 |
+ texture->has_texture=1; |
|
1129 |
+ texture->has_failedload=0; |
|
1130 |
+ texture->texturew=neww; |
|
1131 |
+ texture->textureh=newh; |
|
1132 |
+ } else { |
|
1133 |
+ strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1134 |
+ texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1135 |
+ texture->has_texture=0; |
|
1136 |
+ texture->has_failedload=1; |
|
2042 | 1137 |
} |
2043 |
- return; |
|
1138 |
+ return(0); |
|
2044 | 1139 |
} |
2045 | 1140 |
|
2046 | 1141 |
int |
2047 |
-bg_resetmarks(bg_t *bg) |
|
1142 |
+texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh) |
|
2048 | 1143 |
{ |
2049 |
- int i; |
|
2050 |
- bgload_t *bgload; |
|
2051 |
- if(bg==NULL) |
|
2052 |
- return(-1); |
|
2053 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) |
|
2054 |
- bgload->has_mark=0; |
|
1144 |
+ if(texture==NULL || texture->has_texture==0) |
|
1145 |
+ return(-1); /* sanity check failed */ |
|
1146 |
+ DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
1147 |
+ DrawTexture(texture->texture,x0+(maxw-texture->texturew)/2,y0+(maxh-texture->textureh)/2,WHITE); |
|
2055 | 1148 |
return(0); |
2056 | 1149 |
} |
2057 | 1150 |
|
2058 |
-bgload_t * |
|
2059 |
-bg_get(bg_t *bg, char *path) |
|
2060 |
-{ |
|
2061 |
- int i; |
|
2062 |
- bgload_t *bgload; |
|
2063 |
- if(bg==NULL) |
|
2064 |
- return(NULL); |
|
2065 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2066 |
- if(bgload->thread_finished && bgload->has_data && strcmp(path,bgload->path)==0) { |
|
2067 |
- bgload->has_mark=1; |
|
2068 |
-#if 1 |
|
2069 |
-fprintf(stderr,"bg_get: \"%s\"\n",bgload->path); |
|
2070 |
-#endif |
|
2071 |
- return(bgload); |
|
2072 |
- } |
|
2073 |
- } |
|
2074 |
- return(NULL); |
|
2075 |
-} |
|
2076 |
- |
|
2077 | 1151 |
int |
2078 |
-bg_add(bg_t *bg, char *path) |
|
1152 |
+texture_freedata(texture_t *texture) |
|
2079 | 1153 |
{ |
2080 |
- int i; |
|
2081 |
- bgload_t *bgload; |
|
2082 |
- char dummy; |
|
2083 |
- if(bg==NULL) |
|
2084 |
- return(-1); |
|
2085 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2086 |
- if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
|
2087 |
- bgload->is_todo=1; |
|
2088 |
- bgload->has_mark=1; |
|
2089 |
- dummy=0; |
|
2090 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
2091 |
- return(0); /* already on list */ |
|
2092 |
- } |
|
2093 |
- } |
|
2094 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2095 |
- if(bgload->lended_to_thread==0) { |
|
2096 |
- memset(bgload,0,sizeof(bgload_t)); |
|
2097 |
- strncpy(bgload->path,path,sizeof(bgload->path)); |
|
2098 |
- bgload->path[sizeof(bgload->path)-1]='\0'; |
|
2099 |
- bgload->is_todo=1; |
|
2100 |
- bgload->has_mark=1; |
|
2101 |
- dummy=0; |
|
2102 |
- bgload->lended_to_thread=1; |
|
2103 |
- mypipewrite(bg->pipe[WR],&dummy,1); |
|
2104 |
- return(0); /* added to list */ |
|
2105 |
- } |
|
1154 |
+ if(texture==NULL) |
|
1155 |
+ return(-1); /* sanity check failed */ |
|
1156 |
+ if(texture->has_texture) { |
|
1157 |
+ UnloadTexture(texture->texture); |
|
1158 |
+ texture->currentpath[0]='\0'; |
|
1159 |
+ texture->has_texture=0; |
|
1160 |
+ texture->has_failedload=0; |
|
2106 | 1161 |
} |
2107 |
- return(-1); /* couldn't add */ |
|
1162 |
+ return(0); |
|
2108 | 1163 |
} |
2109 | 1164 |
|
2110 | 1165 |
int |
2111 |
-bg_freeunmarked(bg_t *bg) |
|
1166 |
+imutil_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
|
2112 | 1167 |
{ |
2113 |
- int i; |
|
2114 |
- bgload_t *bgload; |
|
2115 |
- if(bg==NULL) |
|
1168 |
+ if(neww==NULL || newh==NULL || w==0 || h==0 || maxw==0 || maxh==0) |
|
2116 | 1169 |
return(-1); |
2117 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2118 |
- if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
|
2119 |
- if(bgload->has_data) { |
|
2120 |
-#if 1 |
|
2121 |
-fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
|
2122 |
-#endif |
|
2123 |
- UnloadImage(bgload->image); |
|
2124 |
- bgload->has_data=0; |
|
2125 |
- } |
|
2126 |
-#if 1 |
|
2127 |
-else { |
|
2128 |
-fprintf(stderr,"bg: Cancelling: \"%s\"\n",bgload->path); |
|
2129 |
-} |
|
2130 |
-#endif |
|
2131 |
- memset(bgload,0,sizeof(bgload_t)); |
|
2132 |
- } |
|
1170 |
+ if((w/h)>(maxw/maxh) || (maxw==maxh && w>h)) { |
|
1171 |
+ *neww=maxw; |
|
1172 |
+ *newh=h*maxw/w; |
|
1173 |
+ } else { /* (w/h)<=(maxw/maxh) */ |
|
1174 |
+ *newh=maxh; |
|
1175 |
+ *neww=w*maxh/h; |
|
2133 | 1176 |
} |
2134 | 1177 |
return(0); |
2135 | 1178 |
} |
2136 | 1179 |
|
2137 |
-void * |
|
2138 |
-bg_thread(void *parambg) |
|
2139 |
-{ |
|
2140 |
- bg_t *bg; |
|
2141 |
- char dummy; |
|
2142 |
- bg=(bg_t *)parambg; |
|
2143 |
- int i; |
|
2144 |
- bgload_t *bgload; |
|
2145 |
- while(1) { |
|
2146 |
- mypiperead(bg->pipe[RD],&dummy,1); |
|
2147 |
-#if 1 |
|
2148 |
-fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
|
2149 |
-#endif |
|
2150 |
- if(dummy!=0) |
|
2151 |
- break; /* was told to exit */ |
|
2152 |
- for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2153 |
- if(bgload->lended_to_thread==0) |
|
2154 |
- continue; |
|
2155 |
- if(bgload->is_todo==0) { |
|
2156 |
- bgload->thread_finished=1; |
|
2157 |
- continue; |
|
2158 |
- } |
|
2159 |
- if(bgload->has_data==0 && bgload->has_failedload==0) { |
|
2160 |
- bgload->image=imutil_loadimage(bgload->path); |
|
2161 |
- if(IsImageValid(bgload->image)) |
|
2162 |
- bgload->has_data=1; |
|
2163 |
- else |
|
2164 |
- bgload->has_failedload=1; |
|
2165 |
- bgload->thread_finished=1; |
|
2166 |
- } |
|
2167 |
- } |
|
2168 |
- } |
|
2169 |
- pthread_exit(NULL); |
|
2170 |
- return(NULL); |
|
2171 |
-} |
|
2172 |
- |
|
2173 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
2174 |
-static int |
|
2175 |
-mypipe(int fds[2]) |
|
2176 |
-{ |
|
2177 |
- return(win32pipe_pipe(fds)); |
|
2178 |
-} |
|
2179 |
- |
|
2180 |
-static int |
|
2181 |
-mypiperead(int fd, char *buf, int count) |
|
2182 |
-{ |
|
2183 |
- return(win32pipe_read(fd,buf,count)); |
|
2184 |
-} |
|
2185 |
- |
|
2186 |
-static int |
|
2187 |
-mypipewrite(int fd, char *buf, int count) |
|
2188 |
-{ |
|
2189 |
- return(win32pipe_write(fd,buf,count)); |
|
2190 |
-} |
|
2191 |
-#else |
|
2192 |
-static int |
|
2193 |
-mypipe(int fds[2]) |
|
2194 |
-{ |
|
2195 |
- return(pipe(fds)); |
|
2196 |
-} |
|
2197 |
- |
|
2198 |
-static int |
|
2199 |
-mypiperead(int fd, char *buf, int count) |
|
2200 |
-{ |
|
2201 |
- return(read(fd,buf,count)); |
|
2202 |
-} |
|
2203 |
- |
|
2204 |
-static int |
|
2205 |
-mypipewrite(int fd, char *buf, int count) |
|
2206 |
-{ |
|
2207 |
- return(write(fd,buf,count)); |
|
2208 |
-} |
|
2209 |
-#endif |
|
2210 |
- |
|
2211 |
- |
... | ... |
@@ -100,6 +100,7 @@ |
100 | 100 |
|
101 | 101 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
102 | 102 |
|
103 |
+ |
|
103 | 104 |
#if defined(SIMANDROID) |
104 | 105 |
#undef ROOTDIR |
105 | 106 |
#define ROOTDIR "/var/www/default/animeshot/" |
... | ... |
@@ -150,7 +151,7 @@ int MessageBoxA(void *hWnd,void *lpText,void *lpCaption,unsigned int uType); |
150 | 151 |
|
151 | 152 |
|
152 | 153 |
|
153 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
154 |
+#if !defined(__linux__) && !defined(ANDROID) && RAYLIB_VERSION_MAJOR==5 && RAYLIB_VERSION_MINOR==0 |
|
154 | 155 |
/* the old raylib used in the windows build lacks this function */ |
155 | 156 |
bool IsImageValid(Image image) |
156 | 157 |
{ |
... | ... |
@@ -397,7 +398,7 @@ main(int argc, char *argv[]) |
397 | 398 |
click_avail=1; |
398 | 399 |
has_mousechanges=(lmbdown!=oldlmbdown || rmbdown!=oldrmbdown || mousepos.x!=oldmousepos.x || mousepos.y!=oldmousepos.y || wheel.x!=0 || wheel.y!=0)?1:0; |
399 | 400 |
needs_nextredraw=0; |
400 |
- /* process scrolling */ |
|
401 |
+ /* mouse process scrolling */ |
|
401 | 402 |
if(lmbdown==1 && oldlmbdown==0 && scrollstart==0 && mousepos.y>im->body->xywh.y) { |
402 | 403 |
scrollstart=imutil_milliseconds(); |
403 | 404 |
scrollstartpos=mousepos; |
... | ... |
@@ -440,7 +441,7 @@ main(int argc, char *argv[]) |
440 | 441 |
scrollspeed=scrollspeed*4/5; |
441 | 442 |
im->body->dirdata[im->body->currentdirdata]->leftscrollpos+=scrollspeed; |
442 | 443 |
} |
443 |
- /* process clicks on menus */ |
|
444 |
+ /* mouse process clicks on menus */ |
|
444 | 445 |
if(click_avail) { |
445 | 446 |
sel_menu=sel_submenu=NULL; |
446 | 447 |
im_menubar_mouse(im->menubar, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail, &sel_menu, &sel_submenu); |
... | ... |
@@ -141,6 +141,14 @@ |
141 | 141 |
#define WR 1 |
142 | 142 |
#endif |
143 | 143 |
|
144 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
145 |
+int MessageBoxA(void *hWnd,void *lpText,void *lpCaption,unsigned int uType); |
|
146 |
+#define messagebox(str) MessageBoxA(NULL,str,"imgmover",0); |
|
147 |
+#else |
|
148 |
+#define messagebox(str) fprintf(stderr,"%s\n",str); |
|
149 |
+#endif |
|
150 |
+ |
|
151 |
+ |
|
144 | 152 |
|
145 | 153 |
#if !defined(__linux__) && !defined(ANDROID) |
146 | 154 |
/* the old raylib used in the windows build lacks this function */ |
... | ... |
@@ -365,9 +373,7 @@ main(int argc, char *argv[]) |
365 | 373 |
win32pipe_init(); |
366 | 374 |
#endif |
367 | 375 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
368 |
-#if !defined(__linux__) && !defined(ANDROID) |
|
369 |
- MessageBoxA(NULL,"Couldn't init interface","imgmover",0); |
|
370 |
-#endif |
|
376 |
+ messagebox("Couldn't init interface"); |
|
371 | 377 |
return(1); |
372 | 378 |
} |
373 | 379 |
flag_ignorelmb=0; |
... | ... |
@@ -507,6 +513,7 @@ im_t * |
507 | 513 |
im_init(char *menus, char *rootdir) |
508 | 514 |
{ |
509 | 515 |
im_t *im; |
516 |
+ char *errstr; |
|
510 | 517 |
if(menus==NULL) |
511 | 518 |
return(NULL); /* sanity check failed */ |
512 | 519 |
if((im=calloc(1,sizeof(im_t)))==NULL) { |
... | ... |
@@ -519,12 +526,16 @@ im_init(char *menus, char *rootdir) |
519 | 526 |
im->windowinit=1; |
520 | 527 |
SetTargetFPS(30); |
521 | 528 |
/* init fonts and contents */ |
522 |
- if((im->font=im_font_init(FONTSIZE))==NULL |
|
529 |
+ if((errstr="Couldn't init font")==NULL |
|
530 |
+ || (im->font=im_font_init(FONTSIZE))==NULL |
|
523 | 531 |
|| (im->fontbig=im_font_init(FONTBIGSIZE))==NULL |
524 | 532 |
|| (im->fonthuge=im_font_init(FONTHUGESIZE))==NULL |
533 |
+ || (errstr="Couldn't init menus")==NULL |
|
525 | 534 |
|| (im->menubar=im_menubar_init(menus,im->font))==NULL |
535 |
+ || (errstr="Couldn't init interface data")==NULL |
|
526 | 536 |
|| (im->body=im_body_init(0,im->menubar->height, im->font, im->fontbig, im->fonthuge, LEFTSIZE, rootdir,im->w,im->h))==NULL |
527 | 537 |
) { |
538 |
+ messagebox(errstr); |
|
528 | 539 |
im_free(im),im=NULL; |
529 | 540 |
return(NULL); /* insuf. mem. */ |
530 | 541 |
} |
... | ... |
@@ -827,13 +838,20 @@ body_t * |
827 | 838 |
im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight) |
828 | 839 |
{ |
829 | 840 |
body_t *body; |
841 |
+ char *errstr; |
|
830 | 842 |
static char sep[]={SEP}; |
831 |
- if(font==NULL || fontbig==NULL || fonthuge==NULL || rootdir==NULL) |
|
843 |
+ if(font==NULL || fontbig==NULL || fonthuge==NULL || rootdir==NULL) { |
|
844 |
+ messagebox("im_body_init sanity check failed"); |
|
832 | 845 |
return(NULL); /* sanity check failed */ |
833 |
- if((body=calloc(1,sizeof(body_t)))==NULL |
|
846 |
+ } |
|
847 |
+ if((errstr="Insuf. mem. for body")==NULL |
|
848 |
+ || (body=calloc(1,sizeof(body_t)))==NULL |
|
849 |
+ || (errstr="Insuf. mem. for rootdir str")==NULL |
|
834 | 850 |
|| (body->rootdir=strdup(rootdir))==NULL |
851 |
+ || (errstr="Error init bg")==NULL |
|
835 | 852 |
|| (body->bg=bg_init(SIZEBGLOAD))==NULL |
836 | 853 |
) { |
854 |
+ messagebox(errstr); |
|
837 | 855 |
im_body_free(body),body=NULL; |
838 | 856 |
return(NULL); |
839 | 857 |
} |
... | ... |
@@ -1962,16 +1980,23 @@ bg_t * |
1962 | 1980 |
bg_init(int sizebgload) |
1963 | 1981 |
{ |
1964 | 1982 |
bg_t *bg; |
1983 |
+ char *errstr; |
|
1965 | 1984 |
bg=NULL; |
1966 |
- if((bg=calloc(1,sizeof(bg_t)))==NULL |
|
1985 |
+ if((errstr="Insuf. mem. for bg")==NULL |
|
1986 |
+ || (bg=calloc(1,sizeof(bg_t)))==NULL |
|
1987 |
+ || (errstr="Error init pipes (please check program is not blocked in firewall)")==NULL |
|
1967 | 1988 |
|| (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
1968 | 1989 |
|| mypipe(bg->pipe)!=0 |
1990 |
+ || (errstr="Insuf mem bgload")==NULL |
|
1969 | 1991 |
|| (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
1970 | 1992 |
|| (bg->sizebgload=sizebgload)!=sizebgload |
1993 |
+ || (errstr="pthread attr init error")==NULL |
|
1971 | 1994 |
|| pthread_attr_init(&(bg->tattr))!=0 |
1995 |
+ || (errstr="pthread create error")==NULL |
|
1972 | 1996 |
|| pthread_create(&(bg->thread),&(bg->tattr),bg_thread,(void *)bg)!=0 |
1973 | 1997 |
|| (bg->flag_threadstarted=1)!=1 |
1974 | 1998 |
) { |
1999 |
+ messagebox(errstr); |
|
1975 | 2000 |
bg_free(bg); |
1976 | 2001 |
return(NULL); |
1977 | 2002 |
} |
... | ... |
@@ -59,9 +59,9 @@ |
59 | 59 |
|
60 | 60 |
#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
61 | 61 |
|
62 |
-#ifndef ANDROID |
|
63 |
-#define SIMANDROID |
|
64 |
-#endif |
|
62 |
+//#ifndef ANDROID |
|
63 |
+//#define SIMANDROID |
|
64 |
+//#endif |
|
65 | 65 |
|
66 | 66 |
#define TARGETFPS 30 |
67 | 67 |
|
... | ... |
@@ -78,7 +78,14 @@ |
78 | 78 |
#define FONTHUGESIZE 128 |
79 | 79 |
#define ADDREMOVEDIRDATAHEIGHT 128 |
80 | 80 |
#else |
81 |
-#define ROOTDIR "/var/www/default/animeshot/" |
|
81 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
82 |
+#define ROOTDIR "Z:\\" |
|
83 |
+#define SEP "\\" |
|
84 |
+#else |
|
85 |
+//#define ROOTDIR "/var/www/default/animeshot/" |
|
86 |
+#define ROOTDIR "/" |
|
87 |
+#define SEP "/" |
|
88 |
+#endif |
|
82 | 89 |
#define DEFAULTWIDTH 1280 |
83 | 90 |
#define DEFAULTHEIGHT 768 |
84 | 91 |
#define LEFTSIZE 720 |
... | ... |
@@ -100,7 +107,6 @@ |
100 | 107 |
|
101 | 108 |
#define WHEELSTEP LEFTIMAGESIDELEN |
102 | 109 |
|
103 |
-#define SEP "/" |
|
104 | 110 |
|
105 | 111 |
#define BLOCKLISTINGBUF 2048 |
106 | 112 |
#define BLOCKLISTINGELEMS 1024 |
... | ... |
@@ -359,6 +365,9 @@ main(int argc, char *argv[]) |
359 | 365 |
win32pipe_init(); |
360 | 366 |
#endif |
361 | 367 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
368 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
369 |
+ MessageBoxA(NULL,"Couldn't init interface","imgmover",0); |
|
370 |
+#endif |
|
362 | 371 |
return(1); |
363 | 372 |
} |
364 | 373 |
flag_ignorelmb=0; |
... | ... |
@@ -34,6 +34,7 @@ |
34 | 34 |
* 20250330 Refine background loading. |
35 | 35 |
* 20250413 Background loading for windows target. |
36 | 36 |
* 20250420 Fix background loading for windows target. |
37 |
+ * 20250427 Start move image functionality. |
|
37 | 38 |
* |
38 | 39 |
* Author: Dario Rodriguez dario@darionomono.com |
39 | 40 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -265,6 +266,7 @@ typedef struct body_t { |
265 | 266 |
xywh_t dirdataadd; |
266 | 267 |
Font roundedbox; |
267 | 268 |
bg_t *bg; |
269 |
+ char selectedpath[2048]; |
|
268 | 270 |
} body_t; |
269 | 271 |
|
270 | 272 |
typedef struct im_t { |
... | ... |
@@ -295,6 +297,8 @@ body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthu |
295 | 297 |
void im_body_free(body_t *body); |
296 | 298 |
|
297 | 299 |
int im_body_add(body_t *body,char *dir); |
300 |
+int im_body_tryselect(body_t *body, Vector2 mousepos); |
|
301 |
+ |
|
298 | 302 |
|
299 | 303 |
int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
300 | 304 |
int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw, int scrollspeed); |
... | ... |
@@ -363,6 +367,7 @@ main(int argc, char *argv[]) |
363 | 367 |
needs_nextredraw=1; |
364 | 368 |
scrollstart=0; |
365 | 369 |
is_scrolling=0; |
370 |
+ im->body->selectedpath[0]='\0'; |
|
366 | 371 |
while(!WindowShouldClose()) { |
367 | 372 |
imutil_fpsreset(); |
368 | 373 |
oldmousepos=mousepos; |
... | ... |
@@ -399,8 +404,12 @@ main(int argc, char *argv[]) |
399 | 404 |
} |
400 | 405 |
t=scrollstartpos.x-mousepos.x; |
401 | 406 |
t=(t<0)?-t:t; |
402 |
- if(t>SCROLLTHRESHOLD) |
|
407 |
+ if(t>SCROLLTHRESHOLD) { |
|
403 | 408 |
is_scrolling=0,scrollstart=0; |
409 |
+ im_body_tryselect(im->body,scrollstartpos); |
|
410 |
+ if(im->body->selectedpath[0]!='\0') |
|
411 |
+ click_avail=0; |
|
412 |
+ } |
|
404 | 413 |
} |
405 | 414 |
if(is_scrolling) { |
406 | 415 |
long long tcur,tdif; |
... | ... |
@@ -668,7 +677,7 @@ im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbre |
668 | 677 |
*sel_menu=NULL; |
669 | 678 |
*sel_submenu=NULL; |
670 | 679 |
flag_outsideall=1; |
671 |
-#if 1 |
|
680 |
+#if 0 |
|
672 | 681 |
if(lmbpressed || lmbdown) |
673 | 682 |
fprintf(stderr,"in_menubar_mouse: lmbpressed:%i lmbdown:%i\n",lmbpressed,lmbdown); |
674 | 683 |
#endif |
... | ... |
@@ -896,6 +905,30 @@ im_body_add(body_t *body,char *dir) |
896 | 905 |
return(0); |
897 | 906 |
} |
898 | 907 |
|
908 |
+int |
|
909 |
+im_body_tryselect(body_t *body, Vector2 mousepos) |
|
910 |
+{ |
|
911 |
+ int i; |
|
912 |
+ listing_t *listing; |
|
913 |
+ listingdata_t *elem; |
|
914 |
+ if(body==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL || body->currentdirdata>=body->sizedirdata) |
|
915 |
+ return(-1); /* sanity check failed */ |
|
916 |
+ body->selectedpath[0]='\0'; |
|
917 |
+ if(!is_imutil_insidexywh(mousepos,&(body->xywh),0) || mousepos.x>body->leftsize) |
|
918 |
+ return(-1); /* outside leftside */ |
|
919 |
+ listing=&(body->dirdata[body->currentdirdata]->listing); |
|
920 |
+ for(i=0;i<listing->usedelems;i++) { |
|
921 |
+ elem=listing->elems+i; |
|
922 |
+ if(is_imutil_insidexywh(mousepos,&(elem->left.screenxywh),0)) { |
|
923 |
+ strncpy(body->selectedpath,elem->name,sizeof(body->selectedpath)); |
|
924 |
+ body->selectedpath[sizeof(body->selectedpath)-1]='\0'; |
|
925 |
+ return(0); /* found */ |
|
926 |
+ } |
|
927 |
+ } |
|
928 |
+ return(-1); /* no thumbnail found for pos */ |
|
929 |
+} |
|
930 |
+ |
|
931 |
+ |
|
899 | 932 |
int |
900 | 933 |
im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
901 | 934 |
{ |
... | ... |
@@ -922,7 +955,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
922 | 955 |
return(0); /* nothing else to do */ |
923 | 956 |
} |
924 | 957 |
margin=body->ptrfont->height/4; |
925 |
- if(body->is_displayingtexture && lmbreleased && is_imutil_insidexywh(mousepos,&(body->texture.source),margin)) { |
|
958 |
+ if(body->is_displayingtexture && lmbreleased && is_imutil_insidexywh(mousepos,&(body->texture.source),margin) && body->selectedpath[0]=='\0') { |
|
926 | 959 |
body->flag_drawbigtexture=1; |
927 | 960 |
return(0); /* nothing else to do */ |
928 | 961 |
} |
... | ... |
@@ -970,28 +1003,51 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
970 | 1003 |
return(0); |
971 | 1004 |
} |
972 | 1005 |
} |
973 |
- /* dirdata select */ |
|
974 |
- if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
975 |
- int righty; |
|
976 |
- for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
977 |
- if(body->dirdata[i]==NULL) |
|
978 |
- continue; |
|
979 |
- if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata) { |
|
980 |
- body->currentdirdata=i; |
|
981 |
- *click_avail=0; |
|
982 |
- return(0); |
|
1006 |
+ /* dirdata processing */ |
|
1007 |
+ if(body->selectedpath[0]=='\0') { |
|
1008 |
+ /* dirdata select */ |
|
1009 |
+ if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
1010 |
+ int righty; |
|
1011 |
+ for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
1012 |
+ if(body->dirdata[i]==NULL) |
|
1013 |
+ continue; |
|
1014 |
+ if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata) { |
|
1015 |
+ body->currentdirdata=i; |
|
1016 |
+ *click_avail=0; |
|
1017 |
+ return(0); |
|
1018 |
+ } |
|
1019 |
+ righty+=body->dirdata[i]->height; |
|
983 | 1020 |
} |
984 |
- righty+=body->dirdata[i]->height; |
|
985 | 1021 |
} |
1022 |
+ /* detect click on "add dirdata" button */ |
|
1023 |
+ if(is_imutil_insidexywh(mousepos,&(body->dirdataadd),0)) { |
|
1024 |
+ im_body_add(body,body->dirdata[body->currentdirdata]->dirname); |
|
1025 |
+ *click_avail=0; |
|
1026 |
+ return(0); |
|
1027 |
+ } |
|
1028 |
+ /* dirdata remove */ |
|
1029 |
+#warning TODO |
|
986 | 1030 |
} |
987 |
- /* detect click on "add dirdata" button */ |
|
988 |
- if(is_imutil_insidexywh(mousepos,&(body->dirdataadd),0)) { |
|
989 |
- im_body_add(body,body->dirdata[body->currentdirdata]->dirname); |
|
990 |
- *click_avail=0; |
|
991 |
- return(0); |
|
992 |
- } |
|
993 |
- /* dirdata remove */ |
|
1031 |
+ /* unselect selectedpath */ |
|
1032 |
+ if(lmbpressed==0 && body->selectedpath[0]!='\0') { |
|
1033 |
+ if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
1034 |
+ int righty; |
|
1035 |
+ for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
1036 |
+ if(body->dirdata[i]==NULL) |
|
1037 |
+ continue; |
|
1038 |
+ if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
994 | 1039 |
#warning TODO |
1040 |
+#if 1 |
|
1041 |
+fprintf(stderr,"WOULD MOVE \"%s/%s\" to \"%s\"\n",body->dirdata[body->currentdirdata]->dirname,body->selectedpath+1,body->dirdata[i]->dirname); |
|
1042 |
+#endif |
|
1043 |
+ *click_avail=0; |
|
1044 |
+ break; |
|
1045 |
+ } |
|
1046 |
+ righty+=body->dirdata[i]->height; |
|
1047 |
+ } |
|
1048 |
+ } |
|
1049 |
+ body->selectedpath[0]='\0'; |
|
1050 |
+ } |
|
995 | 1051 |
return(0); |
996 | 1052 |
} |
997 | 1053 |
|
... | ... |
@@ -1010,6 +1066,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1010 | 1066 |
int xoff,yoff; |
1011 | 1067 |
thumb_t *thumb; |
1012 | 1068 |
char statustooltip[1024]; |
1069 |
+ thumb_t *selectedthumb; |
|
1013 | 1070 |
if(body==NULL) |
1014 | 1071 |
return(-1); |
1015 | 1072 |
font=body->ptrfont; |
... | ... |
@@ -1018,6 +1075,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
1018 | 1075 |
FILLXYWH(body->backxywh,0,0,0,0); |
1019 | 1076 |
margin=font->height/4; |
1020 | 1077 |
body->is_displayingtexture=0; |
1078 |
+ selectedthumb=NULL; |
|
1021 | 1079 |
/* if we are displaying a full screenimage... */ |
1022 | 1080 |
if(body->flag_drawbigtexture && body->texture.has_texture) { |
1023 | 1081 |
/* draw image in full screen */ |
... | ... |
@@ -1256,6 +1314,17 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1256 | 1314 |
DrawTextEx(font->font,shortname,(Vector2){pos->x+xoff+font->height/4,pos->y+yoff+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
1257 | 1315 |
lastx=xywh->x+xoff+xywh->w,lasty=xywh->y+yoff+xywh->h; |
1258 | 1316 |
} |
1317 |
+ /* show selected rectangle */ |
|
1318 |
+ if(is_leftside && strcmp(body->selectedpath,elem->name)==0) { |
|
1319 |
+ Color c=((Color){0,0,255,64}); |
|
1320 |
+ DrawRectangle(UNROLLXYWH(thumb->screenxywh),c); |
|
1321 |
+ c=((Color){0,0,255,255}); |
|
1322 |
+ DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y,thumb->screenxywh.w,2,c); |
|
1323 |
+ DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y+2,2,thumb->screenxywh.h-4,c); |
|
1324 |
+ DrawRectangle(thumb->screenxywh.x+thumb->screenxywh.w-2,thumb->screenxywh.y+2,2,thumb->screenxywh.h-4,c); |
|
1325 |
+ DrawRectangle(thumb->screenxywh.x,thumb->screenxywh.y+thumb->screenxywh.h-2,thumb->screenxywh.w,2,c); |
|
1326 |
+ selectedthumb=thumb; |
|
1327 |
+ } |
|
1259 | 1328 |
} |
1260 | 1329 |
for(;k<dirdata->listing.usedelems;k++) { |
1261 | 1330 |
elem=dirdata->listing.elems+k; |
... | ... |
@@ -1271,6 +1340,16 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1271 | 1340 |
if(i==body->currentdirdata) { |
1272 | 1341 |
/* draw right side "current" marker inside left side area */ |
1273 | 1342 |
DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
1343 |
+ } else if(body->selectedpath[0]!='\0' && mousepos.x>body->leftsize && mousepos.y>=righty && mousepos.y<(righty+dirdata->height) && strcmp(body->dirdata[i]->dirname,body->dirdata[body->currentdirdata]->dirname)!=0) { |
|
1344 |
+ xywh_t xywh; |
|
1345 |
+ Color c=((Color){0,0,255,64}); |
|
1346 |
+ FILLXYWH(xywh,body->leftsize,righty,body->xywh.w-body->leftsize,dirdata->height); |
|
1347 |
+ DrawRectangle(UNROLLXYWH(xywh),c); |
|
1348 |
+ c=((Color){0,0,255,255}); |
|
1349 |
+ DrawRectangle(xywh.x,xywh.y,xywh.w,2,c); |
|
1350 |
+ DrawRectangle(xywh.x,xywh.y+2,2,xywh.h-4,c); |
|
1351 |
+ DrawRectangle(xywh.x+xywh.w-2,xywh.y+2,2,xywh.h-4,c); |
|
1352 |
+ DrawRectangle(xywh.x,xywh.y+xywh.h-2,xywh.w,2,c); |
|
1274 | 1353 |
} |
1275 | 1354 |
/* advance to next element */ |
1276 | 1355 |
righty+=dirdata->height; |
... | ... |
@@ -1306,6 +1385,12 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1306 | 1385 |
} else { |
1307 | 1386 |
memset(&(body->dirdataadd),0,sizeof(body->dirdataadd)); |
1308 | 1387 |
} |
1388 |
+ /* if moving elem, show line from orig to mousepos */ |
|
1389 |
+ if(body->selectedpath[0]!='\0' && selectedthumb!=NULL) { |
|
1390 |
+ Color c=((Color){0,0,255,255}); |
|
1391 |
+ DrawLineEx((Vector2){(float)(selectedthumb->screenxywh.x+selectedthumb->screenxywh.w/2),(float)(selectedthumb->screenxywh.y+selectedthumb->screenxywh.h/2)},mousepos,2.0,c); |
|
1392 |
+ } |
|
1393 |
+ /* show tooltip */ |
|
1309 | 1394 |
if(statustooltip[0]!='\0') { |
1310 | 1395 |
m2=MeasureTextEx(font->font,statustooltip,font->height,0); |
1311 | 1396 |
DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
... | ... |
@@ -33,6 +33,7 @@ |
33 | 33 |
* 20250329 Background loading of thumbnails. |
34 | 34 |
* 20250330 Refine background loading. |
35 | 35 |
* 20250413 Background loading for windows target. |
36 |
+ * 20250420 Fix background loading for windows target. |
|
36 | 37 |
* |
37 | 38 |
* Author: Dario Rodriguez dario@darionomono.com |
38 | 39 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -48,6 +49,9 @@ |
48 | 49 |
#include <sys/stat.h> |
49 | 50 |
#include <sys/time.h> |
50 | 51 |
#include <pthread.h> |
52 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
53 |
+#include "win32_pipe.h" |
|
54 |
+#endif |
|
51 | 55 |
|
52 | 56 |
#include "raylib.h" |
53 | 57 |
#include "roboto_regular.c" |
... | ... |
@@ -328,6 +332,8 @@ int bg_freeunmarked(bg_t *bg); |
328 | 332 |
void *bg_thread(void *); |
329 | 333 |
|
330 | 334 |
static int mypipe(int fds[2]); |
335 |
+static int mypiperead(int fd, char *buf, int count); |
|
336 |
+static int mypipewrite(int fd, char *buf, int count); |
|
331 | 337 |
|
332 | 338 |
int |
333 | 339 |
main(int argc, char *argv[]) |
... | ... |
@@ -345,6 +351,9 @@ main(int argc, char *argv[]) |
345 | 351 |
int is_scrolling; |
346 | 352 |
int leftscrollposstart; |
347 | 353 |
char *sel_menu,*sel_submenu; |
354 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
355 |
+ win32pipe_init(); |
|
356 |
+#endif |
|
348 | 357 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
349 | 358 |
return(1); |
350 | 359 |
} |
... | ... |
@@ -470,6 +479,9 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
470 | 479 |
EndDrawing(); |
471 | 480 |
} |
472 | 481 |
im_free(im),im=NULL; |
482 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
483 |
+ win32pipe_fini(); |
|
484 |
+#endif |
|
473 | 485 |
return(0); |
474 | 486 |
} |
475 | 487 |
|
... | ... |
@@ -656,6 +668,10 @@ im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbre |
656 | 668 |
*sel_menu=NULL; |
657 | 669 |
*sel_submenu=NULL; |
658 | 670 |
flag_outsideall=1; |
671 |
+#if 1 |
|
672 |
+if(lmbpressed || lmbdown) |
|
673 |
+ fprintf(stderr,"in_menubar_mouse: lmbpressed:%i lmbdown:%i\n",lmbpressed,lmbdown); |
|
674 |
+#endif |
|
659 | 675 |
for(i=0;i<menubar->sizemenudata;i++) { |
660 | 676 |
int insidetitle,currentoption; |
661 | 677 |
insidetitle=is_imutil_insidexywh(mousepos,&(menubar->menudata[i]->xywh),0); |
... | ... |
@@ -1877,8 +1893,17 @@ bg_free(bg_t *bg) |
1877 | 1893 |
return; /* nothing to do */ |
1878 | 1894 |
if(bg->flag_threadstarted) { |
1879 | 1895 |
char dummy=1; |
1880 |
- write(bg->pipe[WR],&dummy,1); |
|
1896 |
+#if 1 |
|
1897 |
+fprintf(stderr,"bg_free: notifying thread to exit\n"); |
|
1898 |
+#endif |
|
1899 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
1900 |
+#if 1 |
|
1901 |
+fprintf(stderr,"bg_free: joining thread\n"); |
|
1902 |
+#endif |
|
1881 | 1903 |
pthread_join(bg->thread,NULL); |
1904 |
+#if 1 |
|
1905 |
+fprintf(stderr,"bg_free: thread joined OK\n"); |
|
1906 |
+#endif |
|
1882 | 1907 |
bg->flag_threadstarted=0; |
1883 | 1908 |
} |
1884 | 1909 |
if(bg->pipe[0]!=-1) |
... | ... |
@@ -1934,7 +1959,7 @@ bg_add(bg_t *bg, char *path) |
1934 | 1959 |
{ |
1935 | 1960 |
int i; |
1936 | 1961 |
bgload_t *bgload; |
1937 |
- int dummy; |
|
1962 |
+ char dummy; |
|
1938 | 1963 |
if(bg==NULL) |
1939 | 1964 |
return(-1); |
1940 | 1965 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
... | ... |
@@ -1942,7 +1967,7 @@ bg_add(bg_t *bg, char *path) |
1942 | 1967 |
bgload->is_todo=1; |
1943 | 1968 |
bgload->has_mark=1; |
1944 | 1969 |
dummy=0; |
1945 |
- write(bg->pipe[WR],&dummy,1); |
|
1970 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
1946 | 1971 |
return(0); /* already on list */ |
1947 | 1972 |
} |
1948 | 1973 |
} |
... | ... |
@@ -1955,7 +1980,7 @@ bg_add(bg_t *bg, char *path) |
1955 | 1980 |
bgload->has_mark=1; |
1956 | 1981 |
dummy=0; |
1957 | 1982 |
bgload->lended_to_thread=1; |
1958 |
- write(bg->pipe[WR],&dummy,1); |
|
1983 |
+ mypipewrite(bg->pipe[WR],&dummy,1); |
|
1959 | 1984 |
return(0); /* added to list */ |
1960 | 1985 |
} |
1961 | 1986 |
} |
... | ... |
@@ -1998,7 +2023,10 @@ bg_thread(void *parambg) |
1998 | 2023 |
int i; |
1999 | 2024 |
bgload_t *bgload; |
2000 | 2025 |
while(1) { |
2001 |
- read(bg->pipe[RD],&dummy,1); |
|
2026 |
+ mypiperead(bg->pipe[RD],&dummy,1); |
|
2027 |
+#if 1 |
|
2028 |
+fprintf(stderr,"Thread received byte: %i\n",(int)((unsigned char)dummy)); |
|
2029 |
+#endif |
|
2002 | 2030 |
if(dummy!=0) |
2003 | 2031 |
break; /* was told to exit */ |
2004 | 2032 |
for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
... | ... |
@@ -2019,20 +2047,45 @@ bg_thread(void *parambg) |
2019 | 2047 |
} |
2020 | 2048 |
} |
2021 | 2049 |
pthread_exit(NULL); |
2050 |
+ return(NULL); |
|
2022 | 2051 |
} |
2023 | 2052 |
|
2024 | 2053 |
#if !defined(__linux__) && !defined(ANDROID) |
2025 |
-#include "win32_pipe.h" |
|
2026 | 2054 |
static int |
2027 | 2055 |
mypipe(int fds[2]) |
2028 | 2056 |
{ |
2029 |
- return(win32_pipe(fds)); |
|
2057 |
+ return(win32pipe_pipe(fds)); |
|
2058 |
+} |
|
2059 |
+ |
|
2060 |
+static int |
|
2061 |
+mypiperead(int fd, char *buf, int count) |
|
2062 |
+{ |
|
2063 |
+ return(win32pipe_read(fd,buf,count)); |
|
2064 |
+} |
|
2065 |
+ |
|
2066 |
+static int |
|
2067 |
+mypipewrite(int fd, char *buf, int count) |
|
2068 |
+{ |
|
2069 |
+ return(win32pipe_write(fd,buf,count)); |
|
2030 | 2070 |
} |
2031 | 2071 |
#else |
2032 | 2072 |
static int |
2033 |
-mypipe(char fds[2]) |
|
2073 |
+mypipe(int fds[2]) |
|
2034 | 2074 |
{ |
2035 | 2075 |
return(pipe(fds)); |
2036 | 2076 |
} |
2077 |
+ |
|
2078 |
+static int |
|
2079 |
+mypiperead(int fd, char *buf, int count) |
|
2080 |
+{ |
|
2081 |
+ return(read(fd,buf,count)); |
|
2082 |
+} |
|
2083 |
+ |
|
2084 |
+static int |
|
2085 |
+mypipewrite(int fd, char *buf, int count) |
|
2086 |
+{ |
|
2087 |
+ return(write(fd,buf,count)); |
|
2088 |
+} |
|
2037 | 2089 |
#endif |
2038 | 2090 |
|
2091 |
+ |
... | ... |
@@ -32,6 +32,7 @@ |
32 | 32 |
* Dirdata colors. Select dirdata. |
33 | 33 |
* 20250329 Background loading of thumbnails. |
34 | 34 |
* 20250330 Refine background loading. |
35 |
+ * 20250413 Background loading for windows target. |
|
35 | 36 |
* |
36 | 37 |
* Author: Dario Rodriguez dario@darionomono.com |
37 | 38 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -326,6 +327,8 @@ int bg_freeunmarked(bg_t *bg); |
326 | 327 |
|
327 | 328 |
void *bg_thread(void *); |
328 | 329 |
|
330 |
+static int mypipe(int fds[2]); |
|
331 |
+ |
|
329 | 332 |
int |
330 | 333 |
main(int argc, char *argv[]) |
331 | 334 |
{ |
... | ... |
@@ -1852,7 +1855,7 @@ bg_init(int sizebgload) |
1852 | 1855 |
bg=NULL; |
1853 | 1856 |
if((bg=calloc(1,sizeof(bg_t)))==NULL |
1854 | 1857 |
|| (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
1855 |
- || pipe(bg->pipe)!=0 |
|
1858 |
+ || mypipe(bg->pipe)!=0 |
|
1856 | 1859 |
|| (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
1857 | 1860 |
|| (bg->sizebgload=sizebgload)!=sizebgload |
1858 | 1861 |
|| pthread_attr_init(&(bg->tattr))!=0 |
... | ... |
@@ -2018,3 +2021,18 @@ bg_thread(void *parambg) |
2018 | 2021 |
pthread_exit(NULL); |
2019 | 2022 |
} |
2020 | 2023 |
|
2024 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
2025 |
+#include "win32_pipe.h" |
|
2026 |
+static int |
|
2027 |
+mypipe(int fds[2]) |
|
2028 |
+{ |
|
2029 |
+ return(win32_pipe(fds)); |
|
2030 |
+} |
|
2031 |
+#else |
|
2032 |
+static int |
|
2033 |
+mypipe(char fds[2]) |
|
2034 |
+{ |
|
2035 |
+ return(pipe(fds)); |
|
2036 |
+} |
|
2037 |
+#endif |
|
2038 |
+ |
... | ... |
@@ -31,6 +31,7 @@ |
31 | 31 |
* 20250320 Fix add-dirdata button appearance. |
32 | 32 |
* Dirdata colors. Select dirdata. |
33 | 33 |
* 20250329 Background loading of thumbnails. |
34 |
+ * 20250330 Refine background loading. |
|
34 | 35 |
* |
35 | 36 |
* Author: Dario Rodriguez dario@darionomono.com |
36 | 37 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -291,7 +292,7 @@ void im_body_free(body_t *body); |
291 | 292 |
int im_body_add(body_t *body,char *dir); |
292 | 293 |
|
293 | 294 |
int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
294 |
-int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw); |
|
295 |
+int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw, int scrollspeed); |
|
295 | 296 |
|
296 | 297 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
297 | 298 |
void listing_freedata(listing_t *listing); |
... | ... |
@@ -421,7 +422,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
421 | 422 |
/* draw screen contents */ |
422 | 423 |
BeginDrawing(); |
423 | 424 |
ClearBackground(RAYWHITE); |
424 |
- im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h,&needs_nextredraw); |
|
425 |
+ im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h,&needs_nextredraw,scrollspeed); |
|
425 | 426 |
im_menubar_draw(im->menubar,im->w,im->h,&needs_nextredraw); |
426 | 427 |
#if 0 |
427 | 428 |
{ |
... | ... |
@@ -976,7 +977,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
976 | 977 |
} |
977 | 978 |
|
978 | 979 |
int |
979 |
-im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw) |
|
980 |
+im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw, int scrollspeed) |
|
980 | 981 |
{ |
981 | 982 |
int i,k,margin,righty; |
982 | 983 |
int lastx,lasty; |
... | ... |
@@ -1142,7 +1143,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1142 | 1143 |
} |
1143 | 1144 |
/* show image */ |
1144 | 1145 |
has_imagedrawn=0; |
1145 |
- if(is_imagefilename(elem->name+1)) { |
|
1146 |
+ if(is_imagefilename(elem->name+1) && !(thumb->screenxywh.y>(body->xywh.y+body->xywh.h) || (thumb->screenxywh.y+thumb->screenxywh.h)<body->xywh.y)) { |
|
1146 | 1147 |
if(thumb->has_texture==0 && thumb->has_failedload==0) { |
1147 | 1148 |
bgload_t *bgload; |
1148 | 1149 |
char fullpath[2048]; |
... | ... |
@@ -1189,7 +1190,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1189 | 1190 |
DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE); |
1190 | 1191 |
has_imagedrawn=1; |
1191 | 1192 |
lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff; |
1192 |
- if(is_leftside && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
1193 |
+ if(is_leftside && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin) && scrollspeed==0) { |
|
1193 | 1194 |
/* draw image in rightside */ |
1194 | 1195 |
char fullpath[2048]; |
1195 | 1196 |
int maxw,maxh; |
... | ... |
@@ -1291,8 +1292,9 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1291 | 1292 |
DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
1292 | 1293 |
DrawTextEx(font->font,statustooltip,(Vector2){margin,windowheight-1-margin-font->height},font->height,0,(Color){ 255,255,255,128 }); |
1293 | 1294 |
} |
1294 |
- /* free not used bg load items */ |
|
1295 |
- bg_freeunmarked(body->bg); |
|
1295 |
+ /* free not used bg load items (only if idle, as it takes time) */ |
|
1296 |
+ if(scrollspeed==0 && *needs_nextredraw==0) |
|
1297 |
+ bg_freeunmarked(body->bg); |
|
1296 | 1298 |
return(0); |
1297 | 1299 |
} |
1298 | 1300 |
|
... | ... |
@@ -30,6 +30,7 @@ |
30 | 30 |
* 20250319 Add-dirdata button. |
31 | 31 |
* 20250320 Fix add-dirdata button appearance. |
32 | 32 |
* Dirdata colors. Select dirdata. |
33 |
+ * 20250329 Background loading of thumbnails. |
|
33 | 34 |
* |
34 | 35 |
* Author: Dario Rodriguez dario@darionomono.com |
35 | 36 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -44,6 +45,7 @@ |
44 | 45 |
#include <dirent.h> |
45 | 46 |
#include <sys/stat.h> |
46 | 47 |
#include <sys/time.h> |
48 |
+#include <pthread.h> |
|
47 | 49 |
|
48 | 50 |
#include "raylib.h" |
49 | 51 |
#include "roboto_regular.c" |
... | ... |
@@ -96,6 +98,7 @@ |
96 | 98 |
#define BLOCKLISTINGBUF 2048 |
97 | 99 |
#define BLOCKLISTINGELEMS 1024 |
98 | 100 |
#define BLOCKDIRDATA 16 |
101 |
+#define SIZEBGLOAD 256 |
|
99 | 102 |
|
100 | 103 |
#ifndef FILLXY |
101 | 104 |
#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
... | ... |
@@ -117,6 +120,15 @@ |
117 | 120 |
#define UNROLLWHXY(xywh) (xywh).w,(xywh).h,(xywh).x,(xywh).y |
118 | 121 |
#endif |
119 | 122 |
|
123 |
+#ifndef RD |
|
124 |
+#define RD 0 |
|
125 |
+#endif |
|
126 |
+ |
|
127 |
+#ifndef WR |
|
128 |
+#define WR 1 |
|
129 |
+#endif |
|
130 |
+ |
|
131 |
+ |
|
120 | 132 |
#if !defined(__linux__) && !defined(ANDROID) |
121 | 133 |
/* the old raylib used in the windows build lacks this function */ |
122 | 134 |
bool IsImageValid(Image image) |
... | ... |
@@ -206,6 +218,28 @@ typedef struct texture_t { |
206 | 218 |
xywh_t source; /* be able to detect a "double click" */ |
207 | 219 |
} texture_t; |
208 | 220 |
|
221 |
+typedef struct bgload_t { |
|
222 |
+ /* main/thread ownership management */ |
|
223 |
+ int lended_to_thread; // written from main, read from thread |
|
224 |
+ int thread_finished; // written from thread, read from main |
|
225 |
+ int is_todo; // written from main, read from thread |
|
226 |
+ int has_mark; // written/read from main |
|
227 |
+ /* data only accessed from owner */ |
|
228 |
+ char path[1024]; // to use only from owner |
|
229 |
+ Image image; // to use only from owner |
|
230 |
+ int has_data; // to use only from owner |
|
231 |
+ int has_failedload; // to use only from owner |
|
232 |
+} bgload_t; |
|
233 |
+ |
|
234 |
+typedef struct bg_t { |
|
235 |
+ int sizebgload; |
|
236 |
+ bgload_t *bgload; |
|
237 |
+ int pipe[2]; |
|
238 |
+ pthread_t thread; |
|
239 |
+ pthread_attr_t tattr; |
|
240 |
+ int flag_threadstarted; |
|
241 |
+} bg_t; |
|
242 |
+ |
|
209 | 243 |
typedef struct body_t { |
210 | 244 |
char *rootdir; |
211 | 245 |
xywh_t xywh; |
... | ... |
@@ -224,6 +258,7 @@ typedef struct body_t { |
224 | 258 |
int flag_drawbigtexture; |
225 | 259 |
xywh_t dirdataadd; |
226 | 260 |
Font roundedbox; |
261 |
+ bg_t *bg; |
|
227 | 262 |
} body_t; |
228 | 263 |
|
229 | 264 |
typedef struct im_t { |
... | ... |
@@ -262,7 +297,7 @@ int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort) |
262 | 297 |
void listing_freedata(listing_t *listing); |
263 | 298 |
int listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_left); |
264 | 299 |
|
265 |
-int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh); |
|
300 |
+int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg); |
|
266 | 301 |
int texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh); |
267 | 302 |
int texture_freedata(texture_t *texture); |
268 | 303 |
|
... | ... |
@@ -281,6 +316,15 @@ void imutil_fpsreset(void); |
281 | 316 |
int imutil_fpsleft(void); |
282 | 317 |
long long imutil_milliseconds(void); |
283 | 318 |
|
319 |
+bg_t *bg_init(int sizebgload); |
|
320 |
+void bg_free(bg_t *bg); |
|
321 |
+int bg_resetmarks(bg_t *bg); |
|
322 |
+bgload_t *bg_get(bg_t *bg, char *path); |
|
323 |
+int bg_add(bg_t *bg, char *path); |
|
324 |
+int bg_freeunmarked(bg_t *bg); |
|
325 |
+ |
|
326 |
+void *bg_thread(void *); |
|
327 |
+ |
|
284 | 328 |
int |
285 | 329 |
main(int argc, char *argv[]) |
286 | 330 |
{ |
... | ... |
@@ -412,7 +456,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
412 | 456 |
} |
413 | 457 |
} |
414 | 458 |
#endif |
415 |
- if(has_mousechanges==0 && needs_nextredraw==0) { |
|
459 |
+ if(has_mousechanges==0 && needs_nextredraw==0 && scrollspeed==0) { |
|
416 | 460 |
/* Wait for new events when calling EndDrawing() */ |
417 | 461 |
EnableEventWaiting(); |
418 | 462 |
} else { |
... | ... |
@@ -750,6 +794,7 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
750 | 794 |
return(NULL); /* sanity check failed */ |
751 | 795 |
if((body=calloc(1,sizeof(body_t)))==NULL |
752 | 796 |
|| (body->rootdir=strdup(rootdir))==NULL |
797 |
+ || (body->bg=bg_init(SIZEBGLOAD))==NULL |
|
753 | 798 |
) { |
754 | 799 |
im_body_free(body),body=NULL; |
755 | 800 |
return(NULL); |
... | ... |
@@ -792,6 +837,8 @@ im_body_free(body_t *body) |
792 | 837 |
if(body->rootdir!=NULL) |
793 | 838 |
free(body->rootdir),body->rootdir=NULL; |
794 | 839 |
/* NOTE: Cannot call UnloadFont(body->roundedbox) as the data was not malloc'd; see https://github.com/raysan5/raylib/blob/master/examples/others/embedded_files_loading.c */ |
840 |
+ if(body->bg!=NULL) |
|
841 |
+ bg_free(body->bg),body->bg=NULL; |
|
795 | 842 |
free(body),body=NULL; |
796 | 843 |
return; |
797 | 844 |
} |
... | ... |
@@ -958,7 +1005,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
958 | 1005 |
maxw=windowwidth; |
959 | 1006 |
maxh=windowheight-body->xywh.y; |
960 | 1007 |
if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0) |
961 |
- texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh); |
|
1008 |
+ texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh,body->bg); |
|
962 | 1009 |
if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,body->texture.currentpath)==0) { |
963 | 1010 |
int x0,y0; |
964 | 1011 |
x0=0; |
... | ... |
@@ -988,6 +1035,8 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
988 | 1035 |
DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
989 | 1036 |
/* draw right side background */ |
990 | 1037 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
1038 |
+ /* reset lazy load marks */ |
|
1039 |
+ bg_resetmarks(body->bg); |
|
991 | 1040 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
992 | 1041 |
statustooltip[0]='\0'; |
993 | 1042 |
for(is_leftside=1,flag_skiprightside=flag_skipall=0;is_leftside>=0 && flag_skiprightside==0 && flag_skipall==0;is_leftside--) { |
... | ... |
@@ -1094,40 +1143,45 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1094 | 1143 |
/* show image */ |
1095 | 1144 |
has_imagedrawn=0; |
1096 | 1145 |
if(is_imagefilename(elem->name+1)) { |
1097 |
- if(thumb->has_texture==0 && thumb->has_failedload==0 && imutil_fpsleft()==0) { |
|
1098 |
- *needs_nextredraw=1; |
|
1099 |
- } else if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
1100 |
- Image im; |
|
1146 |
+ if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
1147 |
+ bgload_t *bgload; |
|
1101 | 1148 |
char fullpath[2048]; |
1149 |
+ *needs_nextredraw=1; |
|
1102 | 1150 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
1103 | 1151 |
fullpath[sizeof(fullpath)-1]='\0'; |
1104 |
- im=imutil_loadimage(fullpath); |
|
1105 |
- if(IsImageValid(im)) { |
|
1106 |
- int neww,newh; |
|
1107 |
- Image im2,impixel; |
|
1152 |
+ bgload=bg_get(body->bg,fullpath); |
|
1153 |
+ if(bgload!=NULL && bgload->has_data!=0) { |
|
1154 |
+ Image im; |
|
1155 |
+ im=ImageCopy(bgload->image); |
|
1156 |
+ if(IsImageValid(im)) { |
|
1157 |
+ int neww,newh; |
|
1158 |
+ Image im2,impixel; |
|
1108 | 1159 |
#if 1 |
1109 | 1160 |
fprintf(stderr,"Loaded %s\n",fullpath); |
1110 | 1161 |
{ |
1111 | 1162 |
int oldw=im.width,oldh=im.height; |
1112 | 1163 |
#endif |
1113 |
- im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
|
1114 |
- imutil_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
1115 |
- ImageResize(&im,neww,newh); |
|
1116 |
- impixel=ImageCopy(im); |
|
1117 |
- ImageResize(&impixel,1,1); |
|
1164 |
+ im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
|
1165 |
+ imutil_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
1166 |
+ ImageResize(&im,neww,newh); |
|
1167 |
+ impixel=ImageCopy(im); |
|
1168 |
+ ImageResize(&impixel,1,1); |
|
1118 | 1169 |
#if 1 |
1119 | 1170 |
if(neww>sidelen || newh>sidelen) |
1120 | 1171 |
fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidelen,oldw,oldh,neww,newh); |
1121 | 1172 |
} |
1122 | 1173 |
#endif |
1123 |
- ImageDraw(&im2,impixel,(Rectangle) {0,0,1,1},(Rectangle) {0,0,sidelen,sidelen},(Color){255,255,255,255}); |
|
1124 |
- ImageDraw(&im2,im,(Rectangle) {0,0,neww,newh},(Rectangle) {(sidelen-neww)/2,(sidelen-newh)/2,neww,newh},(Color){255,255,255,255}); |
|
1125 |
- *te=LoadTextureFromImage(im2); |
|
1126 |
- UnloadImage(im); |
|
1127 |
- UnloadImage(im2); |
|
1128 |
- thumb->has_texture=1; |
|
1129 |
- } else { |
|
1130 |
- thumb->has_failedload=1; |
|
1174 |
+ ImageDraw(&im2,impixel,(Rectangle) {0,0,1,1},(Rectangle) {0,0,sidelen,sidelen},(Color){255,255,255,255}); |
|
1175 |
+ ImageDraw(&im2,im,(Rectangle) {0,0,neww,newh},(Rectangle) {(sidelen-neww)/2,(sidelen-newh)/2,neww,newh},(Color){255,255,255,255}); |
|
1176 |
+ *te=LoadTextureFromImage(im2); |
|
1177 |
+ UnloadImage(im); |
|
1178 |
+ UnloadImage(im2); |
|
1179 |
+ thumb->has_texture=1; |
|
1180 |
+ } else { |
|
1181 |
+ thumb->has_failedload=1; |
|
1182 |
+ } |
|
1183 |
+ } else if(bgload==NULL) { |
|
1184 |
+ bg_add(body->bg,fullpath); |
|
1131 | 1185 |
} |
1132 | 1186 |
} |
1133 | 1187 |
if(thumb->has_texture!=0) { |
... | ... |
@@ -1146,7 +1200,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1146 | 1200 |
if((body->texture.has_texture==0 && !(body->texture.has_failedload && strcmp(body->texture.currentpath,fullpath)==0)) |
1147 | 1201 |
|| strcmp(body->texture.currentpath,fullpath)!=0 |
1148 | 1202 |
) { |
1149 |
- texture_load(&(body->texture),fullpath,maxw,maxh); |
|
1203 |
+ texture_load(&(body->texture),fullpath,maxw,maxh,body->bg); |
|
1150 | 1204 |
} |
1151 | 1205 |
if(body->texture.has_texture && strcmp(body->texture.currentpath,fullpath)==0) { |
1152 | 1206 |
int x0,y0; |
... | ... |
@@ -1237,14 +1291,17 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1237 | 1291 |
DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
1238 | 1292 |
DrawTextEx(font->font,statustooltip,(Vector2){margin,windowheight-1-margin-font->height},font->height,0,(Color){ 255,255,255,128 }); |
1239 | 1293 |
} |
1294 |
+ /* free not used bg load items */ |
|
1295 |
+ bg_freeunmarked(body->bg); |
|
1240 | 1296 |
return(0); |
1241 | 1297 |
} |
1242 | 1298 |
|
1243 | 1299 |
int |
1244 |
-texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
|
1300 |
+texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg) |
|
1245 | 1301 |
{ |
1246 | 1302 |
Image im; |
1247 | 1303 |
int neww,newh; |
1304 |
+ bgload_t *bgload; |
|
1248 | 1305 |
if(texture==NULL || fullpath==NULL) |
1249 | 1306 |
return(-1); /* sanity check failed */ |
1250 | 1307 |
if(texture->has_texture) { |
... | ... |
@@ -1254,7 +1311,11 @@ texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
1254 | 1311 |
texture->has_failedload=0; |
1255 | 1312 |
} |
1256 | 1313 |
texture->currentpath[0]='\0'; |
1257 |
- im=imutil_loadimage(fullpath); |
|
1314 |
+ if(bg!=NULL && (bgload=bg_get(bg,texture->currentpath))!=NULL && bgload->has_data!=0) { |
|
1315 |
+ im=ImageCopy(bgload->image); |
|
1316 |
+ } else { |
|
1317 |
+ im=imutil_loadimage(fullpath); |
|
1318 |
+ } |
|
1258 | 1319 |
if(IsImageValid(im)) { |
1259 | 1320 |
imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
1260 | 1321 |
ImageResize(&im,neww,newh); |
... | ... |
@@ -1782,3 +1843,176 @@ imutil_milliseconds(void) |
1782 | 1843 |
return(res); |
1783 | 1844 |
} |
1784 | 1845 |
|
1846 |
+bg_t * |
|
1847 |
+bg_init(int sizebgload) |
|
1848 |
+{ |
|
1849 |
+ bg_t *bg; |
|
1850 |
+ bg=NULL; |
|
1851 |
+ if((bg=calloc(1,sizeof(bg_t)))==NULL |
|
1852 |
+ || (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
|
1853 |
+ || pipe(bg->pipe)!=0 |
|
1854 |
+ || (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
|
1855 |
+ || (bg->sizebgload=sizebgload)!=sizebgload |
|
1856 |
+ || pthread_attr_init(&(bg->tattr))!=0 |
|
1857 |
+ || pthread_create(&(bg->thread),&(bg->tattr),bg_thread,(void *)bg)!=0 |
|
1858 |
+ || (bg->flag_threadstarted=1)!=1 |
|
1859 |
+ ) { |
|
1860 |
+ bg_free(bg); |
|
1861 |
+ return(NULL); |
|
1862 |
+ } |
|
1863 |
+ return(bg); |
|
1864 |
+} |
|
1865 |
+ |
|
1866 |
+ |
|
1867 |
+void |
|
1868 |
+bg_free(bg_t *bg) |
|
1869 |
+{ |
|
1870 |
+ int i; |
|
1871 |
+ if(bg==NULL) |
|
1872 |
+ return; /* nothing to do */ |
|
1873 |
+ if(bg->flag_threadstarted) { |
|
1874 |
+ char dummy=1; |
|
1875 |
+ write(bg->pipe[WR],&dummy,1); |
|
1876 |
+ pthread_join(bg->thread,NULL); |
|
1877 |
+ bg->flag_threadstarted=0; |
|
1878 |
+ } |
|
1879 |
+ if(bg->pipe[0]!=-1) |
|
1880 |
+ close(bg->pipe[0]),bg->pipe[0]=-1; |
|
1881 |
+ if(bg->pipe[1]!=-1) |
|
1882 |
+ close(bg->pipe[1]),bg->pipe[1]=-1; |
|
1883 |
+ if(bg->bgload!=NULL) { |
|
1884 |
+ bgload_t *bgload; |
|
1885 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1886 |
+ if(bgload->has_data) { |
|
1887 |
+ UnloadImage(bgload->image); |
|
1888 |
+ bgload->has_data=0; |
|
1889 |
+ } |
|
1890 |
+ } |
|
1891 |
+ free(bg->bgload),bg->bgload=NULL,bg->sizebgload=0; |
|
1892 |
+ } |
|
1893 |
+ return; |
|
1894 |
+} |
|
1895 |
+ |
|
1896 |
+int |
|
1897 |
+bg_resetmarks(bg_t *bg) |
|
1898 |
+{ |
|
1899 |
+ int i; |
|
1900 |
+ bgload_t *bgload; |
|
1901 |
+ if(bg==NULL) |
|
1902 |
+ return(-1); |
|
1903 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) |
|
1904 |
+ bgload->has_mark=0; |
|
1905 |
+ return(0); |
|
1906 |
+} |
|
1907 |
+ |
|
1908 |
+bgload_t * |
|
1909 |
+bg_get(bg_t *bg, char *path) |
|
1910 |
+{ |
|
1911 |
+ int i; |
|
1912 |
+ bgload_t *bgload; |
|
1913 |
+ if(bg==NULL) |
|
1914 |
+ return(NULL); |
|
1915 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1916 |
+ if(bgload->thread_finished && bgload->has_data && strcmp(path,bgload->path)==0) { |
|
1917 |
+ bgload->has_mark=1; |
|
1918 |
+#if 1 |
|
1919 |
+fprintf(stderr,"bg_get: \"%s\"\n",bgload->path); |
|
1920 |
+#endif |
|
1921 |
+ return(bgload); |
|
1922 |
+ } |
|
1923 |
+ } |
|
1924 |
+ return(NULL); |
|
1925 |
+} |
|
1926 |
+ |
|
1927 |
+int |
|
1928 |
+bg_add(bg_t *bg, char *path) |
|
1929 |
+{ |
|
1930 |
+ int i; |
|
1931 |
+ bgload_t *bgload; |
|
1932 |
+ int dummy; |
|
1933 |
+ if(bg==NULL) |
|
1934 |
+ return(-1); |
|
1935 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1936 |
+ if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
|
1937 |
+ bgload->is_todo=1; |
|
1938 |
+ bgload->has_mark=1; |
|
1939 |
+ dummy=0; |
|
1940 |
+ write(bg->pipe[WR],&dummy,1); |
|
1941 |
+ return(0); /* already on list */ |
|
1942 |
+ } |
|
1943 |
+ } |
|
1944 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1945 |
+ if(bgload->lended_to_thread==0) { |
|
1946 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
1947 |
+ strncpy(bgload->path,path,sizeof(bgload->path)); |
|
1948 |
+ bgload->path[sizeof(bgload->path)-1]='\0'; |
|
1949 |
+ bgload->is_todo=1; |
|
1950 |
+ bgload->has_mark=1; |
|
1951 |
+ dummy=0; |
|
1952 |
+ bgload->lended_to_thread=1; |
|
1953 |
+ write(bg->pipe[WR],&dummy,1); |
|
1954 |
+ return(0); /* added to list */ |
|
1955 |
+ } |
|
1956 |
+ } |
|
1957 |
+ return(-1); /* couldn't add */ |
|
1958 |
+} |
|
1959 |
+ |
|
1960 |
+int |
|
1961 |
+bg_freeunmarked(bg_t *bg) |
|
1962 |
+{ |
|
1963 |
+ int i; |
|
1964 |
+ bgload_t *bgload; |
|
1965 |
+ if(bg==NULL) |
|
1966 |
+ return(-1); |
|
1967 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1968 |
+ if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
|
1969 |
+ if(bgload->has_data) { |
|
1970 |
+#if 1 |
|
1971 |
+fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
|
1972 |
+#endif |
|
1973 |
+ UnloadImage(bgload->image); |
|
1974 |
+ bgload->has_data=0; |
|
1975 |
+ } |
|
1976 |
+#if 1 |
|
1977 |
+else { |
|
1978 |
+fprintf(stderr,"bg: Cancelling: \"%s\"\n",bgload->path); |
|
1979 |
+} |
|
1980 |
+#endif |
|
1981 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
1982 |
+ } |
|
1983 |
+ } |
|
1984 |
+ return(0); |
|
1985 |
+} |
|
1986 |
+ |
|
1987 |
+void * |
|
1988 |
+bg_thread(void *parambg) |
|
1989 |
+{ |
|
1990 |
+ bg_t *bg; |
|
1991 |
+ char dummy; |
|
1992 |
+ bg=(bg_t *)parambg; |
|
1993 |
+ int i; |
|
1994 |
+ bgload_t *bgload; |
|
1995 |
+ while(1) { |
|
1996 |
+ read(bg->pipe[RD],&dummy,1); |
|
1997 |
+ if(dummy!=0) |
|
1998 |
+ break; /* was told to exit */ |
|
1999 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2000 |
+ if(bgload->lended_to_thread==0) |
|
2001 |
+ continue; |
|
2002 |
+ if(bgload->is_todo==0) { |
|
2003 |
+ bgload->thread_finished=1; |
|
2004 |
+ continue; |
|
2005 |
+ } |
|
2006 |
+ if(bgload->has_data==0 && bgload->has_failedload==0) { |
|
2007 |
+ bgload->image=imutil_loadimage(bgload->path); |
|
2008 |
+ if(IsImageValid(bgload->image)) |
|
2009 |
+ bgload->has_data=1; |
|
2010 |
+ else |
|
2011 |
+ bgload->has_failedload=1; |
|
2012 |
+ bgload->thread_finished=1; |
|
2013 |
+ } |
|
2014 |
+ } |
|
2015 |
+ } |
|
2016 |
+ pthread_exit(NULL); |
|
2017 |
+} |
|
2018 |
+ |
... | ... |
@@ -29,6 +29,7 @@ |
29 | 29 |
* Scroll by finger. Big image on double click. |
30 | 30 |
* 20250319 Add-dirdata button. |
31 | 31 |
* 20250320 Fix add-dirdata button appearance. |
32 |
+ * Dirdata colors. Select dirdata. |
|
32 | 33 |
* |
33 | 34 |
* Author: Dario Rodriguez dario@darionomono.com |
34 | 35 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -192,6 +193,7 @@ typedef struct dirdata_t { |
192 | 193 |
int height; |
193 | 194 |
char *dirname; |
194 | 195 |
listing_t listing; |
196 |
+ int leftscrollpos; |
|
195 | 197 |
} dirdata_t; |
196 | 198 |
|
197 | 199 |
typedef struct texture_t { |
... | ... |
@@ -212,7 +214,6 @@ typedef struct body_t { |
212 | 214 |
int sizedirdata; |
213 | 215 |
dirdata_t **dirdata; |
214 | 216 |
int currentdirdata; |
215 |
- int leftscrollpos; |
|
216 | 217 |
int rightscrollpos; |
217 | 218 |
font_t *ptrfont; |
218 | 219 |
font_t *ptrfontbig; |
... | ... |
@@ -323,7 +324,7 @@ main(int argc, char *argv[]) |
323 | 324 |
if(lmbdown==1 && oldlmbdown==0 && scrollstart==0 && mousepos.y>im->body->xywh.y) { |
324 | 325 |
scrollstart=imutil_milliseconds(); |
325 | 326 |
scrollstartpos=mousepos; |
326 |
- leftscrollposstart=im->body->leftscrollpos; |
|
327 |
+ leftscrollposstart=im->body->dirdata[im->body->currentdirdata]->leftscrollpos; |
|
327 | 328 |
} |
328 | 329 |
if(scrollstart!=0 && lmbdown==0) { |
329 | 330 |
scrollstart=0; |
... | ... |
@@ -351,12 +352,12 @@ main(int argc, char *argv[]) |
351 | 352 |
tdif=tcur-scrolllast; |
352 | 353 |
ycur=scrollstartpos.y-mousepos.y; |
353 | 354 |
scrollspeed=(tdif>0)?(oldmousepos.y-mousepos.y)*100000/tdif:0; |
354 |
- im->body->leftscrollpos=leftscrollposstart+ycur; |
|
355 |
+ im->body->dirdata[im->body->currentdirdata]->leftscrollpos=leftscrollposstart+ycur; |
|
355 | 356 |
scrolllast=tcur; |
356 | 357 |
} |
357 | 358 |
if(is_scrolling==0 && scrollspeed!=0) { |
358 | 359 |
scrollspeed=scrollspeed*4/5; |
359 |
- im->body->leftscrollpos+=scrollspeed; |
|
360 |
+ im->body->dirdata[im->body->currentdirdata]->leftscrollpos+=scrollspeed; |
|
360 | 361 |
} |
361 | 362 |
/* process clicks on menus */ |
362 | 363 |
if(click_avail) { |
... | ... |
@@ -840,10 +841,10 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
840 | 841 |
return(-1); /* sanity check error */ |
841 | 842 |
dirdata=body->dirdata[body->currentdirdata]; |
842 | 843 |
/* wheel */ |
843 |
- body->leftscrollpos-=(int)wheel.y*WHEELSTEP; |
|
844 |
- body->leftscrollpos=(body->leftscrollpos<0)?0:body->leftscrollpos; |
|
845 |
- if(body->leftscrollpos>dirdata->listing.lastleftxywh.y) |
|
846 |
- body->leftscrollpos=dirdata->listing.lastleftxywh.y; |
|
844 |
+ body->dirdata[body->currentdirdata]->leftscrollpos-=(int)wheel.y*WHEELSTEP; |
|
845 |
+ body->dirdata[body->currentdirdata]->leftscrollpos=(body->dirdata[body->currentdirdata]->leftscrollpos<0)?0:body->dirdata[body->currentdirdata]->leftscrollpos; |
|
846 |
+ if(body->dirdata[body->currentdirdata]->leftscrollpos>dirdata->listing.lastleftxywh.y) |
|
847 |
+ body->dirdata[body->currentdirdata]->leftscrollpos=dirdata->listing.lastleftxywh.y; |
|
847 | 848 |
/* check if we have to process a click */ |
848 | 849 |
if(*click_avail==0 || lmbreleased==0) |
849 | 850 |
return(0); /* nothing else to do */ |
... | ... |
@@ -869,7 +870,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
869 | 870 |
dirdata->dirname[0]='\0'; |
870 | 871 |
} |
871 | 872 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
872 |
- body->leftscrollpos=0; |
|
873 |
+ body->dirdata[body->currentdirdata]->leftscrollpos=0; |
|
873 | 874 |
*click_avail=0; |
874 | 875 |
return(0); |
875 | 876 |
} |
... | ... |
@@ -897,13 +898,25 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
897 | 898 |
free(dirdata->dirname),dirdata->dirname=NULL; |
898 | 899 |
dirdata->dirname=newname; |
899 | 900 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
900 |
- body->leftscrollpos=0; |
|
901 |
+ body->dirdata[body->currentdirdata]->leftscrollpos=0; |
|
901 | 902 |
*click_avail=0; |
902 | 903 |
return(0); |
903 | 904 |
} |
904 | 905 |
} |
905 | 906 |
/* dirdata select */ |
906 |
-#warning TODO |
|
907 |
+ if(mousepos.x>body->leftsize && mousepos.y>body->xywh.y) { |
|
908 |
+ int righty; |
|
909 |
+ for(righty=body->xywh.y,i=0;i<body->sizedirdata;i++) { |
|
910 |
+ if(body->dirdata[i]==NULL) |
|
911 |
+ continue; |
|
912 |
+ if(mousepos.y>=righty && mousepos.y<(righty+body->dirdata[i]->height) && i!=body->currentdirdata) { |
|
913 |
+ body->currentdirdata=i; |
|
914 |
+ *click_avail=0; |
|
915 |
+ return(0); |
|
916 |
+ } |
|
917 |
+ righty+=body->dirdata[i]->height; |
|
918 |
+ } |
|
919 |
+ } |
|
907 | 920 |
/* detect click on "add dirdata" button */ |
908 | 921 |
if(is_imutil_insidexywh(mousepos,&(body->dirdataadd),0)) { |
909 | 922 |
im_body_add(body,body->dirdata[body->currentdirdata]->dirname); |
... | ... |
@@ -989,7 +1002,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
989 | 1002 |
if(is_leftside && !(dirdata->dirname[0]=='\0' || strcmp(dirdata->dirname,SEP)==0)) { |
990 | 1003 |
m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
991 | 1004 |
v2.x=(float) (body->xywh.x+fontbig->height/2); |
992 |
- v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2)-body->leftscrollpos; |
|
1005 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2)-body->dirdata[body->currentdirdata]->leftscrollpos; |
|
993 | 1006 |
FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
994 | 1007 |
#if 0 |
995 | 1008 |
DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
... | ... |
@@ -1000,7 +1013,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1000 | 1013 |
} |
1001 | 1014 |
if(is_leftside) { |
1002 | 1015 |
/* ...dirname */ |
1003 |
- v2.y=(float) (body->xywh.y+fontbig->height/4-body->leftscrollpos); |
|
1016 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4-body->dirdata[body->currentdirdata]->leftscrollpos); |
|
1004 | 1017 |
if((v2.y+fontbig->height)>=0) { |
1005 | 1018 |
m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
1006 | 1019 |
v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
... | ... |
@@ -1023,12 +1036,12 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1023 | 1036 |
,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
1024 | 1037 |
,fontbig->height |
1025 | 1038 |
,0 |
1026 |
- ,(Color){ 240, 240, 240, 255 } |
|
1039 |
+ ,(i==body->currentdirdata)?((Color){ 240, 240, 240, 255 }):((Color){ 65, 65, 65, 255 }) |
|
1027 | 1040 |
); |
1028 | 1041 |
} |
1029 | 1042 |
/* directories */ |
1030 | 1043 |
xoff=((is_leftside)?0:body->leftsize); |
1031 |
- yoff=((is_leftside)?body->xywh.y:righty)+fontbig->height/4+fontbig->height+font->height/4-(is_leftside?body->leftscrollpos:0); |
|
1044 |
+ yoff=((is_leftside)?body->xywh.y:righty)+fontbig->height/4+fontbig->height+font->height/4-(is_leftside?body->dirdata[body->currentdirdata]->leftscrollpos:0); |
|
1032 | 1045 |
if(is_leftside && dirdata->dirname[0]=='\0') |
1033 | 1046 |
yoff-=fontbig->height/4+fontbig->height; |
1034 | 1047 |
for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
... | ... |
@@ -28,6 +28,7 @@ |
28 | 28 |
* Delay loading images if over fps deadline. |
29 | 29 |
* Scroll by finger. Big image on double click. |
30 | 30 |
* 20250319 Add-dirdata button. |
31 |
+ * 20250320 Fix add-dirdata button appearance. |
|
31 | 32 |
* |
32 | 33 |
* Author: Dario Rodriguez dario@darionomono.com |
33 | 34 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -77,7 +78,7 @@ |
77 | 78 |
#define FONTSIZE 18 |
78 | 79 |
#define FONTBIGSIZE 32 |
79 | 80 |
#define FONTHUGESIZE 48 |
80 |
-#define ADDREMOVEDIRDATAHEIGHT 64 |
|
81 |
+#define ADDREMOVEDIRDATAHEIGHT 128 |
|
81 | 82 |
#endif |
82 | 83 |
|
83 | 84 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
... | ... |
@@ -1204,6 +1205,8 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1204 | 1205 |
,0.0 |
1205 | 1206 |
,(Color){ 168, 168, 168, 255 } |
1206 | 1207 |
); |
1208 |
+ DrawRectangle(body->dirdataadd.x+13+12,body->dirdataadd.y+13,body->dirdataadd.w-26-24, (float)body->dirdataadd.h-26,(Color){ 168, 168, 168, 255 }); |
|
1209 |
+ DrawRectangle(body->dirdataadd.x+13,body->dirdataadd.y+13+12,body->dirdataadd.w-26, (float)body->dirdataadd.h-26-24,(Color){ 168, 168, 168, 255 }); |
|
1207 | 1210 |
xoff+=gi.image.width+4; |
1208 | 1211 |
gi=GetGlyphInfo(body->roundedbox,'+'); |
1209 | 1212 |
DrawTexturePro(body->roundedbox.texture |
... | ... |
@@ -1211,7 +1214,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1211 | 1214 |
,(Rectangle) { (float) body->dirdataadd.x+30-2, (float) body->dirdataadd.y+30, (float) body->dirdataadd.w-60, (float)body->dirdataadd.h-60} |
1212 | 1215 |
,(Vector2){0.0,0.0} |
1213 | 1216 |
,0.0 |
1214 |
- ,(Color){ 168, 168, 168, 255 } |
|
1217 |
+ ,(Color){ 227, 227, 227, 255 } |
|
1215 | 1218 |
); |
1216 | 1219 |
} else { |
1217 | 1220 |
memset(&(body->dirdataadd),0,sizeof(body->dirdataadd)); |
... | ... |
@@ -27,6 +27,7 @@ |
27 | 27 |
* 20250316 Add android target support. |
28 | 28 |
* Delay loading images if over fps deadline. |
29 | 29 |
* Scroll by finger. Big image on double click. |
30 |
+ * 20250319 Add-dirdata button. |
|
30 | 31 |
* |
31 | 32 |
* Author: Dario Rodriguez dario@darionomono.com |
32 | 33 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -58,12 +59,13 @@ |
58 | 59 |
#define DEFAULTWIDTH 2400 |
59 | 60 |
#define DEFAULTHEIGHT 1080 |
60 | 61 |
#define LEFTSIZE 1600 |
61 |
-#define DEFAULTDIRDATAHEIGHT 520 |
|
62 |
+#define DEFAULTDIRDATAHEIGHT 492 |
|
62 | 63 |
#define DEFAULTDIRDATATRIANGLEW 100 |
63 | 64 |
#define LEFTIMAGESIDELEN 326 |
64 | 65 |
#define FONTSIZE 64 |
65 | 66 |
#define FONTBIGSIZE 96 |
66 | 67 |
#define FONTHUGESIZE 128 |
68 |
+#define ADDREMOVEDIRDATAHEIGHT 128 |
|
67 | 69 |
#else |
68 | 70 |
#define ROOTDIR "/var/www/default/animeshot/" |
69 | 71 |
#define DEFAULTWIDTH 1280 |
... | ... |
@@ -75,6 +77,7 @@ |
75 | 77 |
#define FONTSIZE 18 |
76 | 78 |
#define FONTBIGSIZE 32 |
77 | 79 |
#define FONTHUGESIZE 48 |
80 |
+#define ADDREMOVEDIRDATAHEIGHT 64 |
|
78 | 81 |
#endif |
79 | 82 |
|
80 | 83 |
#define SCROLLTHRESHOLD (LEFTIMAGESIDELEN/3) |
... | ... |
@@ -217,6 +220,8 @@ typedef struct body_t { |
217 | 220 |
int is_displayingtexture; |
218 | 221 |
texture_t bigtexture; |
219 | 222 |
int flag_drawbigtexture; |
223 |
+ xywh_t dirdataadd; |
|
224 |
+ Font roundedbox; |
|
220 | 225 |
} body_t; |
221 | 226 |
|
222 | 227 |
typedef struct im_t { |
... | ... |
@@ -754,6 +759,11 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
754 | 759 |
body->ptrfonthuge=fonthuge; |
755 | 760 |
if(body->rootdir[0]!='\0' && strcmp(body->rootdir,SEP)!=0 && body->rootdir[strlen(body->rootdir)-1]==sep[0]) |
756 | 761 |
body->rootdir[strlen(body->rootdir)-1]='\0'; /* rootdir doesn't need the final '/' */ |
762 |
+ /* init rounded box glyph (a really big zero) */ |
|
763 |
+ { |
|
764 |
+ int codepoints[]={'O','+','-'}; |
|
765 |
+ body->roundedbox=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,ADDREMOVEDIRDATAHEIGHT*4,codepoints,sizeof(codepoints)/sizeof(codepoints[0])); |
|
766 |
+ } |
|
757 | 767 |
return(body); |
758 | 768 |
} |
759 | 769 |
|
... | ... |
@@ -779,6 +789,7 @@ im_body_free(body_t *body) |
779 | 789 |
texture_freedata(&(body->bigtexture)); |
780 | 790 |
if(body->rootdir!=NULL) |
781 | 791 |
free(body->rootdir),body->rootdir=NULL; |
792 |
+ /* NOTE: Cannot call UnloadFont(body->roundedbox) as the data was not malloc'd; see https://github.com/raysan5/raylib/blob/master/examples/others/embedded_files_loading.c */ |
|
782 | 793 |
free(body),body=NULL; |
783 | 794 |
return; |
784 | 795 |
} |
... | ... |
@@ -890,6 +901,15 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
890 | 901 |
return(0); |
891 | 902 |
} |
892 | 903 |
} |
904 |
+ /* dirdata select */ |
|
905 |
+#warning TODO |
|
906 |
+ /* detect click on "add dirdata" button */ |
|
907 |
+ if(is_imutil_insidexywh(mousepos,&(body->dirdataadd),0)) { |
|
908 |
+ im_body_add(body,body->dirdata[body->currentdirdata]->dirname); |
|
909 |
+ *click_avail=0; |
|
910 |
+ return(0); |
|
911 |
+ } |
|
912 |
+ /* dirdata remove */ |
|
893 | 913 |
#warning TODO |
894 | 914 |
return(0); |
895 | 915 |
} |
... | ... |
@@ -1169,6 +1189,33 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1169 | 1189 |
} |
1170 | 1190 |
} |
1171 | 1191 |
} |
1192 |
+ if(flag_skiprightside==0 && (righty+DEFAULTDIRDATAHEIGHT)<=(body->xywh.y+body->xywh.h)) { |
|
1193 |
+ GlyphInfo gi; |
|
1194 |
+ int xoff; |
|
1195 |
+ int margin; |
|
1196 |
+ margin=20; |
|
1197 |
+ FILLXYWH(body->dirdataadd,(body->xywh.x+body->xywh.w-ADDREMOVEDIRDATAHEIGHT-margin),righty+margin,ADDREMOVEDIRDATAHEIGHT,ADDREMOVEDIRDATAHEIGHT); |
|
1198 |
+ gi=GetGlyphInfo(body->roundedbox,'O'); |
|
1199 |
+ xoff=0; |
|
1200 |
+ DrawTexturePro(body->roundedbox.texture |
|
1201 |
+ ,(Rectangle){0.0+xoff,0.0,(float)gi.image.width+5,(float)gi.image.height+2} |
|
1202 |
+ ,(Rectangle) { (float) body->dirdataadd.x, (float) body->dirdataadd.y, (float) body->dirdataadd.w, (float)body->dirdataadd.h} |
|
1203 |
+ ,(Vector2){0.0,0.0} |
|
1204 |
+ ,0.0 |
|
1205 |
+ ,(Color){ 168, 168, 168, 255 } |
|
1206 |
+ ); |
|
1207 |
+ xoff+=gi.image.width+4; |
|
1208 |
+ gi=GetGlyphInfo(body->roundedbox,'+'); |
|
1209 |
+ DrawTexturePro(body->roundedbox.texture |
|
1210 |
+ ,(Rectangle){xoff,0.0,(float)gi.image.width,(float)gi.image.height} |
|
1211 |
+ ,(Rectangle) { (float) body->dirdataadd.x+30-2, (float) body->dirdataadd.y+30, (float) body->dirdataadd.w-60, (float)body->dirdataadd.h-60} |
|
1212 |
+ ,(Vector2){0.0,0.0} |
|
1213 |
+ ,0.0 |
|
1214 |
+ ,(Color){ 168, 168, 168, 255 } |
|
1215 |
+ ); |
|
1216 |
+ } else { |
|
1217 |
+ memset(&(body->dirdataadd),0,sizeof(body->dirdataadd)); |
|
1218 |
+ } |
|
1172 | 1219 |
if(statustooltip[0]!='\0') { |
1173 | 1220 |
m2=MeasureTextEx(font->font,statustooltip,font->height,0); |
1174 | 1221 |
DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
... | ... |
@@ -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 |
+ |
... | ... |
@@ -25,6 +25,7 @@ |
25 | 25 |
* 20250311 Fix bug because of stray CloseWindow() call. |
26 | 26 |
* Add show using all window with right button. |
27 | 27 |
* 20250316 Add android target support. |
28 |
+ * Delay loading images if over fps deadline. |
|
28 | 29 |
* |
29 | 30 |
* Author: Dario Rodriguez dario@darionomono.com |
30 | 31 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -38,6 +39,7 @@ |
38 | 39 |
#include <sys/types.h> |
39 | 40 |
#include <dirent.h> |
40 | 41 |
#include <sys/stat.h> |
42 |
+#include <sys/time.h> |
|
41 | 43 |
|
42 | 44 |
#include "raylib.h" |
43 | 45 |
#include "roboto_regular.c" |
... | ... |
@@ -46,6 +48,8 @@ |
46 | 48 |
|
47 | 49 |
#define SIMANDROID |
48 | 50 |
|
51 |
+#define TARGETFPS 30 |
|
52 |
+ |
|
49 | 53 |
#if defined(ANDROID) || defined(SIMANDROID) |
50 | 54 |
#define ROOTDIR "/sdcard/" |
51 | 55 |
#define DEFAULTWIDTH 2400 |
... | ... |
@@ -229,7 +233,7 @@ menubar_t *im_menubar_init(char *menus, font_t *font); |
229 | 233 |
void im_menubar_free(menubar_t *menubar); |
230 | 234 |
|
231 | 235 |
int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
232 |
-int im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight); |
|
236 |
+int im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight, int *needs_nextredraw); |
|
233 | 237 |
|
234 | 238 |
body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight); |
235 | 239 |
void im_body_free(body_t *body); |
... | ... |
@@ -237,7 +241,7 @@ void im_body_free(body_t *body); |
237 | 241 |
int im_body_add(body_t *body,char *dir); |
238 | 242 |
|
239 | 243 |
int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
240 |
-int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight); |
|
244 |
+int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw); |
|
241 | 245 |
|
242 | 246 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
243 | 247 |
void listing_freedata(listing_t *listing); |
... | ... |
@@ -258,28 +262,47 @@ int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
258 | 262 |
int *getcodepoints(int *sizecodepoints); |
259 | 263 |
int is_imagefilename(char *filename); |
260 | 264 |
Image imutil_loadimage(const char *filename); |
265 |
+void imutil_fpsreset(void); |
|
266 |
+int imutil_fpsleft(void); |
|
261 | 267 |
|
262 | 268 |
int |
263 | 269 |
main(int argc, char *argv[]) |
264 | 270 |
{ |
265 | 271 |
im_t *im; |
266 |
- Vector2 mousepos,wheel; |
|
272 |
+ Vector2 mousepos,wheel,oldmousepos; |
|
267 | 273 |
int flag_ignorelmb; |
268 |
- int lmbpressed,lmbreleased,lmbdown,rmbdown; |
|
274 |
+ int lmbpressed,lmbreleased,lmbdown,rmbdown,oldlmbdown,oldrmbdown; |
|
269 | 275 |
int click_avail; |
276 |
+ int has_mousechanges; |
|
277 |
+ int needs_nextredraw; |
|
270 | 278 |
char *sel_menu,*sel_submenu; |
271 | 279 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
272 | 280 |
return(1); |
273 | 281 |
} |
274 | 282 |
flag_ignorelmb=0; |
283 |
+ mousepos=(Vector2) {.x=0,.y=0}; |
|
284 |
+ lmbdown=rmbdown=-1; |
|
285 |
+ needs_nextredraw=1; |
|
275 | 286 |
while(!WindowShouldClose()) { |
287 |
+ imutil_fpsreset(); |
|
288 |
+ oldmousepos=mousepos; |
|
276 | 289 |
mousepos=GetMousePosition(); |
277 | 290 |
wheel=GetMouseWheelMoveV(); |
278 | 291 |
lmbpressed=IsMouseButtonPressed(0); |
279 | 292 |
lmbreleased=IsMouseButtonReleased(0); |
293 |
+ oldlmbdown=lmbdown; |
|
280 | 294 |
lmbdown=IsMouseButtonDown(0); |
295 |
+ oldrmbdown=rmbdown; |
|
281 | 296 |
rmbdown=IsMouseButtonDown(1); |
282 | 297 |
click_avail=1; |
298 |
+ 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 |
+ needs_nextredraw=0; |
|
283 | 306 |
/* process clicks on menus */ |
284 | 307 |
if(click_avail) { |
285 | 308 |
sel_menu=sel_submenu=NULL; |
... | ... |
@@ -292,13 +315,11 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
292 | 315 |
} |
293 | 316 |
if(click_avail) |
294 | 317 |
im_body_mouse(im->body, mousepos, wheel, lmbpressed, lmbreleased, lmbdown, &click_avail); |
295 |
- |
|
296 |
- |
|
297 | 318 |
/* draw screen contents */ |
298 | 319 |
BeginDrawing(); |
299 | 320 |
ClearBackground(RAYWHITE); |
300 |
- im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h); |
|
301 |
- im_menubar_draw(im->menubar,im->w,im->h); |
|
321 |
+ im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h,&needs_nextredraw); |
|
322 |
+ im_menubar_draw(im->menubar,im->w,im->h,&needs_nextredraw); |
|
302 | 323 |
#if 0 |
303 | 324 |
{ |
304 | 325 |
int i,j; |
... | ... |
@@ -592,7 +613,7 @@ im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbre |
592 | 613 |
} |
593 | 614 |
|
594 | 615 |
int |
595 |
-im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight) |
|
616 |
+im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight, int *needs_nextredraw) |
|
596 | 617 |
{ |
597 | 618 |
int i,j,k,x; |
598 | 619 |
menudata_t *menudata; |
... | ... |
@@ -803,7 +824,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
803 | 824 |
} |
804 | 825 |
|
805 | 826 |
int |
806 |
-im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight) |
|
827 |
+im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight, int *needs_nextredraw) |
|
807 | 828 |
{ |
808 | 829 |
int i,k,margin,righty; |
809 | 830 |
int lastx,lasty; |
... | ... |
@@ -949,7 +970,9 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
949 | 970 |
/* show image */ |
950 | 971 |
has_imagedrawn=0; |
951 | 972 |
if(is_imagefilename(elem->name+1)) { |
952 |
- if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
973 |
+ if(thumb->has_texture==0 && thumb->has_failedload==0 && imutil_fpsleft()==0) { |
|
974 |
+ *needs_nextredraw=1; |
|
975 |
+ } else if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
953 | 976 |
Image im; |
954 | 977 |
char fullpath[2048]; |
955 | 978 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
... | ... |
@@ -1584,3 +1607,35 @@ imutil_loadimage(const char *filename) |
1584 | 1607 |
} |
1585 | 1608 |
#endif |
1586 | 1609 |
|
1610 |
+static void |
|
1611 |
+intimutil_fpsdata(struct timeval **deadline) |
|
1612 |
+{ |
|
1613 |
+ static struct timeval mydeadline; |
|
1614 |
+ *deadline=&(mydeadline); |
|
1615 |
+ return; |
|
1616 |
+} |
|
1617 |
+ |
|
1618 |
+void |
|
1619 |
+imutil_fpsreset(void) |
|
1620 |
+{ |
|
1621 |
+ struct timeval *deadline; |
|
1622 |
+ long deadlineincr; |
|
1623 |
+ intimutil_fpsdata(&deadline); |
|
1624 |
+ gettimeofday(deadline,NULL); |
|
1625 |
+ deadlineincr=1000000L/TARGETFPS; |
|
1626 |
+ deadline->tv_usec+=deadlineincr; |
|
1627 |
+ deadline->tv_sec+=(deadline->tv_usec)/1000000L; |
|
1628 |
+ deadline->tv_usec%=1000000L; |
|
1629 |
+} |
|
1630 |
+ |
|
1631 |
+int |
|
1632 |
+imutil_fpsleft(void) |
|
1633 |
+{ |
|
1634 |
+ struct timeval *deadline,now; |
|
1635 |
+ intimutil_fpsdata(&deadline); |
|
1636 |
+ gettimeofday(&now,NULL); |
|
1637 |
+ if(deadline->tv_sec<now.tv_sec || (deadline->tv_sec==now.tv_sec && deadline->tv_usec<now.tv_usec)) |
|
1638 |
+ return(0); |
|
1639 |
+ return(1); |
|
1640 |
+} |
|
1641 |
+ |
... | ... |
@@ -24,6 +24,7 @@ |
24 | 24 |
* Fix thumb aspect ratio. |
25 | 25 |
* 20250311 Fix bug because of stray CloseWindow() call. |
26 | 26 |
* Add show using all window with right button. |
27 |
+ * 20250316 Add android target support. |
|
27 | 28 |
* |
28 | 29 |
* Author: Dario Rodriguez dario@darionomono.com |
29 | 30 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -41,23 +42,40 @@ |
41 | 42 |
#include "raylib.h" |
42 | 43 |
#include "roboto_regular.c" |
43 | 44 |
|
44 |
-#define DEFAULTWIDTH 1280 |
|
45 |
-#define DEFAULTHEIGHT 768 |
|
46 |
- |
|
47 | 45 |
#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
48 | 46 |
|
47 |
+#define SIMANDROID |
|
48 |
+ |
|
49 |
+#if defined(ANDROID) || defined(SIMANDROID) |
|
50 |
+#define ROOTDIR "/sdcard/" |
|
51 |
+#define DEFAULTWIDTH 2400 |
|
52 |
+#define DEFAULTHEIGHT 1080 |
|
53 |
+#define LEFTSIZE 1600 |
|
54 |
+#define DEFAULTDIRDATAHEIGHT 520 |
|
55 |
+#define DEFAULTDIRDATATRIANGLEW 100 |
|
56 |
+#define LEFTIMAGESIDELEN 326 |
|
57 |
+#define FONTSIZE 64 |
|
58 |
+#define FONTBIGSIZE 96 |
|
59 |
+#define FONTHUGESIZE 128 |
|
60 |
+#else |
|
61 |
+#define ROOTDIR "/var/www/default/animeshot/" |
|
62 |
+#define DEFAULTWIDTH 1280 |
|
63 |
+#define DEFAULTHEIGHT 768 |
|
49 | 64 |
#define LEFTSIZE 720 |
50 | 65 |
#define DEFAULTDIRDATAHEIGHT 150 |
51 | 66 |
#define DEFAULTDIRDATATRIANGLEW 35 |
52 | 67 |
#define LEFTIMAGESIDELEN 125 |
53 |
- |
|
54 | 68 |
#define FONTSIZE 18 |
55 | 69 |
#define FONTBIGSIZE 32 |
56 | 70 |
#define FONTHUGESIZE 48 |
71 |
+#endif |
|
57 | 72 |
|
58 |
-#define WHEELSTEP LEFTIMAGESIDELEN |
|
59 |
- |
|
73 |
+#if defined(SIMANDROID) |
|
74 |
+#undef ROOTDIR |
|
60 | 75 |
#define ROOTDIR "/var/www/default/animeshot/" |
76 |
+#endif |
|
77 |
+ |
|
78 |
+#define WHEELSTEP LEFTIMAGESIDELEN |
|
61 | 79 |
|
62 | 80 |
#define SEP "/" |
63 | 81 |
|
... | ... |
@@ -85,7 +103,7 @@ |
85 | 103 |
#define UNROLLWHXY(xywh) (xywh).w,(xywh).h,(xywh).x,(xywh).y |
86 | 104 |
#endif |
87 | 105 |
|
88 |
-#ifndef __linux__ |
|
106 |
+#if !defined(__linux__) && !defined(ANDROID) |
|
89 | 107 |
/* the old raylib used in the windows build lacks this function */ |
90 | 108 |
bool IsImageValid(Image image) |
91 | 109 |
{ |
... | ... |
@@ -235,10 +253,11 @@ int imutil_submenu_count(char *menus); |
235 | 253 |
char *imutil_submenu_get(char *menus, int targetn, int *len); |
236 | 254 |
char *imutil_strduplen(char *str, int len); |
237 | 255 |
int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin); |
238 |
-int im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh); |
|
256 |
+int imutil_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh); |
|
239 | 257 |
int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
240 | 258 |
int *getcodepoints(int *sizecodepoints); |
241 | 259 |
int is_imagefilename(char *filename); |
260 |
+Image imutil_loadimage(const char *filename); |
|
242 | 261 |
|
243 | 262 |
int |
244 | 263 |
main(int argc, char *argv[]) |
... | ... |
@@ -935,7 +954,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
935 | 954 |
char fullpath[2048]; |
936 | 955 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
937 | 956 |
fullpath[sizeof(fullpath)-1]='\0'; |
938 |
- im=LoadImage(fullpath); |
|
957 |
+ im=imutil_loadimage(fullpath); |
|
939 | 958 |
if(IsImageValid(im)) { |
940 | 959 |
int neww,newh; |
941 | 960 |
Image im2,impixel; |
... | ... |
@@ -945,7 +964,7 @@ fprintf(stderr,"Loaded %s\n",fullpath); |
945 | 964 |
int oldw=im.width,oldh=im.height; |
946 | 965 |
#endif |
947 | 966 |
im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
948 |
- im_util_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
967 |
+ imutil_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
949 | 968 |
ImageResize(&im,neww,newh); |
950 | 969 |
impixel=ImageCopy(im); |
951 | 970 |
ImageResize(&impixel,1,1); |
... | ... |
@@ -1079,9 +1098,9 @@ texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
1079 | 1098 |
texture->has_failedload=0; |
1080 | 1099 |
} |
1081 | 1100 |
texture->currentpath[0]='\0'; |
1082 |
- im=LoadImage(fullpath); |
|
1101 |
+ im=imutil_loadimage(fullpath); |
|
1083 | 1102 |
if(IsImageValid(im)) { |
1084 |
- im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
1103 |
+ imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
1085 | 1104 |
ImageResize(&im,neww,newh); |
1086 | 1105 |
texture->texture=LoadTextureFromImage(im); |
1087 | 1106 |
UnloadImage(im); |
... | ... |
@@ -1239,7 +1258,7 @@ is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin) |
1239 | 1258 |
} |
1240 | 1259 |
|
1241 | 1260 |
int |
1242 |
-im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
|
1261 |
+imutil_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
|
1243 | 1262 |
{ |
1244 | 1263 |
if(neww==NULL || newh==NULL || w==0 || h==0 || maxw==0 || maxh==0) |
1245 | 1264 |
return(-1); |
... | ... |
@@ -1529,3 +1548,39 @@ is_imagefilename(char *filename) |
1529 | 1548 |
return(0); /* not in the knownext list */ |
1530 | 1549 |
} |
1531 | 1550 |
|
1551 |
+#ifdef ANDROID |
|
1552 |
+Image |
|
1553 |
+imutil_loadimage(const char *filename) |
|
1554 |
+{ |
|
1555 |
+ unsigned char *filedata=NULL; |
|
1556 |
+ FILE *f=NULL; |
|
1557 |
+ struct stat st; |
|
1558 |
+ Image img; |
|
1559 |
+ char *ext; |
|
1560 |
+ if((f=fopen(filename,"r"))==NULL |
|
1561 |
+ || fstat(fileno(f),&st)!=0 |
|
1562 |
+ || st.st_size<=0 |
|
1563 |
+ || (filedata=(unsigned char *)malloc(st.st_size))==NULL |
|
1564 |
+ || fread(filedata,1,st.st_size,f)!=st.st_size |
|
1565 |
+ ) { |
|
1566 |
+ if(f!=NULL) |
|
1567 |
+ fclose(f),f=NULL; |
|
1568 |
+ if(filedata!=NULL) |
|
1569 |
+ free(filedata),filedata=NULL; |
|
1570 |
+ return((Image){0}); |
|
1571 |
+ } |
|
1572 |
+ fclose(f); |
|
1573 |
+ ext=strchr(filename,'.'); |
|
1574 |
+ ext=(ext==NULL)?filename+strlen(filename):ext; |
|
1575 |
+ img=LoadImageFromMemory(ext,filedata,st.st_size); |
|
1576 |
+ free(filedata),filedata=NULL; |
|
1577 |
+ return(img); |
|
1578 |
+} |
|
1579 |
+#else |
|
1580 |
+Image |
|
1581 |
+imutil_loadimage(const char *filename) |
|
1582 |
+{ |
|
1583 |
+ return(LoadImage(filename)); |
|
1584 |
+} |
|
1585 |
+#endif |
|
1586 |
+ |
... | ... |
@@ -22,6 +22,8 @@ |
22 | 22 |
* 20250308 Show statustooltip on image hover. |
23 | 23 |
* Scrollwheel support for leftside. |
24 | 24 |
* Fix thumb aspect ratio. |
25 |
+ * 20250311 Fix bug because of stray CloseWindow() call. |
|
26 |
+ * Add show using all window with right button. |
|
25 | 27 |
* |
26 | 28 |
* Author: Dario Rodriguez dario@darionomono.com |
27 | 29 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -161,6 +163,15 @@ typedef struct dirdata_t { |
161 | 163 |
listing_t listing; |
162 | 164 |
} dirdata_t; |
163 | 165 |
|
166 |
+typedef struct texture_t { |
|
167 |
+ char currentpath[2048]; |
|
168 |
+ Texture2D texture; |
|
169 |
+ int texturew; |
|
170 |
+ int textureh; |
|
171 |
+ int has_texture; |
|
172 |
+ int has_failedload; |
|
173 |
+} texture_t; |
|
174 |
+ |
|
164 | 175 |
typedef struct body_t { |
165 | 176 |
char *rootdir; |
166 | 177 |
xywh_t xywh; |
... | ... |
@@ -174,12 +185,8 @@ typedef struct body_t { |
174 | 185 |
font_t *ptrfont; |
175 | 186 |
font_t *ptrfontbig; |
176 | 187 |
font_t *ptrfonthuge; |
177 |
- char currenttexture[2048]; |
|
178 |
- Texture2D texture; |
|
179 |
- int texturew; |
|
180 |
- int textureh; |
|
181 |
- int has_texture; |
|
182 |
- int has_failedload; |
|
188 |
+ texture_t texture; |
|
189 |
+ texture_t bigtexture; |
|
183 | 190 |
} body_t; |
184 | 191 |
|
185 | 192 |
typedef struct im_t { |
... | ... |
@@ -212,12 +219,16 @@ void im_body_free(body_t *body); |
212 | 219 |
int im_body_add(body_t *body,char *dir); |
213 | 220 |
|
214 | 221 |
int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
215 |
-int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight); |
|
222 |
+int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight); |
|
216 | 223 |
|
217 | 224 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
218 | 225 |
void listing_freedata(listing_t *listing); |
219 | 226 |
int listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_left); |
220 | 227 |
|
228 |
+int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh); |
|
229 |
+int texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh); |
|
230 |
+int texture_freedata(texture_t *texture); |
|
231 |
+ |
|
221 | 232 |
int imutil_menu_count(char *menus); |
222 | 233 |
char *imutil_menu_get(char *menus, int targetn, int *len); |
223 | 234 |
int imutil_submenu_count(char *menus); |
... | ... |
@@ -235,7 +246,7 @@ main(int argc, char *argv[]) |
235 | 246 |
im_t *im; |
236 | 247 |
Vector2 mousepos,wheel; |
237 | 248 |
int flag_ignorelmb; |
238 |
- int lmbpressed,lmbreleased,lmbdown; |
|
249 |
+ int lmbpressed,lmbreleased,lmbdown,rmbdown; |
|
239 | 250 |
int click_avail; |
240 | 251 |
char *sel_menu,*sel_submenu; |
241 | 252 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
... | ... |
@@ -248,6 +259,7 @@ main(int argc, char *argv[]) |
248 | 259 |
lmbpressed=IsMouseButtonPressed(0); |
249 | 260 |
lmbreleased=IsMouseButtonReleased(0); |
250 | 261 |
lmbdown=IsMouseButtonDown(0); |
262 |
+ rmbdown=IsMouseButtonDown(1); |
|
251 | 263 |
click_avail=1; |
252 | 264 |
/* process clicks on menus */ |
253 | 265 |
if(click_avail) { |
... | ... |
@@ -266,7 +278,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
266 | 278 |
/* draw screen contents */ |
267 | 279 |
BeginDrawing(); |
268 | 280 |
ClearBackground(RAYWHITE); |
269 |
- im_body_draw(im->body,mousepos,lmbdown,im->w,im->h); |
|
281 |
+ im_body_draw(im->body,mousepos,lmbdown,rmbdown,im->w,im->h); |
|
270 | 282 |
im_menubar_draw(im->menubar,im->w,im->h); |
271 | 283 |
#if 0 |
272 | 284 |
{ |
... | ... |
@@ -352,10 +364,8 @@ im_free(im_t *im) |
352 | 364 |
im_font_free(im->fontbig),im->fontbig=NULL; |
353 | 365 |
if(im->fonthuge!=NULL) |
354 | 366 |
im_font_free(im->fonthuge),im->fonthuge=NULL; |
355 |
-#if 1 /* not working as intended */ |
|
356 | 367 |
if(im->windowinit) |
357 | 368 |
CloseWindow(),im->windowinit=0; |
358 |
-#endif |
|
359 | 369 |
free(im),im=NULL; |
360 | 370 |
return; |
361 | 371 |
} |
... | ... |
@@ -666,12 +676,8 @@ im_body_free(body_t *body) |
666 | 676 |
} |
667 | 677 |
free(body->dirdata),body->dirdata=NULL,body->sizedirdata=0; |
668 | 678 |
} |
669 |
- if(body->has_texture) { |
|
670 |
- UnloadTexture(body->texture); |
|
671 |
- body->currenttexture[0]='\0'; |
|
672 |
- body->has_texture=0; |
|
673 |
- body->has_failedload=0; |
|
674 |
- } |
|
679 |
+ texture_freedata(&(body->texture)); |
|
680 |
+ texture_freedata(&(body->bigtexture)); |
|
675 | 681 |
if(body->rootdir!=NULL) |
676 | 682 |
free(body->rootdir),body->rootdir=NULL; |
677 | 683 |
free(body),body=NULL; |
... | ... |
@@ -778,7 +784,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
778 | 784 |
} |
779 | 785 |
|
780 | 786 |
int |
781 |
-im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight) |
|
787 |
+im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windowwidth, int windowheight) |
|
782 | 788 |
{ |
783 | 789 |
int i,k,margin,righty; |
784 | 790 |
int lastx,lasty; |
... | ... |
@@ -788,6 +794,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int w |
788 | 794 |
font_t *font,*fontbig,*fonthuge; |
789 | 795 |
int is_leftside; |
790 | 796 |
int flag_skiprightside; |
797 |
+ int flag_skipall; |
|
791 | 798 |
int xoff,yoff; |
792 | 799 |
thumb_t *thumb; |
793 | 800 |
char statustooltip[1024]; |
... | ... |
@@ -819,8 +826,8 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int w |
819 | 826 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
820 | 827 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
821 | 828 |
statustooltip[0]='\0'; |
822 |
- for(is_leftside=1,flag_skiprightside=0;is_leftside>=0 && flag_skiprightside==0;is_leftside--) { |
|
823 |
- for(i=(is_leftside)?body->currentdirdata:0,righty=body->xywh.y;(is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata);i++) { |
|
829 |
+ for(is_leftside=1,flag_skiprightside=flag_skipall=0;is_leftside>=0 && flag_skiprightside==0 && flag_skipall==0;is_leftside--) { |
|
830 |
+ for(i=(is_leftside)?body->currentdirdata:0,righty=body->xywh.y;flag_skipall==0 && ((is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata));i++) { |
|
824 | 831 |
int sidelen; |
825 | 832 |
if((dirdata=body->dirdata[i])==NULL) |
826 | 833 |
continue; |
... | ... |
@@ -962,56 +969,49 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
962 | 969 |
DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE); |
963 | 970 |
has_imagedrawn=1; |
964 | 971 |
lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff; |
965 |
- if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
972 |
+ if(is_leftside && lmbdown==0 && rmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
966 | 973 |
/* draw image in rightside */ |
967 |
- char path[2048]; |
|
974 |
+ char fullpath[2048]; |
|
968 | 975 |
int maxw,maxh; |
969 |
- snprintf(path,sizeof(path),"%s/%s",dirdata->dirname,elem->name+1); |
|
970 |
- path[sizeof(path)-1]='\0'; |
|
971 | 976 |
maxw=windowwidth-(body->leftsize-DEFAULTDIRDATATRIANGLEW); |
972 | 977 |
maxh=windowheight-body->xywh.y; |
973 |
- if((body->has_texture==0 && !(body->has_failedload && strcmp(body->currenttexture,path)==0)) |
|
974 |
- || strcmp(body->currenttexture,path)!=0 |
|
978 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
979 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
980 |
+ if((body->texture.has_texture==0 && !(body->texture.has_failedload && strcmp(body->texture.currentpath,fullpath)==0)) |
|
981 |
+ || strcmp(body->texture.currentpath,fullpath)!=0 |
|
975 | 982 |
) { |
976 |
- Image im; |
|
977 |
- int neww,newh; |
|
978 |
- char fullpath[2048]; |
|
979 |
- if(body->has_texture) { |
|
980 |
- UnloadTexture(body->texture); |
|
981 |
- body->currenttexture[0]='\0'; |
|
982 |
- body->has_texture=0; |
|
983 |
- body->has_failedload=0; |
|
984 |
- } |
|
985 |
- snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
986 |
- fullpath[sizeof(fullpath)-1]='\0'; |
|
987 |
- im=LoadImage(fullpath); |
|
988 |
- if(IsImageValid(im)) { |
|
989 |
- im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
990 |
- ImageResize(&im,neww,newh); |
|
991 |
- body->texture=LoadTextureFromImage(im); |
|
992 |
- UnloadImage(im); |
|
993 |
- strncpy(body->currenttexture,fullpath,sizeof(body->currenttexture)); |
|
994 |
- body->currenttexture[sizeof(body->currenttexture)-1]='\0'; |
|
995 |
- body->has_texture=1; |
|
996 |
- body->has_failedload=0; |
|
997 |
- body->texturew=neww; |
|
998 |
- body->textureh=newh; |
|
999 |
- } else { |
|
1000 |
- strncpy(body->currenttexture,fullpath,sizeof(body->currenttexture)); |
|
1001 |
- body->currenttexture[sizeof(body->currenttexture)-1]='\0'; |
|
1002 |
- body->has_texture=0; |
|
1003 |
- body->has_failedload=1; |
|
1004 |
- } |
|
983 |
+ texture_load(&(body->texture),fullpath,maxw,maxh); |
|
1005 | 984 |
} |
1006 |
- if(body->has_texture) { |
|
985 |
+ if(body->texture.has_texture && strcmp(body->texture.currentpath,fullpath)==0) { |
|
1007 | 986 |
int x0,y0; |
1008 | 987 |
x0=body->leftsize-DEFAULTDIRDATATRIANGLEW; |
1009 | 988 |
y0=body->xywh.y; |
1010 |
- DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
1011 |
- DrawTexture(body->texture,x0+(maxw-body->texturew)/2,y0+(maxh-body->textureh)/2,WHITE); |
|
989 |
+ texture_draw(&(body->texture),x0,y0,maxw,maxh); |
|
1012 | 990 |
flag_skiprightside=1; |
1013 | 991 |
} |
1014 | 992 |
} |
993 |
+ if(is_leftside && lmbdown==0 && rmbdown!=0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
994 |
+ /* draw image in full screen */ |
|
995 |
+ char fullpath[2048]; |
|
996 |
+ int maxw,maxh; |
|
997 |
+ maxw=windowwidth; |
|
998 |
+ maxh=windowheight-body->xywh.y; |
|
999 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
1000 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
1001 |
+ if((body->bigtexture.has_texture==0 && !(body->bigtexture.has_failedload && strcmp(body->bigtexture.currentpath,fullpath)==0)) |
|
1002 |
+ || strcmp(body->bigtexture.currentpath,fullpath)!=0 |
|
1003 |
+ ) { |
|
1004 |
+ texture_load(&(body->bigtexture),fullpath,maxw,maxh); |
|
1005 |
+ } |
|
1006 |
+ if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,fullpath)==0) { |
|
1007 |
+ int x0,y0; |
|
1008 |
+ x0=0; |
|
1009 |
+ y0=body->xywh.y; |
|
1010 |
+ texture_draw(&(body->bigtexture),x0,y0,maxw,maxh); |
|
1011 |
+ flag_skipall=1; |
|
1012 |
+ break; |
|
1013 |
+ } |
|
1014 |
+ } |
|
1015 | 1015 |
} |
1016 | 1016 |
} |
1017 | 1017 |
if(has_imagedrawn==0) { |
... | ... |
@@ -1065,6 +1065,65 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1065 | 1065 |
return(0); |
1066 | 1066 |
} |
1067 | 1067 |
|
1068 |
+int |
|
1069 |
+texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
|
1070 |
+{ |
|
1071 |
+ Image im; |
|
1072 |
+ int neww,newh; |
|
1073 |
+ if(texture==NULL || fullpath==NULL) |
|
1074 |
+ return(-1); /* sanity check failed */ |
|
1075 |
+ if(texture->has_texture) { |
|
1076 |
+ UnloadTexture(texture->texture); |
|
1077 |
+ texture->currentpath[0]='\0'; |
|
1078 |
+ texture->has_texture=0; |
|
1079 |
+ texture->has_failedload=0; |
|
1080 |
+ } |
|
1081 |
+ texture->currentpath[0]='\0'; |
|
1082 |
+ im=LoadImage(fullpath); |
|
1083 |
+ if(IsImageValid(im)) { |
|
1084 |
+ im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
1085 |
+ ImageResize(&im,neww,newh); |
|
1086 |
+ texture->texture=LoadTextureFromImage(im); |
|
1087 |
+ UnloadImage(im); |
|
1088 |
+ strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1089 |
+ texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1090 |
+ texture->has_texture=1; |
|
1091 |
+ texture->has_failedload=0; |
|
1092 |
+ texture->texturew=neww; |
|
1093 |
+ texture->textureh=newh; |
|
1094 |
+ } else { |
|
1095 |
+ strncpy(texture->currentpath,fullpath,sizeof(texture->currentpath)); |
|
1096 |
+ texture->currentpath[sizeof(texture->currentpath)-1]='\0'; |
|
1097 |
+ texture->has_texture=0; |
|
1098 |
+ texture->has_failedload=1; |
|
1099 |
+ } |
|
1100 |
+ return(0); |
|
1101 |
+} |
|
1102 |
+ |
|
1103 |
+int |
|
1104 |
+texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh) |
|
1105 |
+{ |
|
1106 |
+ if(texture==NULL || texture->has_texture==0) |
|
1107 |
+ return(-1); /* sanity check failed */ |
|
1108 |
+ DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
1109 |
+ DrawTexture(texture->texture,x0+(maxw-texture->texturew)/2,y0+(maxh-texture->textureh)/2,WHITE); |
|
1110 |
+ return(0); |
|
1111 |
+} |
|
1112 |
+ |
|
1113 |
+int |
|
1114 |
+texture_freedata(texture_t *texture) |
|
1115 |
+{ |
|
1116 |
+ if(texture==NULL) |
|
1117 |
+ return(-1); /* sanity check failed */ |
|
1118 |
+ if(texture->has_texture) { |
|
1119 |
+ UnloadTexture(texture->texture); |
|
1120 |
+ texture->currentpath[0]='\0'; |
|
1121 |
+ texture->has_texture=0; |
|
1122 |
+ texture->has_failedload=0; |
|
1123 |
+ } |
|
1124 |
+ return(0); |
|
1125 |
+} |
|
1126 |
+ |
|
1068 | 1127 |
int |
1069 | 1128 |
imutil_menu_count(char *menus) |
1070 | 1129 |
{ |
... | ... |
@@ -303,7 +303,6 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
303 | 303 |
#endif |
304 | 304 |
EndDrawing(); |
305 | 305 |
} |
306 |
- CloseWindow(); |
|
307 | 306 |
im_free(im),im=NULL; |
308 | 307 |
return(0); |
309 | 308 |
} |
... | ... |
@@ -353,7 +352,7 @@ im_free(im_t *im) |
353 | 352 |
im_font_free(im->fontbig),im->fontbig=NULL; |
354 | 353 |
if(im->fonthuge!=NULL) |
355 | 354 |
im_font_free(im->fonthuge),im->fonthuge=NULL; |
356 |
-#if 0 /* not working as intended */ |
|
355 |
+#if 1 /* not working as intended */ |
|
357 | 356 |
if(im->windowinit) |
358 | 357 |
CloseWindow(),im->windowinit=0; |
359 | 358 |
#endif |
... | ... |
@@ -656,8 +655,6 @@ im_body_free(body_t *body) |
656 | 655 |
dirdata_t *dirdata; |
657 | 656 |
if(body==NULL) |
658 | 657 |
return; /* nothing to do */ |
659 |
- if(body->rootdir!=NULL) |
|
660 |
- free(body->rootdir),body->rootdir=NULL; |
|
661 | 658 |
if(body->dirdata!=NULL) { |
662 | 659 |
for(i=0;i<body->sizedirdata;i++) { |
663 | 660 |
if((dirdata=body->dirdata[i])==NULL) |
... | ... |
@@ -675,6 +672,8 @@ im_body_free(body_t *body) |
675 | 672 |
body->has_texture=0; |
676 | 673 |
body->has_failedload=0; |
677 | 674 |
} |
675 |
+ if(body->rootdir!=NULL) |
|
676 |
+ free(body->rootdir),body->rootdir=NULL; |
|
678 | 677 |
free(body),body=NULL; |
679 | 678 |
return; |
680 | 679 |
} |
... | ... |
@@ -923,9 +922,8 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
923 | 922 |
} |
924 | 923 |
/* show image */ |
925 | 924 |
has_imagedrawn=0; |
926 |
-#if 1 |
|
927 | 925 |
if(is_imagefilename(elem->name+1)) { |
928 |
- if(thumb->has_texture==0) { |
|
926 |
+ if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
929 | 927 |
Image im; |
930 | 928 |
char fullpath[2048]; |
931 | 929 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
... | ... |
@@ -955,6 +953,8 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
955 | 953 |
UnloadImage(im); |
956 | 954 |
UnloadImage(im2); |
957 | 955 |
thumb->has_texture=1; |
956 |
+ } else { |
|
957 |
+ thumb->has_failedload=1; |
|
958 | 958 |
} |
959 | 959 |
} |
960 | 960 |
if(thumb->has_texture!=0) { |
... | ... |
@@ -1014,7 +1014,6 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1014 | 1014 |
} |
1015 | 1015 |
} |
1016 | 1016 |
} |
1017 |
-#endif |
|
1018 | 1017 |
if(has_imagedrawn==0) { |
1019 | 1018 |
char *ptr; |
1020 | 1019 |
char shortname[1024]; |
... | ... |
@@ -21,6 +21,7 @@ |
21 | 21 |
* 20250305 Scrollable left pane. |
22 | 22 |
* 20250308 Show statustooltip on image hover. |
23 | 23 |
* Scrollwheel support for leftside. |
24 |
+ * Fix thumb aspect ratio. |
|
24 | 25 |
* |
25 | 26 |
* Author: Dario Rodriguez dario@darionomono.com |
26 | 27 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -222,7 +223,7 @@ char *imutil_menu_get(char *menus, int targetn, int *len); |
222 | 223 |
int imutil_submenu_count(char *menus); |
223 | 224 |
char *imutil_submenu_get(char *menus, int targetn, int *len); |
224 | 225 |
char *imutil_strduplen(char *str, int len); |
225 |
-int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh); |
|
226 |
+int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin); |
|
226 | 227 |
int im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh); |
227 | 228 |
int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
228 | 229 |
int *getcodepoints(int *sizecodepoints); |
... | ... |
@@ -494,7 +495,7 @@ im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbre |
494 | 495 |
flag_outsideall=1; |
495 | 496 |
for(i=0;i<menubar->sizemenudata;i++) { |
496 | 497 |
int insidetitle,currentoption; |
497 |
- insidetitle=is_imutil_insidexywh(mousepos,&(menubar->menudata[i]->xywh)); |
|
498 |
+ insidetitle=is_imutil_insidexywh(mousepos,&(menubar->menudata[i]->xywh),0); |
|
498 | 499 |
currentoption=menudata_pos2option(menubar->menudata[i],mousepos); |
499 | 500 |
flag_outsideall=(currentoption!=-1 || insidetitle)?0:flag_outsideall; |
500 | 501 |
if(lmbreleased && insidetitle) { |
... | ... |
@@ -730,7 +731,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
730 | 731 |
if(*click_avail==0 || lmbreleased==0) |
731 | 732 |
return(0); /* nothing else to do */ |
732 | 733 |
/* leftside backbutton */ |
733 |
- if(is_imutil_insidexywh(mousepos,&(body->backxywh))) { |
|
734 |
+ if(is_imutil_insidexywh(mousepos,&(body->backxywh),0)) { |
|
734 | 735 |
static char sep[]={SEP}; |
735 | 736 |
if((ptr=strrchr(dirdata->dirname,sep[0]))!=NULL) { |
736 | 737 |
/* previous dir */ |
... | ... |
@@ -749,7 +750,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int |
749 | 750 |
ld=dirdata->listing.elems+i; |
750 | 751 |
if(ld->name[0]!='d') |
751 | 752 |
continue; |
752 |
- if(is_imutil_insidexywh(mousepos,&(ld->left.screenxywh))) { |
|
753 |
+ if(is_imutil_insidexywh(mousepos,&(ld->left.screenxywh),0)) { |
|
753 | 754 |
char *newname,*oldprefix; |
754 | 755 |
int l,l0,l1; |
755 | 756 |
static char sep[]={SEP}; |
... | ... |
@@ -916,7 +917,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
916 | 917 |
#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
917 | 918 |
break; |
918 | 919 |
} |
919 |
- if(is_leftside && is_imutil_insidexywh(mousepos,&(thumb->screenxywh))) { |
|
920 |
+ if(is_leftside && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
920 | 921 |
strncpy(statustooltip,elem->name+1,sizeof(statustooltip)); |
921 | 922 |
statustooltip[sizeof(statustooltip)-1]='\0'; |
922 | 923 |
} |
... | ... |
@@ -931,12 +932,28 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
931 | 932 |
fullpath[sizeof(fullpath)-1]='\0'; |
932 | 933 |
im=LoadImage(fullpath); |
933 | 934 |
if(IsImageValid(im)) { |
935 |
+ int neww,newh; |
|
936 |
+ Image im2,impixel; |
|
934 | 937 |
#if 1 |
935 | 938 |
fprintf(stderr,"Loaded %s\n",fullpath); |
939 |
+{ |
|
940 |
+int oldw=im.width,oldh=im.height; |
|
941 |
+#endif |
|
942 |
+ im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
|
943 |
+ im_util_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
944 |
+ ImageResize(&im,neww,newh); |
|
945 |
+ impixel=ImageCopy(im); |
|
946 |
+ ImageResize(&impixel,1,1); |
|
947 |
+#if 1 |
|
948 |
+if(neww>sidelen || newh>sidelen) |
|
949 |
+fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidelen,oldw,oldh,neww,newh); |
|
950 |
+} |
|
936 | 951 |
#endif |
937 |
- ImageResize(&im,sidelen,sidelen); |
|
938 |
- *te=LoadTextureFromImage(im); |
|
952 |
+ ImageDraw(&im2,impixel,(Rectangle) {0,0,1,1},(Rectangle) {0,0,sidelen,sidelen},(Color){255,255,255,255}); |
|
953 |
+ ImageDraw(&im2,im,(Rectangle) {0,0,neww,newh},(Rectangle) {(sidelen-neww)/2,(sidelen-newh)/2,neww,newh},(Color){255,255,255,255}); |
|
954 |
+ *te=LoadTextureFromImage(im2); |
|
939 | 955 |
UnloadImage(im); |
956 |
+ UnloadImage(im2); |
|
940 | 957 |
thumb->has_texture=1; |
941 | 958 |
} |
942 | 959 |
} |
... | ... |
@@ -945,7 +962,7 @@ fprintf(stderr,"Loaded %s\n",fullpath); |
945 | 962 |
DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE); |
946 | 963 |
has_imagedrawn=1; |
947 | 964 |
lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff; |
948 |
- if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh))) { |
|
965 |
+ if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh),margin)) { |
|
949 | 966 |
/* draw image in rightside */ |
950 | 967 |
char path[2048]; |
951 | 968 |
int maxw,maxh; |
... | ... |
@@ -1149,14 +1166,14 @@ imutil_strduplen(char *str, int len) |
1149 | 1166 |
} |
1150 | 1167 |
|
1151 | 1168 |
int |
1152 |
-is_imutil_insidexywh(Vector2 pos, xywh_t *xywh) |
|
1169 |
+is_imutil_insidexywh(Vector2 pos, xywh_t *xywh, int margin) |
|
1153 | 1170 |
{ |
1154 | 1171 |
if(xywh==NULL) |
1155 | 1172 |
return(0); /* sanity check error */ |
1156 |
- if(pos.x>=(float)(xywh->x) |
|
1157 |
- && pos.x<=(float)(xywh->x+xywh->w) |
|
1158 |
- && pos.y>=(float)(xywh->y) |
|
1159 |
- && pos.y<=(float)(xywh->y+xywh->h) |
|
1173 |
+ if(pos.x>=(float)(xywh->x-margin) |
|
1174 |
+ && pos.x<=(float)(xywh->x+xywh->w+margin) |
|
1175 |
+ && pos.y>=(float)(xywh->y-margin) |
|
1176 |
+ && pos.y<=(float)(xywh->y+xywh->h+margin) |
|
1160 | 1177 |
) { |
1161 | 1178 |
return(1); |
1162 | 1179 |
} |
... | ... |
@@ -1168,7 +1185,7 @@ im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
1168 | 1185 |
{ |
1169 | 1186 |
if(neww==NULL || newh==NULL || w==0 || h==0 || maxw==0 || maxh==0) |
1170 | 1187 |
return(-1); |
1171 |
- if((w/h)>(maxw/maxh)) { |
|
1188 |
+ if((w/h)>(maxw/maxh) || (maxw==maxh && w>h)) { |
|
1172 | 1189 |
*neww=maxw; |
1173 | 1190 |
*newh=h*maxw/w; |
1174 | 1191 |
} else { /* (w/h)<=(maxw/maxh) */ |
... | ... |
@@ -1185,7 +1202,7 @@ menudata_pos2option(menudata_t *menudata, Vector2 pos) |
1185 | 1202 |
int n,h; |
1186 | 1203 |
if(menudata==NULL |
1187 | 1204 |
|| (menudata->flag_open==0 && menudata->flag_stickyopen==0) |
1188 |
- || is_imutil_insidexywh(pos, &(menudata->optionsxywh))==0 |
|
1205 |
+ || is_imutil_insidexywh(pos, &(menudata->optionsxywh),0)==0 |
|
1189 | 1206 |
) { |
1190 | 1207 |
return(-1); |
1191 | 1208 |
} |
... | ... |
@@ -20,6 +20,7 @@ |
20 | 20 |
* Preserve aspect ratio of big image. |
21 | 21 |
* 20250305 Scrollable left pane. |
22 | 22 |
* 20250308 Show statustooltip on image hover. |
23 |
+ * Scrollwheel support for leftside. |
|
23 | 24 |
* |
24 | 25 |
* Author: Dario Rodriguez dario@darionomono.com |
25 | 26 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -51,6 +52,8 @@ |
51 | 52 |
#define FONTBIGSIZE 32 |
52 | 53 |
#define FONTHUGESIZE 48 |
53 | 54 |
|
55 |
+#define WHEELSTEP LEFTIMAGESIDELEN |
|
56 |
+ |
|
54 | 57 |
#define ROOTDIR "/var/www/default/animeshot/" |
55 | 58 |
|
56 | 59 |
#define SEP "/" |
... | ... |
@@ -148,6 +151,7 @@ typedef struct listing_t { |
148 | 151 |
char *buf; |
149 | 152 |
int has_leftxywh; |
150 | 153 |
int has_rightxywh; |
154 |
+ xywh_t lastleftxywh; |
|
151 | 155 |
} listing_t; |
152 | 156 |
|
153 | 157 |
typedef struct dirdata_t { |
... | ... |
@@ -206,7 +210,7 @@ void im_body_free(body_t *body); |
206 | 210 |
|
207 | 211 |
int im_body_add(body_t *body,char *dir); |
208 | 212 |
|
209 |
-int im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
|
213 |
+int im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
|
210 | 214 |
int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight); |
211 | 215 |
|
212 | 216 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
... | ... |
@@ -228,7 +232,7 @@ int |
228 | 232 |
main(int argc, char *argv[]) |
229 | 233 |
{ |
230 | 234 |
im_t *im; |
231 |
- Vector2 mousepos; |
|
235 |
+ Vector2 mousepos,wheel; |
|
232 | 236 |
int flag_ignorelmb; |
233 | 237 |
int lmbpressed,lmbreleased,lmbdown; |
234 | 238 |
int click_avail; |
... | ... |
@@ -239,6 +243,7 @@ main(int argc, char *argv[]) |
239 | 243 |
flag_ignorelmb=0; |
240 | 244 |
while(!WindowShouldClose()) { |
241 | 245 |
mousepos=GetMousePosition(); |
246 |
+ wheel=GetMouseWheelMoveV(); |
|
242 | 247 |
lmbpressed=IsMouseButtonPressed(0); |
243 | 248 |
lmbreleased=IsMouseButtonReleased(0); |
244 | 249 |
lmbdown=IsMouseButtonDown(0); |
... | ... |
@@ -254,7 +259,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
254 | 259 |
} |
255 | 260 |
} |
256 | 261 |
if(click_avail) |
257 |
- im_body_mouse(im->body, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail); |
|
262 |
+ im_body_mouse(im->body, mousepos, wheel, lmbpressed, lmbreleased, lmbdown, &click_avail); |
|
258 | 263 |
|
259 | 264 |
|
260 | 265 |
/* draw screen contents */ |
... | ... |
@@ -707,7 +712,7 @@ im_body_add(body_t *body,char *dir) |
707 | 712 |
} |
708 | 713 |
|
709 | 714 |
int |
710 |
-im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
|
715 |
+im_body_mouse(body_t *body, Vector2 mousepos, Vector2 wheel, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
|
711 | 716 |
{ |
712 | 717 |
int i; |
713 | 718 |
char *ptr; |
... | ... |
@@ -715,9 +720,15 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
715 | 720 |
listingdata_t *ld; |
716 | 721 |
if(body==NULL || click_avail==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL) |
717 | 722 |
return(-1); /* sanity check error */ |
718 |
- if(*click_avail==0 || lmbreleased==0) |
|
719 |
- return(0); /* nothing to do */ |
|
720 | 723 |
dirdata=body->dirdata[body->currentdirdata]; |
724 |
+ /* wheel */ |
|
725 |
+ body->leftscrollpos-=(int)wheel.y*WHEELSTEP; |
|
726 |
+ body->leftscrollpos=(body->leftscrollpos<0)?0:body->leftscrollpos; |
|
727 |
+ if(body->leftscrollpos>dirdata->listing.lastleftxywh.y) |
|
728 |
+ body->leftscrollpos=dirdata->listing.lastleftxywh.y; |
|
729 |
+ /* check if we have to process a click */ |
|
730 |
+ if(*click_avail==0 || lmbreleased==0) |
|
731 |
+ return(0); /* nothing else to do */ |
|
721 | 732 |
/* leftside backbutton */ |
722 | 733 |
if(is_imutil_insidexywh(mousepos,&(body->backxywh))) { |
723 | 734 |
static char sep[]={SEP}; |
... | ... |
@@ -729,6 +740,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
729 | 740 |
dirdata->dirname[0]='\0'; |
730 | 741 |
} |
731 | 742 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
743 |
+ body->leftscrollpos=0; |
|
732 | 744 |
*click_avail=0; |
733 | 745 |
return(0); |
734 | 746 |
} |
... | ... |
@@ -737,7 +749,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
737 | 749 |
ld=dirdata->listing.elems+i; |
738 | 750 |
if(ld->name[0]!='d') |
739 | 751 |
continue; |
740 |
- if(is_imutil_insidexywh(mousepos,&(ld->left.xywh))) { |
|
752 |
+ if(is_imutil_insidexywh(mousepos,&(ld->left.screenxywh))) { |
|
741 | 753 |
char *newname,*oldprefix; |
742 | 754 |
int l,l0,l1; |
743 | 755 |
static char sep[]={SEP}; |
... | ... |
@@ -756,6 +768,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
756 | 768 |
free(dirdata->dirname),dirdata->dirname=NULL; |
757 | 769 |
dirdata->dirname=newname; |
758 | 770 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
771 |
+ body->leftscrollpos=0; |
|
759 | 772 |
*click_avail=0; |
760 | 773 |
return(0); |
761 | 774 |
} |
... | ... |
@@ -780,17 +793,6 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int w |
780 | 793 |
char statustooltip[1024]; |
781 | 794 |
if(body==NULL) |
782 | 795 |
return(-1); |
783 |
-#if 1 |
|
784 |
-#warning TESTING LEFTSCROLL |
|
785 |
-body->leftscrollpos=(int) mousepos.y; |
|
786 |
-{ |
|
787 |
- static int lastlsp=-1; |
|
788 |
- if(body->leftscrollpos!=lastlsp) { |
|
789 |
- lastlsp=body->leftscrollpos; |
|
790 |
- fprintf(stderr,"leftscrollpos:%i\n",body->leftscrollpos); |
|
791 |
- } |
|
792 |
-} |
|
793 |
-#endif |
|
794 | 796 |
font=body->ptrfont; |
795 | 797 |
fontbig=body->ptrfontbig; |
796 | 798 |
fonthuge=body->ptrfonthuge; |
... | ... |
@@ -1368,6 +1370,8 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1368 | 1370 |
if(listing==NULL || font==NULL) |
1369 | 1371 |
return(-1); /* sanity check failed */ |
1370 | 1372 |
margin=font->height/4; |
1373 |
+ if(is_leftside) |
|
1374 |
+ memset(&(listing->lastleftxywh),0,sizeof(listing->lastleftxywh)); |
|
1371 | 1375 |
/* directories */ |
1372 | 1376 |
if(is_leftside) { |
1373 | 1377 |
x0=font->height/2; |
... | ... |
@@ -1391,6 +1395,8 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1391 | 1395 |
continue; |
1392 | 1396 |
} |
1393 | 1397 |
FILLXYWH(thumb->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
1398 |
+ if(is_leftside && (thumb->xywh.y+thumb->xywh.h)>(listing->lastleftxywh.y+listing->lastleftxywh.h)) |
|
1399 |
+ memcpy(&(listing->lastleftxywh),&(thumb->xywh),sizeof(xywh_t)); |
|
1394 | 1400 |
x+=margin*2+m2.x+font->height/4; |
1395 | 1401 |
} |
1396 | 1402 |
y+=((x==x0)?0:font->height+margin*2+font->height/4); |
... | ... |
@@ -1415,6 +1421,8 @@ listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_le |
1415 | 1421 |
continue; |
1416 | 1422 |
} |
1417 | 1423 |
FILLXYWH(thumb->xywh,x,y,sidelen,sidelen); |
1424 |
+ if(is_leftside && (thumb->xywh.y+thumb->xywh.h)>(listing->lastleftxywh.y+listing->lastleftxywh.h)) |
|
1425 |
+ memcpy(&(listing->lastleftxywh),&(thumb->xywh),sizeof(xywh_t)); |
|
1418 | 1426 |
x+=margin*2+sidelen; |
1419 | 1427 |
} |
1420 | 1428 |
return(0); |
... | ... |
@@ -19,6 +19,7 @@ |
19 | 19 |
* Show big image on hover. |
20 | 20 |
* Preserve aspect ratio of big image. |
21 | 21 |
* 20250305 Scrollable left pane. |
22 |
+ * 20250308 Show statustooltip on image hover. |
|
22 | 23 |
* |
23 | 24 |
* Author: Dario Rodriguez dario@darionomono.com |
24 | 25 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -776,6 +777,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int w |
776 | 777 |
int flag_skiprightside; |
777 | 778 |
int xoff,yoff; |
778 | 779 |
thumb_t *thumb; |
780 |
+ char statustooltip[1024]; |
|
779 | 781 |
if(body==NULL) |
780 | 782 |
return(-1); |
781 | 783 |
#if 1 |
... | ... |
@@ -814,6 +816,7 @@ body->leftscrollpos=(int) mousepos.y; |
814 | 816 |
/* draw right side background */ |
815 | 817 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
816 | 818 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
819 |
+ statustooltip[0]='\0'; |
|
817 | 820 |
for(is_leftside=1,flag_skiprightside=0;is_leftside>=0 && flag_skiprightside==0;is_leftside--) { |
818 | 821 |
for(i=(is_leftside)?body->currentdirdata:0,righty=body->xywh.y;(is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata);i++) { |
819 | 822 |
int sidelen; |
... | ... |
@@ -911,6 +914,10 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
911 | 914 |
#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
912 | 915 |
break; |
913 | 916 |
} |
917 |
+ if(is_leftside && is_imutil_insidexywh(mousepos,&(thumb->screenxywh))) { |
|
918 |
+ strncpy(statustooltip,elem->name+1,sizeof(statustooltip)); |
|
919 |
+ statustooltip[sizeof(statustooltip)-1]='\0'; |
|
920 |
+ } |
|
914 | 921 |
/* show image */ |
915 | 922 |
has_imagedrawn=0; |
916 | 923 |
#if 1 |
... | ... |
@@ -1032,6 +1039,11 @@ fprintf(stderr,"Loaded %s\n",fullpath); |
1032 | 1039 |
} |
1033 | 1040 |
} |
1034 | 1041 |
} |
1042 |
+ if(statustooltip[0]!='\0') { |
|
1043 |
+ m2=MeasureTextEx(font->font,statustooltip,font->height,0); |
|
1044 |
+ DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
|
1045 |
+ DrawTextEx(font->font,statustooltip,(Vector2){margin,windowheight-1-margin-font->height},font->height,0,(Color){ 255,255,255,128 }); |
|
1046 |
+ } |
|
1035 | 1047 |
return(0); |
1036 | 1048 |
} |
1037 | 1049 |
|
... | ... |
@@ -18,6 +18,7 @@ |
18 | 18 |
* Basic image loading. |
19 | 19 |
* Show big image on hover. |
20 | 20 |
* Preserve aspect ratio of big image. |
21 |
+ * 20250305 Scrollable left pane. |
|
21 | 22 |
* |
22 | 23 |
* Author: Dario Rodriguez dario@darionomono.com |
23 | 24 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -73,6 +74,10 @@ |
73 | 74 |
#define UNROLLXYWH(xywh) (xywh).x,(xywh).y,(xywh).w,(xywh).h |
74 | 75 |
#endif |
75 | 76 |
|
77 |
+#ifndef UNROLLWHXY |
|
78 |
+#define UNROLLWHXY(xywh) (xywh).w,(xywh).h,(xywh).x,(xywh).y |
|
79 |
+#endif |
|
80 |
+ |
|
76 | 81 |
#ifndef __linux__ |
77 | 82 |
/* the old raylib used in the windows build lacks this function */ |
78 | 83 |
bool IsImageValid(Image image) |
... | ... |
@@ -121,8 +126,10 @@ typedef struct menubar_t { |
121 | 126 |
|
122 | 127 |
typedef struct thumb_t { |
123 | 128 |
xywh_t xywh; |
129 |
+ xywh_t screenxywh; |
|
124 | 130 |
Texture2D texture; |
125 | 131 |
int has_texture; |
132 |
+ int has_failedload; |
|
126 | 133 |
} thumb_t; |
127 | 134 |
|
128 | 135 |
typedef struct listingdata_t { |
... | ... |
@@ -138,6 +145,8 @@ typedef struct listing_t { |
138 | 145 |
int sizebuf; |
139 | 146 |
int usedbuf; |
140 | 147 |
char *buf; |
148 |
+ int has_leftxywh; |
|
149 |
+ int has_rightxywh; |
|
141 | 150 |
} listing_t; |
142 | 151 |
|
143 | 152 |
typedef struct dirdata_t { |
... | ... |
@@ -159,11 +168,12 @@ typedef struct body_t { |
159 | 168 |
font_t *ptrfont; |
160 | 169 |
font_t *ptrfontbig; |
161 | 170 |
font_t *ptrfonthuge; |
162 |
- char currenttexture[1024]; |
|
171 |
+ char currenttexture[2048]; |
|
163 | 172 |
Texture2D texture; |
164 | 173 |
int texturew; |
165 | 174 |
int textureh; |
166 | 175 |
int has_texture; |
176 |
+ int has_failedload; |
|
167 | 177 |
} body_t; |
168 | 178 |
|
169 | 179 |
typedef struct im_t { |
... | ... |
@@ -190,7 +200,7 @@ void im_menubar_free(menubar_t *menubar); |
190 | 200 |
int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
191 | 201 |
int im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight); |
192 | 202 |
|
193 |
-body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir); |
|
203 |
+body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight); |
|
194 | 204 |
void im_body_free(body_t *body); |
195 | 205 |
|
196 | 206 |
int im_body_add(body_t *body,char *dir); |
... | ... |
@@ -200,6 +210,7 @@ int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, i |
200 | 210 |
|
201 | 211 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
202 | 212 |
void listing_freedata(listing_t *listing); |
213 |
+int listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_left); |
|
203 | 214 |
|
204 | 215 |
int imutil_menu_count(char *menus); |
205 | 216 |
char *imutil_menu_get(char *menus, int targetn, int *len); |
... | ... |
@@ -310,7 +321,7 @@ im_init(char *menus, char *rootdir) |
310 | 321 |
|| (im->fontbig=im_font_init(FONTBIGSIZE))==NULL |
311 | 322 |
|| (im->fonthuge=im_font_init(FONTHUGESIZE))==NULL |
312 | 323 |
|| (im->menubar=im_menubar_init(menus,im->font))==NULL |
313 |
- || (im->body=im_body_init(0,im->menubar->height, im->font, im->fontbig, im->fonthuge, LEFTSIZE, rootdir))==NULL |
|
324 |
+ || (im->body=im_body_init(0,im->menubar->height, im->font, im->fontbig, im->fonthuge, LEFTSIZE, rootdir,im->w,im->h))==NULL |
|
314 | 325 |
) { |
315 | 326 |
im_free(im),im=NULL; |
316 | 327 |
return(NULL); /* insuf. mem. */ |
... | ... |
@@ -609,7 +620,7 @@ im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight) |
609 | 620 |
} |
610 | 621 |
|
611 | 622 |
body_t * |
612 |
-im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir) |
|
623 |
+im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir, int windowwidth, int windowheight) |
|
613 | 624 |
{ |
614 | 625 |
body_t *body; |
615 | 626 |
static char sep[]={SEP}; |
... | ... |
@@ -621,7 +632,7 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
621 | 632 |
im_body_free(body),body=NULL; |
622 | 633 |
return(NULL); |
623 | 634 |
} |
624 |
- FILLXY(body->xywh,x,y); |
|
635 |
+ FILLXYWH(body->xywh,x,y,windowwidth-x,windowheight-y); |
|
625 | 636 |
body->leftsize=leftsize; |
626 | 637 |
body->ptrfont=font; |
627 | 638 |
body->ptrfontbig=fontbig; |
... | ... |
@@ -653,7 +664,9 @@ im_body_free(body_t *body) |
653 | 664 |
} |
654 | 665 |
if(body->has_texture) { |
655 | 666 |
UnloadTexture(body->texture); |
667 |
+ body->currenttexture[0]='\0'; |
|
656 | 668 |
body->has_texture=0; |
669 |
+ body->has_failedload=0; |
|
657 | 670 |
} |
658 | 671 |
free(body),body=NULL; |
659 | 672 |
return; |
... | ... |
@@ -753,59 +766,89 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
753 | 766 |
int |
754 | 767 |
im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight) |
755 | 768 |
{ |
756 |
- int i,x,y,k,margin,righty; |
|
769 |
+ int i,k,margin,righty; |
|
770 |
+ int lastx,lasty; |
|
757 | 771 |
dirdata_t *dirdata; |
758 | 772 |
listingdata_t *elem; |
759 | 773 |
Vector2 v2,m2; |
760 | 774 |
font_t *font,*fontbig,*fonthuge; |
761 | 775 |
int is_leftside; |
762 | 776 |
int flag_skiprightside; |
777 |
+ int xoff,yoff; |
|
778 |
+ thumb_t *thumb; |
|
763 | 779 |
if(body==NULL) |
764 | 780 |
return(-1); |
781 |
+#if 1 |
|
782 |
+#warning TESTING LEFTSCROLL |
|
783 |
+body->leftscrollpos=(int) mousepos.y; |
|
784 |
+{ |
|
785 |
+ static int lastlsp=-1; |
|
786 |
+ if(body->leftscrollpos!=lastlsp) { |
|
787 |
+ lastlsp=body->leftscrollpos; |
|
788 |
+ fprintf(stderr,"leftscrollpos:%i\n",body->leftscrollpos); |
|
789 |
+ } |
|
790 |
+} |
|
791 |
+#endif |
|
765 | 792 |
font=body->ptrfont; |
766 | 793 |
fontbig=body->ptrfontbig; |
767 | 794 |
fonthuge=body->ptrfonthuge; |
768 |
- FILLWH(body->xywh,windowwidth-body->xywh.x,windowheight-body->xywh.y); |
|
769 | 795 |
FILLXYWH(body->backxywh,0,0,0,0); |
796 |
+ margin=font->height/4; |
|
797 |
+ /* calculate positions */ |
|
798 |
+ for(i=0;i<body->sizedirdata;i++) { |
|
799 |
+ if(body->dirdata[i]==NULL) |
|
800 |
+ continue; |
|
801 |
+ if(body->dirdata[i]->listing.has_rightxywh==0) { |
|
802 |
+ int sidelen; |
|
803 |
+ sidelen=body->dirdata[i]->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
|
804 |
+ listing_fillxywh(&(body->dirdata[i]->listing),body->ptrfont,body->xywh.w-(body->xywh.x+body->leftsize),sidelen,0); |
|
805 |
+ body->dirdata[i]->listing.has_rightxywh=1; |
|
806 |
+ } |
|
807 |
+ if(i==body->currentdirdata && body->dirdata[i]->listing.has_leftxywh==0) { |
|
808 |
+ listing_fillxywh(&(body->dirdata[i]->listing),body->ptrfont,body->leftsize,LEFTIMAGESIDELEN,1); |
|
809 |
+ body->dirdata[i]->listing.has_leftxywh=1; |
|
810 |
+ } |
|
811 |
+ } |
|
770 | 812 |
/* draw left side background */ |
771 | 813 |
DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
772 | 814 |
/* draw right side background */ |
773 | 815 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
774 | 816 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
775 | 817 |
for(is_leftside=1,flag_skiprightside=0;is_leftside>=0 && flag_skiprightside==0;is_leftside--) { |
776 |
- for(i=(is_leftside)?body->currentdirdata:0,y=righty=body->xywh.y;(is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata);i++) { |
|
777 |
- int x0,y0,x1,y1; |
|
818 |
+ for(i=(is_leftside)?body->currentdirdata:0,righty=body->xywh.y;(is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata);i++) { |
|
778 | 819 |
int sidelen; |
779 | 820 |
if((dirdata=body->dirdata[i])==NULL) |
780 | 821 |
continue; |
781 | 822 |
if(is_leftside && !(i==body->currentdirdata)) |
782 | 823 |
continue; /* this element is not in leftside */ |
783 |
- margin=font->height/4; |
|
784 | 824 |
sidelen=(is_leftside)?LEFTIMAGESIDELEN:dirdata->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
785 | 825 |
/* draw left side back arrow if is_leftside and not in root dir */ |
786 | 826 |
if(is_leftside && !(dirdata->dirname[0]=='\0' || strcmp(dirdata->dirname,SEP)==0)) { |
787 | 827 |
m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
788 | 828 |
v2.x=(float) (body->xywh.x+fontbig->height/2); |
789 |
- v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2); |
|
829 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2)-body->leftscrollpos; |
|
790 | 830 |
FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
791 | 831 |
#if 0 |
792 | 832 |
DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
793 | 833 |
DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone */ |
794 | 834 |
#endif |
795 |
- DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
|
835 |
+ if((v2.y+fontbig->height)>=0) |
|
836 |
+ DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
|
796 | 837 |
} |
797 | 838 |
if(is_leftside) { |
798 | 839 |
/* ...dirname */ |
799 |
- m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
|
800 |
- v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
801 |
- v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
802 |
- DrawTextEx(fontbig->font |
|
803 |
- ,dirdata->dirname |
|
804 |
- ,v2 |
|
805 |
- ,fontbig->height |
|
806 |
- ,0 |
|
807 |
- ,(Color){ 65, 65, 65, 255 } |
|
808 |
- ); |
|
840 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4-body->leftscrollpos); |
|
841 |
+ if((v2.y+fontbig->height)>=0) { |
|
842 |
+ m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
|
843 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
844 |
+ DrawTextEx(fontbig->font |
|
845 |
+ ,dirdata->dirname |
|
846 |
+ ,v2 |
|
847 |
+ ,fontbig->height |
|
848 |
+ ,0 |
|
849 |
+ ,(Color){ 65, 65, 65, 255 } |
|
850 |
+ ); |
|
851 |
+ } |
|
809 | 852 |
} else { /* rightside */ |
810 | 853 |
/* ...bg */ |
811 | 854 |
DrawRectangle(body->xywh.x+body->leftsize,righty,body->xywh.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
... | ... |
@@ -821,166 +864,160 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
821 | 864 |
); |
822 | 865 |
} |
823 | 866 |
/* directories */ |
824 |
- if(is_leftside) { |
|
825 |
- x0=body->xywh.x+font->height/2; |
|
826 |
- x1=body->xywh.x+body->leftsize-DEFAULTDIRDATATRIANGLEW-font->height/2; |
|
827 |
- y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
|
828 |
- y1=body->xywh.y+body->xywh.h-DEFAULTDIRDATATRIANGLEW-font->height/2; |
|
829 |
- } else { |
|
830 |
- x0=body->xywh.x+body->leftsize+fontbig->height/2; |
|
831 |
- x1=body->xywh.x+body->xywh.w-font->height/2; |
|
832 |
- y0=righty+fontbig->height/4+fontbig->height+margin; |
|
833 |
- y1=y0+margin*2+font->height-1; |
|
834 |
- } |
|
835 |
- for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
|
836 |
- Color c=(is_leftside)?((Color){ 65, 65, 65, 255 }):((Color){ 240, 240, 240, 255 }); |
|
867 |
+ xoff=((is_leftside)?0:body->leftsize); |
|
868 |
+ yoff=((is_leftside)?body->xywh.y:righty)+fontbig->height/4+fontbig->height+font->height/4-(is_leftside?body->leftscrollpos:0); |
|
869 |
+ if(is_leftside && dirdata->dirname[0]=='\0') |
|
870 |
+ yoff-=fontbig->height/4+fontbig->height; |
|
871 |
+ for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
|
837 | 872 |
elem=dirdata->listing.elems+k; |
838 |
- if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) |
|
839 |
- continue; |
|
840 |
- if(y>y1) |
|
873 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
874 |
+ if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) { |
|
875 |
+ if(elem->name[0]=='d') |
|
876 |
+ FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
841 | 877 |
continue; |
842 |
- m2=MeasureTextEx(font->font,elem->name+1,font->height,0); |
|
843 |
- if((x+margin*2+m2.x)>x1) { |
|
844 |
- if(!is_leftside) { |
|
845 |
- DrawTextEx(fonthuge->font |
|
846 |
- ,"..." |
|
847 |
- ,(Vector2) {x+margin,y+(fontbig->height-fonthuge->height)} |
|
848 |
- ,fonthuge->height |
|
849 |
- ,0 |
|
850 |
- ,c |
|
851 |
- ); |
|
852 |
- } |
|
853 |
- x=x0,y+=font->height+margin*2+font->height/4; |
|
854 |
- if(y>y1) |
|
855 |
- continue; |
|
856 | 878 |
} |
857 |
- if(is_leftside) { |
|
858 |
- FILLXYWH(elem->left.xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
859 |
- DrawRectangleLines(UNROLLXYWH(elem->left.xywh),c); |
|
860 |
- } else { |
|
861 |
- FILLXYWH(elem->right.xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
862 |
- DrawRectangleLines(UNROLLXYWH(elem->right.xywh),c); |
|
879 |
+ if((thumb->xywh.y+yoff)>(body->xywh.y+body->xywh.h) || thumb->xywh.w==0 || thumb->xywh.h==0) { |
|
880 |
+#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
|
881 |
+ break; |
|
882 |
+ } |
|
883 |
+ if((thumb->xywh.y+yoff+thumb->xywh.h)<0) { |
|
884 |
+ FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
885 |
+ continue; |
|
863 | 886 |
} |
864 |
- DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,c); |
|
865 |
- x+=margin*2+m2.x+font->height/4; |
|
887 |
+ FILLXYWH(thumb->screenxywh,thumb->xywh.x+xoff,thumb->xywh.y+yoff,thumb->xywh.w,thumb->xywh.h); |
|
888 |
+ DrawRectangleLines(UNROLLXYWH(thumb->screenxywh),((Color){ 65, 65, 65, 255 })); |
|
889 |
+ DrawTextEx(font->font,elem->name+1,(Vector2){thumb->screenxywh.x+margin,thumb->screenxywh.y+margin},font->height,0,((Color){ 65, 65, 65, 255 })); |
|
890 |
+ lastx=thumb->screenxywh.x+thumb->screenxywh.w,lasty=thumb->screenxywh.y+thumb->screenxywh.h; |
|
866 | 891 |
} |
867 |
- /* files */ |
|
868 |
- if(is_leftside) { |
|
869 |
- y0=(x==x0)?y:y+font->height+margin*2+font->height/4; |
|
870 |
- sidelen=LEFTIMAGESIDELEN; |
|
871 |
- } else { |
|
872 |
- y0=righty+dirdata->height-sidelen-margin-fontbig->height/4; |
|
873 |
- y1=y0+sidelen+margin; |
|
874 |
- x0-=margin; |
|
892 |
+ for(;k<dirdata->listing.usedelems;k++) { |
|
893 |
+ elem=dirdata->listing.elems+k; |
|
894 |
+ if(elem->name[0]!='d') |
|
895 |
+ continue; |
|
896 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
897 |
+ FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
875 | 898 |
} |
876 |
- for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
|
899 |
+ /* files */ |
|
900 |
+ for(k=0,lastx=lasty=0;k<dirdata->listing.usedelems;k++) { |
|
901 |
+ Texture2D *te; |
|
902 |
+ xywh_t *xywh; |
|
877 | 903 |
elem=dirdata->listing.elems+k; |
904 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
905 |
+ xywh=&(thumb->xywh); |
|
906 |
+ te=&(thumb->texture); |
|
907 |
+ int has_imagedrawn; |
|
878 | 908 |
if(elem->name[0]!='f' && elem->name[0]!='l') |
879 | 909 |
continue; |
880 |
- if(y>y1) |
|
881 |
- continue; |
|
882 |
- if((x+margin*2+sidelen)>x1) { |
|
883 |
- if(!is_leftside) { |
|
884 |
- DrawTextEx(fonthuge->font |
|
885 |
- ,"..." |
|
886 |
- ,(Vector2) {x+margin,y+(sidelen-fonthuge->height)} |
|
887 |
- ,fonthuge->height |
|
888 |
- ,0 |
|
889 |
- ,(Color){ 0,0,0,64 } |
|
890 |
- ); |
|
891 |
- } |
|
892 |
- x=x0,y+=sidelen+margin*2; |
|
893 |
- if(y>y1) |
|
894 |
- continue; |
|
910 |
+ if((xywh->y+yoff)>(body->xywh.y+body->xywh.h) || xywh->w==0 || xywh->h==0) { |
|
911 |
+#warning TODO: if !is_leftside, draw "..." in huge font using lastx,lasty as reference |
|
912 |
+ break; |
|
895 | 913 |
} |
896 |
- if(is_leftside) { |
|
897 |
- FILLXYWH(elem->left.xywh,x+margin,y+margin,sidelen,sidelen); |
|
898 |
- DrawRectangle(UNROLLXYWH(elem->left.xywh),((Color){0,0,0,64})); |
|
899 |
- } else { |
|
900 |
- FILLXYWH(elem->right.xywh,x+margin,y+margin,sidelen,sidelen); |
|
901 |
- DrawRectangle(UNROLLXYWH(elem->right.xywh),((Color){0,0,0,64})); |
|
914 |
+ /* show image */ |
|
915 |
+ has_imagedrawn=0; |
|
916 |
+#if 1 |
|
917 |
+ if(is_imagefilename(elem->name+1)) { |
|
918 |
+ if(thumb->has_texture==0) { |
|
919 |
+ Image im; |
|
920 |
+ char fullpath[2048]; |
|
921 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
922 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
923 |
+ im=LoadImage(fullpath); |
|
924 |
+ if(IsImageValid(im)) { |
|
925 |
+#if 1 |
|
926 |
+fprintf(stderr,"Loaded %s\n",fullpath); |
|
927 |
+#endif |
|
928 |
+ ImageResize(&im,sidelen,sidelen); |
|
929 |
+ *te=LoadTextureFromImage(im); |
|
930 |
+ UnloadImage(im); |
|
931 |
+ thumb->has_texture=1; |
|
932 |
+ } |
|
933 |
+ } |
|
934 |
+ if(thumb->has_texture!=0) { |
|
935 |
+ FILLXYWH(thumb->screenxywh,xywh->x+xoff,xywh->y+yoff,xywh->w,xywh->h); |
|
936 |
+ DrawTexture(*te,thumb->screenxywh.x,thumb->screenxywh.y,WHITE); |
|
937 |
+ has_imagedrawn=1; |
|
938 |
+ lastx=xywh->x+xywh->w,lasty=xywh->y+xywh->h+yoff; |
|
939 |
+ if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,&(thumb->screenxywh))) { |
|
940 |
+ /* draw image in rightside */ |
|
941 |
+ char path[2048]; |
|
942 |
+ int maxw,maxh; |
|
943 |
+ snprintf(path,sizeof(path),"%s/%s",dirdata->dirname,elem->name+1); |
|
944 |
+ path[sizeof(path)-1]='\0'; |
|
945 |
+ maxw=windowwidth-(body->leftsize-DEFAULTDIRDATATRIANGLEW); |
|
946 |
+ maxh=windowheight-body->xywh.y; |
|
947 |
+ if((body->has_texture==0 && !(body->has_failedload && strcmp(body->currenttexture,path)==0)) |
|
948 |
+ || strcmp(body->currenttexture,path)!=0 |
|
949 |
+ ) { |
|
950 |
+ Image im; |
|
951 |
+ int neww,newh; |
|
952 |
+ char fullpath[2048]; |
|
953 |
+ if(body->has_texture) { |
|
954 |
+ UnloadTexture(body->texture); |
|
955 |
+ body->currenttexture[0]='\0'; |
|
956 |
+ body->has_texture=0; |
|
957 |
+ body->has_failedload=0; |
|
958 |
+ } |
|
959 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
960 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
961 |
+ im=LoadImage(fullpath); |
|
962 |
+ if(IsImageValid(im)) { |
|
963 |
+ im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
964 |
+ ImageResize(&im,neww,newh); |
|
965 |
+ body->texture=LoadTextureFromImage(im); |
|
966 |
+ UnloadImage(im); |
|
967 |
+ strncpy(body->currenttexture,fullpath,sizeof(body->currenttexture)); |
|
968 |
+ body->currenttexture[sizeof(body->currenttexture)-1]='\0'; |
|
969 |
+ body->has_texture=1; |
|
970 |
+ body->has_failedload=0; |
|
971 |
+ body->texturew=neww; |
|
972 |
+ body->textureh=newh; |
|
973 |
+ } else { |
|
974 |
+ strncpy(body->currenttexture,fullpath,sizeof(body->currenttexture)); |
|
975 |
+ body->currenttexture[sizeof(body->currenttexture)-1]='\0'; |
|
976 |
+ body->has_texture=0; |
|
977 |
+ body->has_failedload=1; |
|
978 |
+ } |
|
979 |
+ } |
|
980 |
+ if(body->has_texture) { |
|
981 |
+ int x0,y0; |
|
982 |
+ x0=body->leftsize-DEFAULTDIRDATATRIANGLEW; |
|
983 |
+ y0=body->xywh.y; |
|
984 |
+ DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
985 |
+ DrawTexture(body->texture,x0+(maxw-body->texturew)/2,y0+(maxh-body->textureh)/2,WHITE); |
|
986 |
+ flag_skiprightside=1; |
|
987 |
+ } |
|
988 |
+ } |
|
989 |
+ } |
|
902 | 990 |
} |
903 |
- { |
|
991 |
+#endif |
|
992 |
+ if(has_imagedrawn==0) { |
|
904 | 993 |
char *ptr; |
905 | 994 |
char shortname[1024]; |
906 | 995 |
xywh_t *pos; |
907 | 996 |
int l; |
908 |
- Texture2D *te; |
|
909 |
- int *has_texture; |
|
910 | 997 |
font_t *myfont=(is_leftside)?fonthuge:font; |
911 | 998 |
pos=is_leftside?&(elem->left.xywh):&(elem->right.xywh); |
912 |
- te=is_leftside?&(elem->left.texture):&(elem->right.texture); |
|
913 |
- has_texture=is_leftside?&(elem->left.has_texture):&(elem->right.has_texture); |
|
999 |
+ FILLXYWH(thumb->screenxywh,xywh->x+xoff,xywh->y+yoff,xywh->w,xywh->h); |
|
1000 |
+ DrawRectangle(UNROLLXYWH(thumb->screenxywh),((Color){0,0,0,64})); |
|
914 | 1001 |
if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
915 | 1002 |
m2=MeasureTextEx(myfont->font,ptr,myfont->height,0); |
916 |
- DrawTextEx(myfont->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+(font->height)/2+margin+(sidelen-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
|
1003 |
+ DrawTextEx(myfont->font,ptr,(Vector2){xywh->x+xoff+(sidelen-m2.x)/2,xywh->y+yoff+(font->height)/2+(xywh->w-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
|
917 | 1004 |
} |
918 | 1005 |
ptr=(ptr==NULL)?elem->name+1:ptr; |
919 | 1006 |
l=(ptr-(elem->name+1)); |
920 | 1007 |
l=(l>=sizeof(shortname))?sizeof(shortname)-1:l; |
921 | 1008 |
memcpy(shortname,elem->name+1,l); |
922 | 1009 |
shortname[l]='\0'; |
923 |
- DrawRectangle(pos->x,pos->y,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
|
924 |
- DrawTextEx(font->font,shortname,(Vector2){pos->x+font->height/4,pos->y+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
|
925 |
- /* show image */ |
|
926 |
- if(is_imagefilename(elem->name+1)) { |
|
927 |
- if(*has_texture==0) { |
|
928 |
- Image im; |
|
929 |
- char fullpath[2048]; |
|
930 |
- snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
931 |
- fullpath[sizeof(fullpath)-1]='\0'; |
|
932 |
- im=LoadImage(fullpath); |
|
933 |
- if(IsImageValid(im)) { |
|
934 |
- ImageResize(&im,sidelen,sidelen); |
|
935 |
- *te=LoadTextureFromImage(im); |
|
936 |
- UnloadImage(im); |
|
937 |
- *has_texture=1; |
|
938 |
- } |
|
939 |
- } |
|
940 |
- if(*has_texture!=0) { |
|
941 |
- DrawTexture(*te,pos->x,pos->y,WHITE); |
|
942 |
- if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,pos)) { |
|
943 |
- /* draw image in rightside */ |
|
944 |
- char path[2048]; |
|
945 |
- int maxw,maxh; |
|
946 |
- snprintf(path,sizeof(path),"%s/%s",dirdata->dirname,elem->name+1); |
|
947 |
- path[sizeof(path)-1]='\0'; |
|
948 |
- maxw=windowwidth-(body->leftsize-DEFAULTDIRDATATRIANGLEW); |
|
949 |
- maxh=windowheight-body->xywh.y; |
|
950 |
- if(body->has_texture==0 || strcmp(body->currenttexture,path)!=0) { |
|
951 |
- Image im; |
|
952 |
- int neww,newh; |
|
953 |
- char fullpath[2048]; |
|
954 |
- if(body->has_texture) { |
|
955 |
- UnloadTexture(body->texture); |
|
956 |
- body->has_texture=0; |
|
957 |
- } |
|
958 |
- snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
959 |
- fullpath[sizeof(fullpath)-1]='\0'; |
|
960 |
- im=LoadImage(fullpath); |
|
961 |
- if(IsImageValid(im)) { |
|
962 |
- im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
963 |
- ImageResize(&im,neww,newh); |
|
964 |
- body->texture=LoadTextureFromImage(im); |
|
965 |
- UnloadImage(im); |
|
966 |
- body->has_texture=1; |
|
967 |
- body->texturew=neww; |
|
968 |
- body->textureh=newh; |
|
969 |
- } |
|
970 |
- } |
|
971 |
- if(body->has_texture) { |
|
972 |
- int x0,y0; |
|
973 |
- x0=body->leftsize-DEFAULTDIRDATATRIANGLEW; |
|
974 |
- y0=body->xywh.y; |
|
975 |
- DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
976 |
- DrawTexture(body->texture,x0+(maxw-body->texturew)/2,y0+(maxh-body->textureh)/2,WHITE); |
|
977 |
- flag_skiprightside=1; |
|
978 |
- } |
|
979 |
- } |
|
980 |
- } |
|
981 |
- } |
|
1010 |
+ DrawRectangle(pos->x+xoff,pos->y+yoff,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
|
1011 |
+ DrawTextEx(font->font,shortname,(Vector2){pos->x+xoff+font->height/4,pos->y+yoff+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
|
1012 |
+ lastx=xywh->x+xoff+xywh->w,lasty=xywh->y+yoff+xywh->h; |
|
982 | 1013 |
} |
983 |
- x+=margin*2+sidelen; |
|
1014 |
+ } |
|
1015 |
+ for(;k<dirdata->listing.usedelems;k++) { |
|
1016 |
+ elem=dirdata->listing.elems+k; |
|
1017 |
+ if(elem->name[0]!='f' && elem->name[0]!='l') |
|
1018 |
+ continue; |
|
1019 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
1020 |
+ FILLXYWH(thumb->screenxywh,0,0,0,0); |
|
984 | 1021 |
} |
985 | 1022 |
/* ...finishing touchs */ |
986 | 1023 |
if(is_leftside) { |
... | ... |
@@ -1182,15 +1219,18 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1182 | 1219 |
if(ld->left.has_texture) { |
1183 | 1220 |
UnloadTexture(ld->left.texture); |
1184 | 1221 |
ld->left.has_texture=0; |
1222 |
+ ld->left.has_failedload=0; |
|
1185 | 1223 |
} |
1186 | 1224 |
if(ld->right.has_texture) { |
1187 | 1225 |
UnloadTexture(ld->right.texture); |
1188 | 1226 |
ld->right.has_texture=0; |
1227 |
+ ld->right.has_failedload=0; |
|
1189 | 1228 |
} |
1190 | 1229 |
} |
1191 | 1230 |
/* reset struct */ |
1192 | 1231 |
listing->usedelems=listing->usedbuf=0; |
1193 | 1232 |
memset(listing->elems,0,sizeof(listingdata_t)*listing->sizeelems); |
1233 |
+ listing->has_leftxywh=listing->has_rightxywh=0; |
|
1194 | 1234 |
/* fill listing */ |
1195 | 1235 |
if(pathprefix==NULL && parampath==NULL) |
1196 | 1236 |
return(-1); /* nothing to fill */ |
... | ... |
@@ -1289,10 +1329,12 @@ listing_freedata(listing_t *listing) |
1289 | 1329 |
if(ld->left.has_texture) { |
1290 | 1330 |
UnloadTexture(ld->left.texture); |
1291 | 1331 |
ld->left.has_texture=0; |
1332 |
+ ld->left.has_failedload=0; |
|
1292 | 1333 |
} |
1293 | 1334 |
if(ld->right.has_texture) { |
1294 | 1335 |
UnloadTexture(ld->right.texture); |
1295 | 1336 |
ld->right.has_texture=0; |
1337 |
+ ld->right.has_failedload=0; |
|
1296 | 1338 |
} |
1297 | 1339 |
} |
1298 | 1340 |
free(listing->elems),listing->elems=NULL,listing->sizeelems=listing->usedelems=0; |
... | ... |
@@ -1302,6 +1344,70 @@ listing_freedata(listing_t *listing) |
1302 | 1344 |
return; |
1303 | 1345 |
} |
1304 | 1346 |
|
1347 |
+int |
|
1348 |
+listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_leftside) |
|
1349 |
+{ |
|
1350 |
+ int x0,y0,x1; |
|
1351 |
+ int k,x,y; |
|
1352 |
+ Vector2 m2; |
|
1353 |
+ int margin; |
|
1354 |
+ listingdata_t *elem; |
|
1355 |
+ thumb_t *thumb; |
|
1356 |
+ if(listing==NULL || font==NULL) |
|
1357 |
+ return(-1); /* sanity check failed */ |
|
1358 |
+ margin=font->height/4; |
|
1359 |
+ /* directories */ |
|
1360 |
+ if(is_leftside) { |
|
1361 |
+ x0=font->height/2; |
|
1362 |
+ x1=w-DEFAULTDIRDATATRIANGLEW-font->height/2; |
|
1363 |
+ y0=0; |
|
1364 |
+ } else { |
|
1365 |
+ x0=FONTBIGSIZE/2; |
|
1366 |
+ x1=w-font->height/2; |
|
1367 |
+ y0=0; |
|
1368 |
+ } |
|
1369 |
+ for(k=0,x=x0,y=y0;k<listing->usedelems;k++) { |
|
1370 |
+ elem=listing->elems+k; |
|
1371 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
1372 |
+ if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) |
|
1373 |
+ continue; |
|
1374 |
+ m2=MeasureTextEx(font->font,elem->name+1,font->height,0); |
|
1375 |
+ if((x+margin*2+m2.x)>x1 && !(is_leftside==0 && y>y0)) |
|
1376 |
+ x=x0,y+=font->height+margin*2+font->height/4; |
|
1377 |
+ if(is_leftside==0 && y>y0) { |
|
1378 |
+ FILLXYWH(thumb->xywh,0,0,0,0); |
|
1379 |
+ continue; |
|
1380 |
+ } |
|
1381 |
+ FILLXYWH(thumb->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
1382 |
+ x+=margin*2+m2.x+font->height/4; |
|
1383 |
+ } |
|
1384 |
+ y+=((x==x0)?0:font->height+margin*2+font->height/4); |
|
1385 |
+ /* files */ |
|
1386 |
+ if(is_leftside) |
|
1387 |
+ y0=y; |
|
1388 |
+ else |
|
1389 |
+ y0+=margin*2+font->height+margin; |
|
1390 |
+ for(k=0,x=x0,y=y0;k<listing->usedelems;k++) { |
|
1391 |
+ elem=listing->elems+k; |
|
1392 |
+ thumb=(is_leftside)?&(elem->left):&(elem->right); |
|
1393 |
+ if(elem->name[0]!='f' && elem->name[0]!='l') |
|
1394 |
+ continue; |
|
1395 |
+ if(!is_leftside && y>y0) { |
|
1396 |
+ FILLXYWH(thumb->xywh,0,0,0,0); |
|
1397 |
+ continue; |
|
1398 |
+ } |
|
1399 |
+ if((x+margin*2+sidelen)>x1 && !(is_leftside==0 && y>y0)) |
|
1400 |
+ x=x0,y+=sidelen+margin*2; |
|
1401 |
+ if(is_leftside==0 && y>y0) { |
|
1402 |
+ FILLXYWH(thumb->xywh,0,0,0,0); |
|
1403 |
+ continue; |
|
1404 |
+ } |
|
1405 |
+ FILLXYWH(thumb->xywh,x,y,sidelen,sidelen); |
|
1406 |
+ x+=margin*2+sidelen; |
|
1407 |
+ } |
|
1408 |
+ return(0); |
|
1409 |
+} |
|
1410 |
+ |
|
1305 | 1411 |
int |
1306 | 1412 |
is_imagefilename(char *filename) |
1307 | 1413 |
{ |
... | ... |
@@ -17,6 +17,7 @@ |
17 | 17 |
* 20250301 Aesthetic fixes for leftside. |
18 | 18 |
* Basic image loading. |
19 | 19 |
* Show big image on hover. |
20 |
+ * Preserve aspect ratio of big image. |
|
20 | 21 |
* |
21 | 22 |
* Author: Dario Rodriguez dario@darionomono.com |
22 | 23 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -118,13 +119,15 @@ typedef struct menubar_t { |
118 | 119 |
font_t *ptrfont; |
119 | 120 |
} menubar_t; |
120 | 121 |
|
121 |
-typedef struct listingdata_t { |
|
122 |
- xywh_t leftxywh; |
|
123 |
- Texture2D lefttexture; |
|
124 |
- int has_lefttexture; |
|
122 |
+typedef struct thumb_t { |
|
125 | 123 |
xywh_t xywh; |
126 | 124 |
Texture2D texture; |
127 | 125 |
int has_texture; |
126 |
+} thumb_t; |
|
127 |
+ |
|
128 |
+typedef struct listingdata_t { |
|
129 |
+ thumb_t left; |
|
130 |
+ thumb_t right; |
|
128 | 131 |
char *name; /* first byte in the name is the type, next is the name, i.e. a directory is "dhome" and a file is "f.bashrc" (this is done for easier sorting) */ |
129 | 132 |
} listingdata_t; |
130 | 133 |
|
... | ... |
@@ -158,6 +161,8 @@ typedef struct body_t { |
158 | 161 |
font_t *ptrfonthuge; |
159 | 162 |
char currenttexture[1024]; |
160 | 163 |
Texture2D texture; |
164 |
+ int texturew; |
|
165 |
+ int textureh; |
|
161 | 166 |
int has_texture; |
162 | 167 |
} body_t; |
163 | 168 |
|
... | ... |
@@ -191,7 +196,7 @@ void im_body_free(body_t *body); |
191 | 196 |
int im_body_add(body_t *body,char *dir); |
192 | 197 |
|
193 | 198 |
int im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
194 |
-int im_body_draw(body_t *body, Vector2 mousepos, int windowwidth, int windowheight); |
|
199 |
+int im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight); |
|
195 | 200 |
|
196 | 201 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
197 | 202 |
void listing_freedata(listing_t *listing); |
... | ... |
@@ -202,6 +207,7 @@ int imutil_submenu_count(char *menus); |
202 | 207 |
char *imutil_submenu_get(char *menus, int targetn, int *len); |
203 | 208 |
char *imutil_strduplen(char *str, int len); |
204 | 209 |
int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh); |
210 |
+int im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh); |
|
205 | 211 |
int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
206 | 212 |
int *getcodepoints(int *sizecodepoints); |
207 | 213 |
int is_imagefilename(char *filename); |
... | ... |
@@ -242,7 +248,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
242 | 248 |
/* draw screen contents */ |
243 | 249 |
BeginDrawing(); |
244 | 250 |
ClearBackground(RAYWHITE); |
245 |
- im_body_draw(im->body,mousepos,im->w,im->h); |
|
251 |
+ im_body_draw(im->body,mousepos,lmbdown,im->w,im->h); |
|
246 | 252 |
im_menubar_draw(im->menubar,im->w,im->h); |
247 | 253 |
#if 0 |
248 | 254 |
{ |
... | ... |
@@ -717,7 +723,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
717 | 723 |
ld=dirdata->listing.elems+i; |
718 | 724 |
if(ld->name[0]!='d') |
719 | 725 |
continue; |
720 |
- if(is_imutil_insidexywh(mousepos,&(ld->leftxywh))) { |
|
726 |
+ if(is_imutil_insidexywh(mousepos,&(ld->left.xywh))) { |
|
721 | 727 |
char *newname,*oldprefix; |
722 | 728 |
int l,l0,l1; |
723 | 729 |
static char sep[]={SEP}; |
... | ... |
@@ -745,7 +751,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
745 | 751 |
} |
746 | 752 |
|
747 | 753 |
int |
748 |
-im_body_draw(body_t *body, Vector2 mousepos, int windowwidth, int windowheight) |
|
754 |
+im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int windowwidth, int windowheight) |
|
749 | 755 |
{ |
750 | 756 |
int i,x,y,k,margin,righty; |
751 | 757 |
dirdata_t *dirdata; |
... | ... |
@@ -849,11 +855,11 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
849 | 855 |
continue; |
850 | 856 |
} |
851 | 857 |
if(is_leftside) { |
852 |
- FILLXYWH(elem->leftxywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
853 |
- DrawRectangleLines(UNROLLXYWH(elem->leftxywh),c); |
|
858 |
+ FILLXYWH(elem->left.xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
859 |
+ DrawRectangleLines(UNROLLXYWH(elem->left.xywh),c); |
|
854 | 860 |
} else { |
855 |
- FILLXYWH(elem->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
856 |
- DrawRectangleLines(UNROLLXYWH(elem->xywh),c); |
|
861 |
+ FILLXYWH(elem->right.xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
862 |
+ DrawRectangleLines(UNROLLXYWH(elem->right.xywh),c); |
|
857 | 863 |
} |
858 | 864 |
DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,c); |
859 | 865 |
x+=margin*2+m2.x+font->height/4; |
... | ... |
@@ -888,11 +894,11 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
888 | 894 |
continue; |
889 | 895 |
} |
890 | 896 |
if(is_leftside) { |
891 |
- FILLXYWH(elem->leftxywh,x+margin,y+margin,sidelen,sidelen); |
|
892 |
- DrawRectangle(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,64})); |
|
897 |
+ FILLXYWH(elem->left.xywh,x+margin,y+margin,sidelen,sidelen); |
|
898 |
+ DrawRectangle(UNROLLXYWH(elem->left.xywh),((Color){0,0,0,64})); |
|
893 | 899 |
} else { |
894 |
- FILLXYWH(elem->xywh,x+margin,y+margin,sidelen,sidelen); |
|
895 |
- DrawRectangle(UNROLLXYWH(elem->xywh),((Color){0,0,0,64})); |
|
900 |
+ FILLXYWH(elem->right.xywh,x+margin,y+margin,sidelen,sidelen); |
|
901 |
+ DrawRectangle(UNROLLXYWH(elem->right.xywh),((Color){0,0,0,64})); |
|
896 | 902 |
} |
897 | 903 |
{ |
898 | 904 |
char *ptr; |
... | ... |
@@ -902,9 +908,9 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
902 | 908 |
Texture2D *te; |
903 | 909 |
int *has_texture; |
904 | 910 |
font_t *myfont=(is_leftside)?fonthuge:font; |
905 |
- pos=is_leftside?&(elem->leftxywh):&(elem->xywh); |
|
906 |
- te=is_leftside?&(elem->lefttexture):&(elem->texture); |
|
907 |
- has_texture=is_leftside?&(elem->has_lefttexture):&(elem->has_texture); |
|
911 |
+ pos=is_leftside?&(elem->left.xywh):&(elem->right.xywh); |
|
912 |
+ te=is_leftside?&(elem->left.texture):&(elem->right.texture); |
|
913 |
+ has_texture=is_leftside?&(elem->left.has_texture):&(elem->right.has_texture); |
|
908 | 914 |
if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
909 | 915 |
m2=MeasureTextEx(myfont->font,ptr,myfont->height,0); |
910 | 916 |
DrawTextEx(myfont->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+(font->height)/2+margin+(sidelen-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
... | ... |
@@ -933,13 +939,17 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
933 | 939 |
} |
934 | 940 |
if(*has_texture!=0) { |
935 | 941 |
DrawTexture(*te,pos->x,pos->y,WHITE); |
936 |
- if(is_leftside && is_imutil_insidexywh(mousepos,pos)) { |
|
942 |
+ if(is_leftside && lmbdown==0 && is_imutil_insidexywh(mousepos,pos)) { |
|
937 | 943 |
/* draw image in rightside */ |
938 | 944 |
char path[2048]; |
945 |
+ int maxw,maxh; |
|
939 | 946 |
snprintf(path,sizeof(path),"%s/%s",dirdata->dirname,elem->name+1); |
940 | 947 |
path[sizeof(path)-1]='\0'; |
948 |
+ maxw=windowwidth-(body->leftsize-DEFAULTDIRDATATRIANGLEW); |
|
949 |
+ maxh=windowheight-body->xywh.y; |
|
941 | 950 |
if(body->has_texture==0 || strcmp(body->currenttexture,path)!=0) { |
942 | 951 |
Image im; |
952 |
+ int neww,newh; |
|
943 | 953 |
char fullpath[2048]; |
944 | 954 |
if(body->has_texture) { |
945 | 955 |
UnloadTexture(body->texture); |
... | ... |
@@ -949,15 +959,22 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
949 | 959 |
fullpath[sizeof(fullpath)-1]='\0'; |
950 | 960 |
im=LoadImage(fullpath); |
951 | 961 |
if(IsImageValid(im)) { |
952 |
- ImageResize(&im,windowwidth-body->leftsize,windowheight-body->xywh.y); |
|
962 |
+ im_util_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
|
963 |
+ ImageResize(&im,neww,newh); |
|
953 | 964 |
body->texture=LoadTextureFromImage(im); |
954 | 965 |
UnloadImage(im); |
955 | 966 |
body->has_texture=1; |
967 |
+ body->texturew=neww; |
|
968 |
+ body->textureh=newh; |
|
956 | 969 |
} |
957 | 970 |
} |
958 | 971 |
if(body->has_texture) { |
959 |
- DrawTexture(body->texture,body->leftsize,body->xywh.y,WHITE); |
|
960 |
- flag_skiprightside=1; |
|
972 |
+ int x0,y0; |
|
973 |
+ x0=body->leftsize-DEFAULTDIRDATATRIANGLEW; |
|
974 |
+ y0=body->xywh.y; |
|
975 |
+ DrawRectangle(x0,y0,maxw,maxh,(Color){ 215, 215, 215, 255 } ); |
|
976 |
+ DrawTexture(body->texture,x0+(maxw-body->texturew)/2,y0+(maxh-body->textureh)/2,WHITE); |
|
977 |
+ flag_skiprightside=1; |
|
961 | 978 |
} |
962 | 979 |
} |
963 | 980 |
} |
... | ... |
@@ -967,9 +984,12 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
967 | 984 |
} |
968 | 985 |
/* ...finishing touchs */ |
969 | 986 |
if(is_leftside) { |
970 |
- /* draw right side "current" marker inside left side area */ |
|
971 |
- DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
987 |
+ ; |
|
972 | 988 |
} else { |
989 |
+ if(i==body->currentdirdata) { |
|
990 |
+ /* draw right side "current" marker inside left side area */ |
|
991 |
+ DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
992 |
+ } |
|
973 | 993 |
/* advance to next element */ |
974 | 994 |
righty+=dirdata->height; |
975 | 995 |
} |
... | ... |
@@ -1092,6 +1112,22 @@ is_imutil_insidexywh(Vector2 pos, xywh_t *xywh) |
1092 | 1112 |
return(0); |
1093 | 1113 |
} |
1094 | 1114 |
|
1115 |
+int |
|
1116 |
+im_util_aspectmaximize(int w, int h, int maxw, int maxh, int *neww, int *newh) |
|
1117 |
+{ |
|
1118 |
+ if(neww==NULL || newh==NULL || w==0 || h==0 || maxw==0 || maxh==0) |
|
1119 |
+ return(-1); |
|
1120 |
+ if((w/h)>(maxw/maxh)) { |
|
1121 |
+ *neww=maxw; |
|
1122 |
+ *newh=h*maxw/w; |
|
1123 |
+ } else { /* (w/h)<=(maxw/maxh) */ |
|
1124 |
+ *newh=maxh; |
|
1125 |
+ *neww=w*maxh/h; |
|
1126 |
+ } |
|
1127 |
+ return(0); |
|
1128 |
+} |
|
1129 |
+ |
|
1130 |
+ |
|
1095 | 1131 |
int |
1096 | 1132 |
menudata_pos2option(menudata_t *menudata, Vector2 pos) |
1097 | 1133 |
{ |
... | ... |
@@ -1143,13 +1179,13 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1143 | 1179 |
/* free old textures */ |
1144 | 1180 |
for(i=0;i<listing->usedelems;i++) { |
1145 | 1181 |
ld=listing->elems+i; |
1146 |
- if(ld->has_lefttexture) { |
|
1147 |
- UnloadTexture(ld->lefttexture); |
|
1148 |
- ld->has_lefttexture=0; |
|
1182 |
+ if(ld->left.has_texture) { |
|
1183 |
+ UnloadTexture(ld->left.texture); |
|
1184 |
+ ld->left.has_texture=0; |
|
1149 | 1185 |
} |
1150 |
- if(ld->has_texture) { |
|
1151 |
- UnloadTexture(ld->texture); |
|
1152 |
- ld->has_texture=0; |
|
1186 |
+ if(ld->right.has_texture) { |
|
1187 |
+ UnloadTexture(ld->right.texture); |
|
1188 |
+ ld->right.has_texture=0; |
|
1153 | 1189 |
} |
1154 | 1190 |
} |
1155 | 1191 |
/* reset struct */ |
... | ... |
@@ -1250,13 +1286,13 @@ listing_freedata(listing_t *listing) |
1250 | 1286 |
listingdata_t *ld; |
1251 | 1287 |
for(i=0;i<listing->usedelems;i++) { |
1252 | 1288 |
ld=listing->elems+i; |
1253 |
- if(ld->has_lefttexture) { |
|
1254 |
- UnloadTexture(ld->lefttexture); |
|
1255 |
- ld->has_lefttexture=0; |
|
1289 |
+ if(ld->left.has_texture) { |
|
1290 |
+ UnloadTexture(ld->left.texture); |
|
1291 |
+ ld->left.has_texture=0; |
|
1256 | 1292 |
} |
1257 |
- if(ld->has_texture) { |
|
1258 |
- UnloadTexture(ld->texture); |
|
1259 |
- ld->has_texture=0; |
|
1293 |
+ if(ld->right.has_texture) { |
|
1294 |
+ UnloadTexture(ld->right.texture); |
|
1295 |
+ ld->right.has_texture=0; |
|
1260 | 1296 |
} |
1261 | 1297 |
} |
1262 | 1298 |
free(listing->elems),listing->elems=NULL,listing->sizeelems=listing->usedelems=0; |
... | ... |
@@ -16,6 +16,7 @@ |
16 | 16 |
* 20250228 Navigate directories |
17 | 17 |
* 20250301 Aesthetic fixes for leftside. |
18 | 18 |
* Basic image loading. |
19 |
+ * Show big image on hover. |
|
19 | 20 |
* |
20 | 21 |
* Author: Dario Rodriguez dario@darionomono.com |
21 | 22 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -155,6 +156,9 @@ typedef struct body_t { |
155 | 156 |
font_t *ptrfont; |
156 | 157 |
font_t *ptrfontbig; |
157 | 158 |
font_t *ptrfonthuge; |
159 |
+ char currenttexture[1024]; |
|
160 |
+ Texture2D texture; |
|
161 |
+ int has_texture; |
|
158 | 162 |
} body_t; |
159 | 163 |
|
160 | 164 |
typedef struct im_t { |
... | ... |
@@ -187,7 +191,7 @@ void im_body_free(body_t *body); |
187 | 191 |
int im_body_add(body_t *body,char *dir); |
188 | 192 |
|
189 | 193 |
int im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
190 |
-int im_body_draw(body_t *body, int windowwidth, int windowheight); |
|
194 |
+int im_body_draw(body_t *body, Vector2 mousepos, int windowwidth, int windowheight); |
|
191 | 195 |
|
192 | 196 |
int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
193 | 197 |
void listing_freedata(listing_t *listing); |
... | ... |
@@ -238,7 +242,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
238 | 242 |
/* draw screen contents */ |
239 | 243 |
BeginDrawing(); |
240 | 244 |
ClearBackground(RAYWHITE); |
241 |
- im_body_draw(im->body,im->w,im->h); |
|
245 |
+ im_body_draw(im->body,mousepos,im->w,im->h); |
|
242 | 246 |
im_menubar_draw(im->menubar,im->w,im->h); |
243 | 247 |
#if 0 |
244 | 248 |
{ |
... | ... |
@@ -641,6 +645,10 @@ im_body_free(body_t *body) |
641 | 645 |
} |
642 | 646 |
free(body->dirdata),body->dirdata=NULL,body->sizedirdata=0; |
643 | 647 |
} |
648 |
+ if(body->has_texture) { |
|
649 |
+ UnloadTexture(body->texture); |
|
650 |
+ body->has_texture=0; |
|
651 |
+ } |
|
644 | 652 |
free(body),body=NULL; |
645 | 653 |
return; |
646 | 654 |
} |
... | ... |
@@ -737,7 +745,7 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
737 | 745 |
} |
738 | 746 |
|
739 | 747 |
int |
740 |
-im_body_draw(body_t *body, int windowwidth, int windowheight) |
|
748 |
+im_body_draw(body_t *body, Vector2 mousepos, int windowwidth, int windowheight) |
|
741 | 749 |
{ |
742 | 750 |
int i,x,y,k,margin,righty; |
743 | 751 |
dirdata_t *dirdata; |
... | ... |
@@ -745,6 +753,7 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
745 | 753 |
Vector2 v2,m2; |
746 | 754 |
font_t *font,*fontbig,*fonthuge; |
747 | 755 |
int is_leftside; |
756 |
+ int flag_skiprightside; |
|
748 | 757 |
if(body==NULL) |
749 | 758 |
return(-1); |
750 | 759 |
font=body->ptrfont; |
... | ... |
@@ -756,13 +765,13 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
756 | 765 |
DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
757 | 766 |
/* draw right side background */ |
758 | 767 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
759 |
- for(i=0,y=righty=body->xywh.y;i<body->sizedirdata;i++) { |
|
760 |
- if((dirdata=body->dirdata[i])==NULL) |
|
761 |
- continue; |
|
762 |
- /* two passes for each dirdata, first leftside, then rightside */ |
|
763 |
- for(is_leftside=1;is_leftside>=0;is_leftside--) { |
|
768 |
+ /* first pass, draw leftside, second pass, draw all of rightside */ |
|
769 |
+ for(is_leftside=1,flag_skiprightside=0;is_leftside>=0 && flag_skiprightside==0;is_leftside--) { |
|
770 |
+ for(i=(is_leftside)?body->currentdirdata:0,y=righty=body->xywh.y;(is_leftside && i==body->currentdirdata) || (!is_leftside && i<body->sizedirdata);i++) { |
|
764 | 771 |
int x0,y0,x1,y1; |
765 | 772 |
int sidelen; |
773 |
+ if((dirdata=body->dirdata[i])==NULL) |
|
774 |
+ continue; |
|
766 | 775 |
if(is_leftside && !(i==body->currentdirdata)) |
767 | 776 |
continue; /* this element is not in leftside */ |
768 | 777 |
margin=font->height/4; |
... | ... |
@@ -922,8 +931,36 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
922 | 931 |
*has_texture=1; |
923 | 932 |
} |
924 | 933 |
} |
925 |
- if(*has_texture!=0) |
|
934 |
+ if(*has_texture!=0) { |
|
926 | 935 |
DrawTexture(*te,pos->x,pos->y,WHITE); |
936 |
+ if(is_leftside && is_imutil_insidexywh(mousepos,pos)) { |
|
937 |
+ /* draw image in rightside */ |
|
938 |
+ char path[2048]; |
|
939 |
+ snprintf(path,sizeof(path),"%s/%s",dirdata->dirname,elem->name+1); |
|
940 |
+ path[sizeof(path)-1]='\0'; |
|
941 |
+ if(body->has_texture==0 || strcmp(body->currenttexture,path)!=0) { |
|
942 |
+ Image im; |
|
943 |
+ char fullpath[2048]; |
|
944 |
+ if(body->has_texture) { |
|
945 |
+ UnloadTexture(body->texture); |
|
946 |
+ body->has_texture=0; |
|
947 |
+ } |
|
948 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
949 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
950 |
+ im=LoadImage(fullpath); |
|
951 |
+ if(IsImageValid(im)) { |
|
952 |
+ ImageResize(&im,windowwidth-body->leftsize,windowheight-body->xywh.y); |
|
953 |
+ body->texture=LoadTextureFromImage(im); |
|
954 |
+ UnloadImage(im); |
|
955 |
+ body->has_texture=1; |
|
956 |
+ } |
|
957 |
+ } |
|
958 |
+ if(body->has_texture) { |
|
959 |
+ DrawTexture(body->texture,body->leftsize,body->xywh.y,WHITE); |
|
960 |
+ flag_skiprightside=1; |
|
961 |
+ } |
|
962 |
+ } |
|
963 |
+ } |
|
927 | 964 |
} |
928 | 965 |
} |
929 | 966 |
x+=margin*2+sidelen; |
... | ... |
@@ -14,7 +14,8 @@ |
14 | 14 |
* 20250225 Draw image placeholders |
15 | 15 |
* 20250226 Fix rightside positions |
16 | 16 |
* 20250228 Navigate directories |
17 |
- * 20250301 Aestetic fixes for leftside. |
|
17 |
+ * 20250301 Aesthetic fixes for leftside. |
|
18 |
+ * Basic image loading. |
|
18 | 19 |
* |
19 | 20 |
* Author: Dario Rodriguez dario@darionomono.com |
20 | 21 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -70,6 +71,22 @@ |
70 | 71 |
#define UNROLLXYWH(xywh) (xywh).x,(xywh).y,(xywh).w,(xywh).h |
71 | 72 |
#endif |
72 | 73 |
|
74 |
+#ifndef __linux__ |
|
75 |
+/* the old raylib used in the windows build lacks this function */ |
|
76 |
+bool IsImageValid(Image image) |
|
77 |
+{ |
|
78 |
+ bool result = false; |
|
79 |
+ |
|
80 |
+ if ((image.data != NULL) && // Validate pixel data available |
|
81 |
+ (image.width > 0) && // Validate image width |
|
82 |
+ (image.height > 0) && // Validate image height |
|
83 |
+ (image.format > 0) && // Validate image format |
|
84 |
+ (image.mipmaps > 0)) result = true; // Validate image mipmaps (at least 1 for basic mipmap level) |
|
85 |
+ |
|
86 |
+ return result; |
|
87 |
+} |
|
88 |
+#endif |
|
89 |
+ |
|
73 | 90 |
typedef struct xywh_t { |
74 | 91 |
int x; |
75 | 92 |
int y; |
... | ... |
@@ -102,7 +119,11 @@ typedef struct menubar_t { |
102 | 119 |
|
103 | 120 |
typedef struct listingdata_t { |
104 | 121 |
xywh_t leftxywh; |
122 |
+ Texture2D lefttexture; |
|
123 |
+ int has_lefttexture; |
|
105 | 124 |
xywh_t xywh; |
125 |
+ Texture2D texture; |
|
126 |
+ int has_texture; |
|
106 | 127 |
char *name; /* first byte in the name is the type, next is the name, i.e. a directory is "dhome" and a file is "f.bashrc" (this is done for easier sorting) */ |
107 | 128 |
} listingdata_t; |
108 | 129 |
|
... | ... |
@@ -179,6 +200,7 @@ char *imutil_strduplen(char *str, int len); |
179 | 200 |
int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh); |
180 | 201 |
int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
181 | 202 |
int *getcodepoints(int *sizecodepoints); |
203 |
+int is_imagefilename(char *filename); |
|
182 | 204 |
|
183 | 205 |
int |
184 | 206 |
main(int argc, char *argv[]) |
... | ... |
@@ -580,6 +602,7 @@ body_t * |
580 | 602 |
im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir) |
581 | 603 |
{ |
582 | 604 |
body_t *body; |
605 |
+ static char sep[]={SEP}; |
|
583 | 606 |
if(font==NULL || fontbig==NULL || fonthuge==NULL || rootdir==NULL) |
584 | 607 |
return(NULL); /* sanity check failed */ |
585 | 608 |
if((body=calloc(1,sizeof(body_t)))==NULL |
... | ... |
@@ -593,6 +616,8 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
593 | 616 |
body->ptrfont=font; |
594 | 617 |
body->ptrfontbig=fontbig; |
595 | 618 |
body->ptrfonthuge=fonthuge; |
619 |
+ if(body->rootdir[0]!='\0' && strcmp(body->rootdir,SEP)!=0 && body->rootdir[strlen(body->rootdir)-1]==sep[0]) |
|
620 |
+ body->rootdir[strlen(body->rootdir)-1]='\0'; /* rootdir doesn't need the final '/' */ |
|
596 | 621 |
return(body); |
597 | 622 |
} |
598 | 623 |
|
... | ... |
@@ -865,8 +890,12 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
865 | 890 |
char shortname[1024]; |
866 | 891 |
xywh_t *pos; |
867 | 892 |
int l; |
893 |
+ Texture2D *te; |
|
894 |
+ int *has_texture; |
|
868 | 895 |
font_t *myfont=(is_leftside)?fonthuge:font; |
869 | 896 |
pos=is_leftside?&(elem->leftxywh):&(elem->xywh); |
897 |
+ te=is_leftside?&(elem->lefttexture):&(elem->texture); |
|
898 |
+ has_texture=is_leftside?&(elem->has_lefttexture):&(elem->has_texture); |
|
870 | 899 |
if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
871 | 900 |
m2=MeasureTextEx(myfont->font,ptr,myfont->height,0); |
872 | 901 |
DrawTextEx(myfont->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+(font->height)/2+margin+(sidelen-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
... | ... |
@@ -878,6 +907,24 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
878 | 907 |
shortname[l]='\0'; |
879 | 908 |
DrawRectangle(pos->x,pos->y,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
880 | 909 |
DrawTextEx(font->font,shortname,(Vector2){pos->x+font->height/4,pos->y+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
910 |
+ /* show image */ |
|
911 |
+ if(is_imagefilename(elem->name+1)) { |
|
912 |
+ if(*has_texture==0) { |
|
913 |
+ Image im; |
|
914 |
+ char fullpath[2048]; |
|
915 |
+ snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
|
916 |
+ fullpath[sizeof(fullpath)-1]='\0'; |
|
917 |
+ im=LoadImage(fullpath); |
|
918 |
+ if(IsImageValid(im)) { |
|
919 |
+ ImageResize(&im,sidelen,sidelen); |
|
920 |
+ *te=LoadTextureFromImage(im); |
|
921 |
+ UnloadImage(im); |
|
922 |
+ *has_texture=1; |
|
923 |
+ } |
|
924 |
+ } |
|
925 |
+ if(*has_texture!=0) |
|
926 |
+ DrawTexture(*te,pos->x,pos->y,WHITE); |
|
927 |
+ } |
|
881 | 928 |
} |
882 | 929 |
x+=margin*2+sidelen; |
883 | 930 |
} |
... | ... |
@@ -1048,15 +1095,30 @@ strptrcmp(void *a,void *b) |
1048 | 1095 |
int |
1049 | 1096 |
listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort) |
1050 | 1097 |
{ |
1051 |
- int l; |
|
1098 |
+ int i,l; |
|
1052 | 1099 |
DIR *d; |
1053 | 1100 |
struct dirent *de; |
1054 | 1101 |
unsigned char dtype; |
1055 | 1102 |
char path[1024]; |
1103 |
+ listingdata_t *ld; |
|
1056 | 1104 |
if(listing==NULL) |
1057 | 1105 |
return(-1); /* sanity check failed */ |
1106 |
+ /* free old textures */ |
|
1107 |
+ for(i=0;i<listing->usedelems;i++) { |
|
1108 |
+ ld=listing->elems+i; |
|
1109 |
+ if(ld->has_lefttexture) { |
|
1110 |
+ UnloadTexture(ld->lefttexture); |
|
1111 |
+ ld->has_lefttexture=0; |
|
1112 |
+ } |
|
1113 |
+ if(ld->has_texture) { |
|
1114 |
+ UnloadTexture(ld->texture); |
|
1115 |
+ ld->has_texture=0; |
|
1116 |
+ } |
|
1117 |
+ } |
|
1118 |
+ /* reset struct */ |
|
1058 | 1119 |
listing->usedelems=listing->usedbuf=0; |
1059 | 1120 |
memset(listing->elems,0,sizeof(listingdata_t)*listing->sizeelems); |
1121 |
+ /* fill listing */ |
|
1060 | 1122 |
if(pathprefix==NULL && parampath==NULL) |
1061 | 1123 |
return(-1); /* nothing to fill */ |
1062 | 1124 |
snprintf(path,sizeof(path),"%s%s%s",(pathprefix!=NULL)?pathprefix:"",SEP,(parampath!=NULL)?parampath:""); |
... | ... |
@@ -1146,10 +1208,50 @@ listing_freedata(listing_t *listing) |
1146 | 1208 |
{ |
1147 | 1209 |
if(listing==NULL) |
1148 | 1210 |
return; /* nothing to do */ |
1149 |
- if(listing->elems!=NULL) |
|
1211 |
+ if(listing->elems!=NULL) { |
|
1212 |
+ int i; |
|
1213 |
+ listingdata_t *ld; |
|
1214 |
+ for(i=0;i<listing->usedelems;i++) { |
|
1215 |
+ ld=listing->elems+i; |
|
1216 |
+ if(ld->has_lefttexture) { |
|
1217 |
+ UnloadTexture(ld->lefttexture); |
|
1218 |
+ ld->has_lefttexture=0; |
|
1219 |
+ } |
|
1220 |
+ if(ld->has_texture) { |
|
1221 |
+ UnloadTexture(ld->texture); |
|
1222 |
+ ld->has_texture=0; |
|
1223 |
+ } |
|
1224 |
+ } |
|
1150 | 1225 |
free(listing->elems),listing->elems=NULL,listing->sizeelems=listing->usedelems=0; |
1226 |
+ } |
|
1151 | 1227 |
if(listing->buf!=NULL) |
1152 | 1228 |
free(listing->buf),listing->buf=NULL,listing->sizebuf=listing->usedbuf=0; |
1153 | 1229 |
return; |
1154 | 1230 |
} |
1155 | 1231 |
|
1232 |
+int |
|
1233 |
+is_imagefilename(char *filename) |
|
1234 |
+{ |
|
1235 |
+ char *ptr; |
|
1236 |
+ int i; |
|
1237 |
+ char *knownext[]={".jpg",".jpeg",".JPG",".JPEG",".Jpg",".Jpeg" |
|
1238 |
+ ,".png",".PNG",".Png" |
|
1239 |
+ ,".tga",".TGA",".Tga" |
|
1240 |
+ ,".bmp",".BMP",".Bmp" |
|
1241 |
+ ,".psd",".PSD",".Psd" |
|
1242 |
+ ,".gif",".GIF",".Gif" |
|
1243 |
+ ,".hdr",".HDR",".Hdr" |
|
1244 |
+ ,".pic",".PIC",".Pic" |
|
1245 |
+ ,".pnm",".PNM",".Pnm" |
|
1246 |
+ }; |
|
1247 |
+ if(filename==NULL) |
|
1248 |
+ return(0); /* sanity check failed */ |
|
1249 |
+ if((ptr=strrchr(filename,'.'))==NULL) |
|
1250 |
+ return(0); /* no extension found */ |
|
1251 |
+ for(i=0;i<(sizeof(knownext)/sizeof(knownext[0]));i++) { |
|
1252 |
+ if(strcmp(ptr,knownext[i])==0) |
|
1253 |
+ return(1); /* it has a known ext */ |
|
1254 |
+ } |
|
1255 |
+ return(0); /* not in the knownext list */ |
|
1256 |
+} |
|
1257 |
+ |
... | ... |
@@ -13,6 +13,8 @@ |
13 | 13 |
* 20250224 Draw right dir list and store elem positions. |
14 | 14 |
* 20250225 Draw image placeholders |
15 | 15 |
* 20250226 Fix rightside positions |
16 |
+ * 20250228 Navigate directories |
|
17 |
+ * 20250301 Aestetic fixes for leftside. |
|
16 | 18 |
* |
17 | 19 |
* Author: Dario Rodriguez dario@darionomono.com |
18 | 20 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -38,7 +40,7 @@ |
38 | 40 |
#define LEFTSIZE 720 |
39 | 41 |
#define DEFAULTDIRDATAHEIGHT 150 |
40 | 42 |
#define DEFAULTDIRDATATRIANGLEW 35 |
41 |
-#define LEFTIMAGESIDELEN 130 |
|
43 |
+#define LEFTIMAGESIDELEN 125 |
|
42 | 44 |
|
43 | 45 |
#define FONTSIZE 18 |
44 | 46 |
#define FONTBIGSIZE 32 |
... | ... |
@@ -282,7 +284,7 @@ im_init(char *menus, char *rootdir) |
282 | 284 |
return(NULL); /* insuf. mem. */ |
283 | 285 |
} |
284 | 286 |
/* add the starting directory */ |
285 |
- im_body_add(im->body,"/"); |
|
287 |
+ im_body_add(im->body,""); |
|
286 | 288 |
return(im); |
287 | 289 |
} |
288 | 290 |
|
... | ... |
@@ -667,11 +669,15 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
667 | 669 |
if(is_imutil_insidexywh(mousepos,&(body->backxywh))) { |
668 | 670 |
static char sep[]={SEP}; |
669 | 671 |
if((ptr=strrchr(dirdata->dirname,sep[0]))!=NULL) { |
672 |
+ /* previous dir */ |
|
670 | 673 |
*ptr='\0'; |
671 |
- listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
|
672 |
- *click_avail=0; |
|
673 |
- return(0); |
|
674 |
+ } else { |
|
675 |
+ /* root dir */ |
|
676 |
+ dirdata->dirname[0]='\0'; |
|
674 | 677 |
} |
678 |
+ listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
|
679 |
+ *click_avail=0; |
|
680 |
+ return(0); |
|
675 | 681 |
} |
676 | 682 |
/* leftside directories */ |
677 | 683 |
for(i=0;i<dirdata->listing.usedelems;i++) { |
... | ... |
@@ -683,13 +689,17 @@ im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, i |
683 | 689 |
int l,l0,l1; |
684 | 690 |
static char sep[]={SEP}; |
685 | 691 |
oldprefix=(strcmp(dirdata->dirname,SEP)==0)?"":dirdata->dirname; |
686 |
- l=(l0=strlen(oldprefix))+1+(l1=strlen(ld->name+1))+1; |
|
692 |
+ l0=strlen(oldprefix); |
|
693 |
+ l1=strlen(ld->name+1); |
|
694 |
+ l=l0+((l0>0)?1:0)+l1+1; |
|
687 | 695 |
if((newname=malloc(l))==NULL) |
688 | 696 |
return(-1); /* insuf. mem. */ |
689 |
- memcpy(newname,oldprefix,l0); |
|
690 |
- newname[l0]=sep[0]; |
|
691 |
- memcpy(newname+l0+1,ld->name+1,l1); |
|
692 |
- newname[l0+1+l1]='\0'; |
|
697 |
+ if(l0>0) { |
|
698 |
+ memcpy(newname,oldprefix,l0); |
|
699 |
+ newname[l0]=sep[0]; |
|
700 |
+ } |
|
701 |
+ memcpy(newname+l0+((l0>0)?1:0),ld->name+1,l1); |
|
702 |
+ newname[l0+((l0>0)?1:0)+l1]='\0'; |
|
693 | 703 |
free(dirdata->dirname),dirdata->dirname=NULL; |
694 | 704 |
dirdata->dirname=newname; |
695 | 705 |
listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
... | ... |
@@ -734,9 +744,9 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
734 | 744 |
sidelen=(is_leftside)?LEFTIMAGESIDELEN:dirdata->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
735 | 745 |
/* draw left side back arrow if is_leftside and not in root dir */ |
736 | 746 |
if(is_leftside && !(dirdata->dirname[0]=='\0' || strcmp(dirdata->dirname,SEP)==0)) { |
737 |
- v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
738 |
- v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
739 | 747 |
m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
748 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
749 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4+(fontbig->height-v2.x)/2); |
|
740 | 750 |
FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
741 | 751 |
#if 0 |
742 | 752 |
DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
... | ... |
@@ -773,7 +783,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
773 | 783 |
/* directories */ |
774 | 784 |
if(is_leftside) { |
775 | 785 |
x0=body->xywh.x+font->height/2; |
776 |
- x1=body->xywh.x+body->leftsize-font->height/2; |
|
786 |
+ x1=body->xywh.x+body->leftsize-DEFAULTDIRDATATRIANGLEW-font->height/2; |
|
777 | 787 |
y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
778 | 788 |
y1=body->xywh.y+body->xywh.h-DEFAULTDIRDATATRIANGLEW-font->height/2; |
779 | 789 |
} else { |
... | ... |
@@ -654,6 +654,49 @@ im_body_add(body_t *body,char *dir) |
654 | 654 |
int |
655 | 655 |
im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
656 | 656 |
{ |
657 |
+ int i; |
|
658 |
+ char *ptr; |
|
659 |
+ dirdata_t *dirdata; |
|
660 |
+ listingdata_t *ld; |
|
661 |
+ if(body==NULL || click_avail==NULL || body->currentdirdata<0 || body->currentdirdata>=body->sizedirdata || body->dirdata[body->currentdirdata]==NULL) |
|
662 |
+ return(-1); /* sanity check error */ |
|
663 |
+ if(*click_avail==0 || lmbreleased==0) |
|
664 |
+ return(0); /* nothing to do */ |
|
665 |
+ dirdata=body->dirdata[body->currentdirdata]; |
|
666 |
+ /* leftside backbutton */ |
|
667 |
+ if(is_imutil_insidexywh(mousepos,&(body->backxywh))) { |
|
668 |
+ static char sep[]={SEP}; |
|
669 |
+ if((ptr=strrchr(dirdata->dirname,sep[0]))!=NULL) { |
|
670 |
+ *ptr='\0'; |
|
671 |
+ listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
|
672 |
+ *click_avail=0; |
|
673 |
+ return(0); |
|
674 |
+ } |
|
675 |
+ } |
|
676 |
+ /* leftside directories */ |
|
677 |
+ for(i=0;i<dirdata->listing.usedelems;i++) { |
|
678 |
+ ld=dirdata->listing.elems+i; |
|
679 |
+ if(ld->name[0]!='d') |
|
680 |
+ continue; |
|
681 |
+ if(is_imutil_insidexywh(mousepos,&(ld->leftxywh))) { |
|
682 |
+ char *newname,*oldprefix; |
|
683 |
+ int l,l0,l1; |
|
684 |
+ static char sep[]={SEP}; |
|
685 |
+ oldprefix=(strcmp(dirdata->dirname,SEP)==0)?"":dirdata->dirname; |
|
686 |
+ l=(l0=strlen(oldprefix))+1+(l1=strlen(ld->name+1))+1; |
|
687 |
+ if((newname=malloc(l))==NULL) |
|
688 |
+ return(-1); /* insuf. mem. */ |
|
689 |
+ memcpy(newname,oldprefix,l0); |
|
690 |
+ newname[l0]=sep[0]; |
|
691 |
+ memcpy(newname+l0+1,ld->name+1,l1); |
|
692 |
+ newname[l0+1+l1]='\0'; |
|
693 |
+ free(dirdata->dirname),dirdata->dirname=NULL; |
|
694 |
+ dirdata->dirname=newname; |
|
695 |
+ listing_get(&(dirdata->listing),body->rootdir,dirdata->dirname,1); |
|
696 |
+ *click_avail=0; |
|
697 |
+ return(0); |
|
698 |
+ } |
|
699 |
+ } |
|
657 | 700 |
#warning TODO |
658 | 701 |
return(0); |
659 | 702 |
} |
... | ... |
@@ -689,8 +732,8 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
689 | 732 |
continue; /* this element is not in leftside */ |
690 | 733 |
margin=font->height/4; |
691 | 734 |
sidelen=(is_leftside)?LEFTIMAGESIDELEN:dirdata->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
692 |
- if(is_leftside) { |
|
693 |
- /* draw left side back arrow */ |
|
735 |
+ /* draw left side back arrow if is_leftside and not in root dir */ |
|
736 |
+ if(is_leftside && !(dirdata->dirname[0]=='\0' || strcmp(dirdata->dirname,SEP)==0)) { |
|
694 | 737 |
v2.x=(float) (body->xywh.x+fontbig->height/2); |
695 | 738 |
v2.y=(float) (body->xywh.y+fontbig->height/4); |
696 | 739 |
m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
... | ... |
@@ -12,6 +12,7 @@ |
12 | 12 |
* 20250223 Draw pane titles and main dir list. |
13 | 13 |
* 20250224 Draw right dir list and store elem positions. |
14 | 14 |
* 20250225 Draw image placeholders |
15 |
+ * 20250226 Fix rightside positions |
|
15 | 16 |
* |
16 | 17 |
* Author: Dario Rodriguez dario@darionomono.com |
17 | 18 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -37,7 +38,7 @@ |
37 | 38 |
#define LEFTSIZE 720 |
38 | 39 |
#define DEFAULTDIRDATAHEIGHT 150 |
39 | 40 |
#define DEFAULTDIRDATATRIANGLEW 35 |
40 |
-#define LEFTIMAGESIDELEN 150 |
|
41 |
+#define LEFTIMAGESIDELEN 130 |
|
41 | 42 |
|
42 | 43 |
#define FONTSIZE 18 |
43 | 44 |
#define FONTBIGSIZE 32 |
... | ... |
@@ -686,6 +687,8 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
686 | 687 |
int sidelen; |
687 | 688 |
if(is_leftside && !(i==body->currentdirdata)) |
688 | 689 |
continue; /* this element is not in leftside */ |
690 |
+ margin=font->height/4; |
|
691 |
+ sidelen=(is_leftside)?LEFTIMAGESIDELEN:dirdata->height-(fontbig->height+fontbig->height/4+font->height+margin*4+fontbig->height/4); |
|
689 | 692 |
if(is_leftside) { |
690 | 693 |
/* draw left side back arrow */ |
691 | 694 |
v2.x=(float) (body->xywh.x+fontbig->height/2); |
... | ... |
@@ -721,7 +724,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
721 | 724 |
,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
722 | 725 |
,fontbig->height |
723 | 726 |
,0 |
724 |
- ,(Color){ 65, 65, 65, 255 } |
|
727 |
+ ,(Color){ 240, 240, 240, 255 } |
|
725 | 728 |
); |
726 | 729 |
} |
727 | 730 |
/* directories */ |
... | ... |
@@ -733,11 +736,11 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
733 | 736 |
} else { |
734 | 737 |
x0=body->xywh.x+body->leftsize+fontbig->height/2; |
735 | 738 |
x1=body->xywh.x+body->xywh.w-font->height/2; |
736 |
- y0=righty+fontbig->height/4+fontbig->height+font->height/4; |
|
739 |
+ y0=righty+fontbig->height/4+fontbig->height+margin; |
|
737 | 740 |
y1=y0+margin*2+font->height-1; |
738 | 741 |
} |
739 |
- margin=font->height/4; |
|
740 | 742 |
for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
743 |
+ Color c=(is_leftside)?((Color){ 65, 65, 65, 255 }):((Color){ 240, 240, 240, 255 }); |
|
741 | 744 |
elem=dirdata->listing.elems+k; |
742 | 745 |
if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) |
743 | 746 |
continue; |
... | ... |
@@ -751,7 +754,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
751 | 754 |
,(Vector2) {x+margin,y+(fontbig->height-fonthuge->height)} |
752 | 755 |
,fonthuge->height |
753 | 756 |
,0 |
754 |
- ,(Color){ 65, 65, 65, 255 } |
|
757 |
+ ,c |
|
755 | 758 |
); |
756 | 759 |
} |
757 | 760 |
x=x0,y+=font->height+margin*2+font->height/4; |
... | ... |
@@ -760,12 +763,12 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
760 | 763 |
} |
761 | 764 |
if(is_leftside) { |
762 | 765 |
FILLXYWH(elem->leftxywh,x,y,margin*2+m2.x,margin*2+font->height); |
763 |
- DrawRectangleLines(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,255})); |
|
766 |
+ DrawRectangleLines(UNROLLXYWH(elem->leftxywh),c); |
|
764 | 767 |
} else { |
765 | 768 |
FILLXYWH(elem->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
766 |
- DrawRectangleLines(UNROLLXYWH(elem->xywh),((Color){0,0,0,255})); |
|
769 |
+ DrawRectangleLines(UNROLLXYWH(elem->xywh),c); |
|
767 | 770 |
} |
768 |
- DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,(Color){ 65, 65, 65, 255 }); |
|
771 |
+ DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,c); |
|
769 | 772 |
x+=margin*2+m2.x+font->height/4; |
770 | 773 |
} |
771 | 774 |
/* files */ |
... | ... |
@@ -773,9 +776,9 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
773 | 776 |
y0=(x==x0)?y:y+font->height+margin*2+font->height/4; |
774 | 777 |
sidelen=LEFTIMAGESIDELEN; |
775 | 778 |
} else { |
776 |
- y0=righty; //y0+margin*2+font->height+font->height/2; |
|
777 |
- y1=righty+dirdata->height-fontbig->height/4; |
|
778 |
- sidelen=y1-y0-1; |
|
779 |
+ y0=righty+dirdata->height-sidelen-margin-fontbig->height/4; |
|
780 |
+ y1=y0+sidelen+margin; |
|
781 |
+ x0-=margin; |
|
779 | 782 |
} |
780 | 783 |
for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
781 | 784 |
elem=dirdata->listing.elems+k; |
... | ... |
@@ -790,7 +793,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
790 | 793 |
,(Vector2) {x+margin,y+(sidelen-fonthuge->height)} |
791 | 794 |
,fonthuge->height |
792 | 795 |
,0 |
793 |
- ,(Color){ 65, 65, 65, 255 } |
|
796 |
+ ,(Color){ 0,0,0,64 } |
|
794 | 797 |
); |
795 | 798 |
} |
796 | 799 |
x=x0,y+=sidelen+margin*2; |
... | ... |
@@ -809,10 +812,11 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
809 | 812 |
char shortname[1024]; |
810 | 813 |
xywh_t *pos; |
811 | 814 |
int l; |
815 |
+ font_t *myfont=(is_leftside)?fonthuge:font; |
|
812 | 816 |
pos=is_leftside?&(elem->leftxywh):&(elem->xywh); |
813 | 817 |
if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
814 |
- m2=MeasureTextEx(fonthuge->font,ptr,fonthuge->height,0); |
|
815 |
- DrawTextEx(fonthuge->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+margin+(sidelen-fonthuge->height)/2},fonthuge->height,0,(Color){ 65, 65, 65, 255 }); |
|
818 |
+ m2=MeasureTextEx(myfont->font,ptr,myfont->height,0); |
|
819 |
+ DrawTextEx(myfont->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+(font->height)/2+margin+(sidelen-myfont->height)/2},myfont->height,0,(Color){ 0,0,0,96 }); |
|
816 | 820 |
} |
817 | 821 |
ptr=(ptr==NULL)?elem->name+1:ptr; |
818 | 822 |
l=(ptr-(elem->name+1)); |
... | ... |
@@ -820,7 +824,7 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
820 | 824 |
memcpy(shortname,elem->name+1,l); |
821 | 825 |
shortname[l]='\0'; |
822 | 826 |
DrawRectangle(pos->x,pos->y,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
823 |
- DrawTextEx(font->font,shortname,(Vector2){pos->x+font->height/4,pos->y+font->height/4},font->height,0,(Color){ 255, 255, 255, 255 }); |
|
827 |
+ DrawTextEx(font->font,shortname,(Vector2){pos->x+font->height/4,pos->y+font->height/4},font->height,0,(Color){ 192,192,192,255 }); |
|
824 | 828 |
} |
825 | 829 |
x+=margin*2+sidelen; |
826 | 830 |
} |
... | ... |
@@ -834,67 +838,6 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
834 | 838 |
} |
835 | 839 |
} |
836 | 840 |
} |
837 |
-#if 0 |
|
838 |
- /* example from menubar */ |
|
839 |
- int i,j,k,x; |
|
840 |
- menudata_t *menudata; |
|
841 |
- font_t *font; |
|
842 |
- if(menubar==NULL || font==NULL) |
|
843 |
- return(-1); /* sanity check failed */ |
|
844 |
- font=menubar->ptrfont; |
|
845 |
- DrawRectangle(0,0,windowwidth, font->height+font->height/2, (Color){ 235, 235, 235, 235 } ); |
|
846 |
- for(i=0,x=0;i<menubar->sizemenudata;i++) { |
|
847 |
- Vector2 v2; |
|
848 |
- menudata=menubar->menudata[i]; |
|
849 |
- v2=MeasureTextEx(font->font,menudata->title,font->height,0); |
|
850 |
- FILLXYWH(menudata->xywh,x,0,((int)v2.x)+font->height,font->height+font->height/2); |
|
851 |
- v2.x=(float) (menudata->xywh.x+font->height/2); |
|
852 |
- v2.y=(float) (menudata->xywh.y+font->height/4); |
|
853 |
- DrawTextEx(font->font |
|
854 |
- ,menudata->title |
|
855 |
- ,v2 |
|
856 |
- ,font->height |
|
857 |
- ,0 |
|
858 |
- ,(Color){ 45, 45, 45, 255 } |
|
859 |
- ); |
|
860 |
- if(menudata->flag_open || menudata->flag_stickyopen) { |
|
861 |
- int underline_height=3; |
|
862 |
- int maxw; |
|
863 |
- DrawRectangle(menudata->xywh.x,menudata->xywh.y+menudata->xywh.h-underline_height,menudata->xywh.w,underline_height, (Color){ 53,132,228,255 } ); |
|
864 |
- for(j=0,maxw=0;j<menudata->sizeoptions;j++) { |
|
865 |
- v2=MeasureTextEx(font->font,menudata->options[j],font->height,0); |
|
866 |
- maxw=(((int)(v2.x))>maxw)?((int)(v2.x)):maxw; |
|
867 |
- } |
|
868 |
- maxw=(maxw<(menudata->xywh.w+font->height))?(menudata->xywh.w+font->height):maxw; |
|
869 |
- maxw+=font->height; |
|
870 |
- FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(font->height+font->height/2)*menudata->sizeoptions); |
|
871 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y-2,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y-2,(Color){ 255,255,255,255 } ); |
|
872 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y,menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 255,255,255,255 } ); |
|
873 |
- DrawLine(menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
874 |
- DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
875 |
- DrawRectangle(menudata->optionsxywh.x,menudata->optionsxywh.y,menudata->optionsxywh.w,menudata->optionsxywh.h,(Color){ 235, 235, 235, 235 }); |
|
876 |
- for(k=0;k<menudata->sizeoptions;k++) { |
|
877 |
- Color c; |
|
878 |
- c=(k==menudata->currentoption)?((Color){ 255,255,255,255 }):((Color){ 45, 45, 45, 255 }); |
|
879 |
- if(k==menudata->currentoption) |
|
880 |
- DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(font->height+(font->height/2))*k,menudata->optionsxywh.w-2,font->height+font->height/2,(Color){ 53,132,228,255 }); |
|
881 |
- v2.x=(float) (menudata->optionsxywh.x+font->height/2); |
|
882 |
- v2.y=(float) (menudata->optionsxywh.y+(font->height/4)+(font->height+(font->height/2))*k); |
|
883 |
- DrawTextEx(font->font |
|
884 |
- ,menudata->options[k] |
|
885 |
- ,v2 |
|
886 |
- ,font->height |
|
887 |
- ,0 |
|
888 |
- ,c |
|
889 |
- ); |
|
890 |
- } |
|
891 |
- } else { |
|
892 |
- FILLXYWH(menudata->optionsxywh,0,0,0,0); |
|
893 |
- } |
|
894 |
- x=menudata->xywh.x+menudata->xywh.w; |
|
895 |
- } |
|
896 |
- return(0); |
|
897 |
-#endif |
|
898 | 841 |
return(0); |
899 | 842 |
} |
900 | 843 |
|
... | ... |
@@ -10,6 +10,8 @@ |
10 | 10 |
* 20250216 Modularize menu handling. |
11 | 11 |
* 20250222 Able to list files. |
12 | 12 |
* 20250223 Draw pane titles and main dir list. |
13 |
+ * 20250224 Draw right dir list and store elem positions. |
|
14 |
+ * 20250225 Draw image placeholders |
|
13 | 15 |
* |
14 | 16 |
* Author: Dario Rodriguez dario@darionomono.com |
15 | 17 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -35,6 +37,7 @@ |
35 | 37 |
#define LEFTSIZE 720 |
36 | 38 |
#define DEFAULTDIRDATAHEIGHT 150 |
37 | 39 |
#define DEFAULTDIRDATATRIANGLEW 35 |
40 |
+#define LEFTIMAGESIDELEN 150 |
|
38 | 41 |
|
39 | 42 |
#define FONTSIZE 18 |
40 | 43 |
#define FONTBIGSIZE 32 |
... | ... |
@@ -680,6 +683,7 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
680 | 683 |
/* two passes for each dirdata, first leftside, then rightside */ |
681 | 684 |
for(is_leftside=1;is_leftside>=0;is_leftside--) { |
682 | 685 |
int x0,y0,x1,y1; |
686 |
+ int sidelen; |
|
683 | 687 |
if(is_leftside && !(i==body->currentdirdata)) |
684 | 688 |
continue; /* this element is not in leftside */ |
685 | 689 |
if(is_leftside) { |
... | ... |
@@ -727,9 +731,9 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
727 | 731 |
y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
728 | 732 |
y1=body->xywh.y+body->xywh.h-DEFAULTDIRDATATRIANGLEW-font->height/2; |
729 | 733 |
} else { |
730 |
- x0=body->xywh.x+body->leftsize+font->height/2; |
|
734 |
+ x0=body->xywh.x+body->leftsize+fontbig->height/2; |
|
731 | 735 |
x1=body->xywh.x+body->xywh.w-font->height/2; |
732 |
- y0=righty+fontbig->height/2+m2.y+font->height/4; |
|
736 |
+ y0=righty+fontbig->height/4+fontbig->height+font->height/4; |
|
733 | 737 |
y1=y0+margin*2+font->height-1; |
734 | 738 |
} |
735 | 739 |
margin=font->height/4; |
... | ... |
@@ -741,17 +745,85 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
741 | 745 |
continue; |
742 | 746 |
m2=MeasureTextEx(font->font,elem->name+1,font->height,0); |
743 | 747 |
if((x+margin*2+m2.x)>x1) { |
748 |
+ if(!is_leftside) { |
|
749 |
+ DrawTextEx(fonthuge->font |
|
750 |
+ ,"..." |
|
751 |
+ ,(Vector2) {x+margin,y+(fontbig->height-fonthuge->height)} |
|
752 |
+ ,fonthuge->height |
|
753 |
+ ,0 |
|
754 |
+ ,(Color){ 65, 65, 65, 255 } |
|
755 |
+ ); |
|
756 |
+ } |
|
744 | 757 |
x=x0,y+=font->height+margin*2+font->height/4; |
745 | 758 |
if(y>y1) |
746 | 759 |
continue; |
747 | 760 |
} |
748 |
- FILLXYWH(elem->leftxywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
749 |
- DrawRectangleLines(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,255})); |
|
761 |
+ if(is_leftside) { |
|
762 |
+ FILLXYWH(elem->leftxywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
763 |
+ DrawRectangleLines(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,255})); |
|
764 |
+ } else { |
|
765 |
+ FILLXYWH(elem->xywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
766 |
+ DrawRectangleLines(UNROLLXYWH(elem->xywh),((Color){0,0,0,255})); |
|
767 |
+ } |
|
750 | 768 |
DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,(Color){ 65, 65, 65, 255 }); |
751 | 769 |
x+=margin*2+m2.x+font->height/4; |
752 | 770 |
} |
753 |
- |
|
754 |
-#warning TODO SHOW FILES |
|
771 |
+ /* files */ |
|
772 |
+ if(is_leftside) { |
|
773 |
+ y0=(x==x0)?y:y+font->height+margin*2+font->height/4; |
|
774 |
+ sidelen=LEFTIMAGESIDELEN; |
|
775 |
+ } else { |
|
776 |
+ y0=righty; //y0+margin*2+font->height+font->height/2; |
|
777 |
+ y1=righty+dirdata->height-fontbig->height/4; |
|
778 |
+ sidelen=y1-y0-1; |
|
779 |
+ } |
|
780 |
+ for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
|
781 |
+ elem=dirdata->listing.elems+k; |
|
782 |
+ if(elem->name[0]!='f' && elem->name[0]!='l') |
|
783 |
+ continue; |
|
784 |
+ if(y>y1) |
|
785 |
+ continue; |
|
786 |
+ if((x+margin*2+sidelen)>x1) { |
|
787 |
+ if(!is_leftside) { |
|
788 |
+ DrawTextEx(fonthuge->font |
|
789 |
+ ,"..." |
|
790 |
+ ,(Vector2) {x+margin,y+(sidelen-fonthuge->height)} |
|
791 |
+ ,fonthuge->height |
|
792 |
+ ,0 |
|
793 |
+ ,(Color){ 65, 65, 65, 255 } |
|
794 |
+ ); |
|
795 |
+ } |
|
796 |
+ x=x0,y+=sidelen+margin*2; |
|
797 |
+ if(y>y1) |
|
798 |
+ continue; |
|
799 |
+ } |
|
800 |
+ if(is_leftside) { |
|
801 |
+ FILLXYWH(elem->leftxywh,x+margin,y+margin,sidelen,sidelen); |
|
802 |
+ DrawRectangle(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,64})); |
|
803 |
+ } else { |
|
804 |
+ FILLXYWH(elem->xywh,x+margin,y+margin,sidelen,sidelen); |
|
805 |
+ DrawRectangle(UNROLLXYWH(elem->xywh),((Color){0,0,0,64})); |
|
806 |
+ } |
|
807 |
+ { |
|
808 |
+ char *ptr; |
|
809 |
+ char shortname[1024]; |
|
810 |
+ xywh_t *pos; |
|
811 |
+ int l; |
|
812 |
+ pos=is_leftside?&(elem->leftxywh):&(elem->xywh); |
|
813 |
+ if((ptr=strchr(elem->name+1,'.'))!=NULL) { |
|
814 |
+ m2=MeasureTextEx(fonthuge->font,ptr,fonthuge->height,0); |
|
815 |
+ DrawTextEx(fonthuge->font,ptr,(Vector2){x+margin+(sidelen-m2.x)/2,y+margin+(sidelen-fonthuge->height)/2},fonthuge->height,0,(Color){ 65, 65, 65, 255 }); |
|
816 |
+ } |
|
817 |
+ ptr=(ptr==NULL)?elem->name+1:ptr; |
|
818 |
+ l=(ptr-(elem->name+1)); |
|
819 |
+ l=(l>=sizeof(shortname))?sizeof(shortname)-1:l; |
|
820 |
+ memcpy(shortname,elem->name+1,l); |
|
821 |
+ shortname[l]='\0'; |
|
822 |
+ DrawRectangle(pos->x,pos->y,pos->w,font->height+font->height/2,((Color){0,0,0,64})); |
|
823 |
+ DrawTextEx(font->font,shortname,(Vector2){pos->x+font->height/4,pos->y+font->height/4},font->height,0,(Color){ 255, 255, 255, 255 }); |
|
824 |
+ } |
|
825 |
+ x+=margin*2+sidelen; |
|
826 |
+ } |
|
755 | 827 |
/* ...finishing touchs */ |
756 | 828 |
if(is_leftside) { |
757 | 829 |
/* draw right side "current" marker inside left side area */ |
... | ... |
@@ -94,10 +94,16 @@ typedef struct menubar_t { |
94 | 94 |
font_t *ptrfont; |
95 | 95 |
} menubar_t; |
96 | 96 |
|
97 |
+typedef struct listingdata_t { |
|
98 |
+ xywh_t leftxywh; |
|
99 |
+ xywh_t xywh; |
|
100 |
+ char *name; /* first byte in the name is the type, next is the name, i.e. a directory is "dhome" and a file is "f.bashrc" (this is done for easier sorting) */ |
|
101 |
+} listingdata_t; |
|
102 |
+ |
|
97 | 103 |
typedef struct listing_t { |
98 | 104 |
int sizeelems; |
99 | 105 |
int usedelems; |
100 |
- char **elems; /* first byte in the elem is the type, next is the name, i.e. a directory is "dhome" and a file is "f.bashrc" */ |
|
106 |
+ listingdata_t *elems; |
|
101 | 107 |
int sizebuf; |
102 | 108 |
int usedbuf; |
103 | 109 |
char *buf; |
... | ... |
@@ -229,7 +235,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
229 | 235 |
v2.x=(float) (im->font->height/2); |
230 | 236 |
v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
231 | 237 |
DrawTextEx(im->font->font |
232 |
- ,listing.elems[j] |
|
238 |
+ ,listing.elems[j].name |
|
233 | 239 |
,v2 |
234 | 240 |
,im->font->height |
235 | 241 |
,0 |
... | ... |
@@ -653,8 +659,10 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
653 | 659 |
{ |
654 | 660 |
int i,x,y,k,margin,righty; |
655 | 661 |
dirdata_t *dirdata; |
662 |
+ listingdata_t *elem; |
|
656 | 663 |
Vector2 v2,m2; |
657 | 664 |
font_t *font,*fontbig,*fonthuge; |
665 |
+ int is_leftside; |
|
658 | 666 |
if(body==NULL) |
659 | 667 |
return(-1); |
660 | 668 |
font=body->ptrfont; |
... | ... |
@@ -669,66 +677,90 @@ im_body_draw(body_t *body, int windowwidth, int windowheight) |
669 | 677 |
for(i=0,y=righty=body->xywh.y;i<body->sizedirdata;i++) { |
670 | 678 |
if((dirdata=body->dirdata[i])==NULL) |
671 | 679 |
continue; |
672 |
- /* draw left side if appropiate */ |
|
673 |
- if(i==body->currentdirdata) { |
|
680 |
+ /* two passes for each dirdata, first leftside, then rightside */ |
|
681 |
+ for(is_leftside=1;is_leftside>=0;is_leftside--) { |
|
674 | 682 |
int x0,y0,x1,y1; |
675 |
- /* draw left side */ |
|
676 |
- /* ...back arrow */ |
|
677 |
- v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
678 |
- v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
679 |
- m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
|
680 |
- FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
|
683 |
+ if(is_leftside && !(i==body->currentdirdata)) |
|
684 |
+ continue; /* this element is not in leftside */ |
|
685 |
+ if(is_leftside) { |
|
686 |
+ /* draw left side back arrow */ |
|
687 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
688 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
689 |
+ m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
|
690 |
+ FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
|
681 | 691 |
#if 0 |
682 | 692 |
DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
683 | 693 |
DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone */ |
684 | 694 |
#endif |
685 |
- DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
|
686 |
- /* ...dirname */ |
|
687 |
- m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
|
688 |
- v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
689 |
- v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
690 |
- DrawTextEx(fontbig->font |
|
691 |
- ,dirdata->dirname |
|
692 |
- ,v2 |
|
693 |
- ,fontbig->height |
|
694 |
- ,0 |
|
695 |
- ,(Color){ 65, 65, 65, 255 } |
|
696 |
- ); |
|
695 |
+ DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
|
696 |
+ } |
|
697 |
+ if(is_leftside) { |
|
698 |
+ /* ...dirname */ |
|
699 |
+ m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
|
700 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
701 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
702 |
+ DrawTextEx(fontbig->font |
|
703 |
+ ,dirdata->dirname |
|
704 |
+ ,v2 |
|
705 |
+ ,fontbig->height |
|
706 |
+ ,0 |
|
707 |
+ ,(Color){ 65, 65, 65, 255 } |
|
708 |
+ ); |
|
709 |
+ } else { /* rightside */ |
|
710 |
+ /* ...bg */ |
|
711 |
+ DrawRectangle(body->xywh.x+body->leftsize,righty,body->xywh.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
|
712 |
+ /* ...bottom separator */ |
|
713 |
+ DrawRectangle(body->xywh.x+body->leftsize,righty+dirdata->height-1,body->xywh.w-body->leftsize, 1, (Color){ 221, 221, 221, 255 } ); |
|
714 |
+ /* ...dirname */ |
|
715 |
+ DrawTextEx(fontbig->font |
|
716 |
+ ,dirdata->dirname |
|
717 |
+ ,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
|
718 |
+ ,fontbig->height |
|
719 |
+ ,0 |
|
720 |
+ ,(Color){ 65, 65, 65, 255 } |
|
721 |
+ ); |
|
722 |
+ } |
|
697 | 723 |
/* directories */ |
698 |
- x0=body->xywh.x+font->height/2; |
|
699 |
- x1=body->xywh.x+body->leftsize-font->height/2; |
|
700 |
- y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
|
701 |
- y1=body->xywh.y+body->xywh.h-font->height/2; |
|
724 |
+ if(is_leftside) { |
|
725 |
+ x0=body->xywh.x+font->height/2; |
|
726 |
+ x1=body->xywh.x+body->leftsize-font->height/2; |
|
727 |
+ y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
|
728 |
+ y1=body->xywh.y+body->xywh.h-DEFAULTDIRDATATRIANGLEW-font->height/2; |
|
729 |
+ } else { |
|
730 |
+ x0=body->xywh.x+body->leftsize+font->height/2; |
|
731 |
+ x1=body->xywh.x+body->xywh.w-font->height/2; |
|
732 |
+ y0=righty+fontbig->height/2+m2.y+font->height/4; |
|
733 |
+ y1=y0+margin*2+font->height-1; |
|
734 |
+ } |
|
702 | 735 |
margin=font->height/4; |
703 | 736 |
for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
704 |
- m2=MeasureTextEx(font->font,dirdata->listing.elems[k]+1,font->height,0); |
|
705 |
- if((x+margin*2+m2.x)>x1) |
|
737 |
+ elem=dirdata->listing.elems+k; |
|
738 |
+ if(elem->name[0]!='d' || strcmp(elem->name,"d.")==0 || strcmp(elem->name,"d..")==0) |
|
739 |
+ continue; |
|
740 |
+ if(y>y1) |
|
741 |
+ continue; |
|
742 |
+ m2=MeasureTextEx(font->font,elem->name+1,font->height,0); |
|
743 |
+ if((x+margin*2+m2.x)>x1) { |
|
706 | 744 |
x=x0,y+=font->height+margin*2+font->height/4; |
707 |
-#warning TODO: store the bounding box of the element |
|
708 |
- DrawRectangleLines(x,y,margin*2+m2.x,margin*2+font->height,((Color){0,0,0,255})); |
|
709 |
- DrawTextEx(font->font,dirdata->listing.elems[k]+1,(Vector2){x+margin,y+margin},font->height,0,(Color){ 65, 65, 65, 255 }); |
|
745 |
+ if(y>y1) |
|
746 |
+ continue; |
|
747 |
+ } |
|
748 |
+ FILLXYWH(elem->leftxywh,x,y,margin*2+m2.x,margin*2+font->height); |
|
749 |
+ DrawRectangleLines(UNROLLXYWH(elem->leftxywh),((Color){0,0,0,255})); |
|
750 |
+ DrawTextEx(font->font,elem->name+1,(Vector2){x+margin,y+margin},font->height,0,(Color){ 65, 65, 65, 255 }); |
|
710 | 751 |
x+=margin*2+m2.x+font->height/4; |
711 | 752 |
} |
712 | 753 |
|
713 |
-#warning TODO |
|
714 |
- /* draw right side "current" marker inside left side area */ |
|
715 |
- DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
754 |
+#warning TODO SHOW FILES |
|
755 |
+ /* ...finishing touchs */ |
|
756 |
+ if(is_leftside) { |
|
757 |
+ /* draw right side "current" marker inside left side area */ |
|
758 |
+ DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
759 |
+ } else { |
|
760 |
+ /* advance to next element */ |
|
761 |
+ righty+=dirdata->height; |
|
762 |
+ } |
|
716 | 763 |
} |
717 |
- /* draw right side */ |
|
718 |
- /* ...bg */ |
|
719 |
- DrawRectangle(body->xywh.x+body->leftsize,righty,body->xywh.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
|
720 |
- /* ...bottom separator */ |
|
721 |
- DrawRectangle(body->xywh.x+body->leftsize,righty+dirdata->height-1,body->xywh.w-body->leftsize, 1, (Color){ 221, 221, 221, 255 } ); |
|
722 |
- /* ...dirname */ |
|
723 |
- DrawTextEx(fontbig->font |
|
724 |
- ,dirdata->dirname |
|
725 |
- ,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
|
726 |
- ,fontbig->height |
|
727 |
- ,0 |
|
728 |
- ,(Color){ 65, 65, 65, 255 } |
|
729 |
- ); |
|
730 |
- /* advance to next element */ |
|
731 |
- righty+=dirdata->height; |
|
732 | 764 |
} |
733 | 765 |
#if 0 |
734 | 766 |
/* example from menubar */ |
... | ... |
@@ -942,7 +974,7 @@ getcodepoints(int *sizecodepoints) |
942 | 974 |
static int |
943 | 975 |
strptrcmp(void *a,void *b) |
944 | 976 |
{ |
945 |
- return(strcmp(*((char **)a),*((char **)b))); |
|
977 |
+ return(strcmp(((listingdata_t *)a)->name,((listingdata_t *)b)->name)); |
|
946 | 978 |
} |
947 | 979 |
|
948 | 980 |
int |
... | ... |
@@ -956,6 +988,7 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
956 | 988 |
if(listing==NULL) |
957 | 989 |
return(-1); /* sanity check failed */ |
958 | 990 |
listing->usedelems=listing->usedbuf=0; |
991 |
+ memset(listing->elems,0,sizeof(listingdata_t)*listing->sizeelems); |
|
959 | 992 |
if(pathprefix==NULL && parampath==NULL) |
960 | 993 |
return(-1); /* nothing to fill */ |
961 | 994 |
snprintf(path,sizeof(path),"%s%s%s",(pathprefix!=NULL)?pathprefix:"",SEP,(parampath!=NULL)?parampath:""); |
... | ... |
@@ -998,12 +1031,13 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
998 | 1031 |
} |
999 | 1032 |
/* check for space for this elem (and get space if necessary) */ |
1000 | 1033 |
if(listing->usedelems==listing->sizeelems) { |
1001 |
- char **newelems; |
|
1002 |
- if((newelems=realloc(listing->elems,sizeof(char *)*(listing->sizeelems+BLOCKLISTINGELEMS)))==NULL) { |
|
1034 |
+ listingdata_t *newelems; |
|
1035 |
+ if((newelems=realloc(listing->elems,sizeof(listingdata_t)*(listing->sizeelems+BLOCKLISTINGELEMS)))==NULL) { |
|
1003 | 1036 |
closedir(d),d=NULL; |
1004 | 1037 |
return(-1); /* insuf. mem. */ |
1005 | 1038 |
} |
1006 | 1039 |
listing->elems=newelems; |
1040 |
+ memset(listing->elems+listing->sizeelems,0,sizeof(listingdata_t)*BLOCKLISTINGELEMS); |
|
1007 | 1041 |
listing->sizeelems+=BLOCKLISTINGELEMS; |
1008 | 1042 |
} |
1009 | 1043 |
/* check for space for this elem data (and get space if necessary) */ |
... | ... |
@@ -1021,21 +1055,21 @@ listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort |
1021 | 1055 |
} |
1022 | 1056 |
/* the elem data buffer has a new pointer, fix previous entries */ |
1023 | 1057 |
for(i=0;i<listing->usedelems;i++) { |
1024 |
- off=(listing->elems[i])-listing->buf; |
|
1025 |
- listing->elems[i]=newbuf+off; |
|
1058 |
+ off=(listing->elems[i].name)-listing->buf; |
|
1059 |
+ listing->elems[i].name=newbuf+off; |
|
1026 | 1060 |
} |
1027 | 1061 |
listing->buf=newbuf; |
1028 | 1062 |
listing->sizebuf+=BLOCKLISTINGELEMS; |
1029 | 1063 |
} |
1030 | 1064 |
/* store the data */ |
1031 |
- listing->elems[listing->usedelems++]=listing->buf+listing->usedbuf; |
|
1065 |
+ listing->elems[listing->usedelems++].name=listing->buf+listing->usedbuf; |
|
1032 | 1066 |
listing->buf[listing->usedbuf++]=dtype; |
1033 | 1067 |
memcpy(listing->buf+listing->usedbuf,de->d_name,l+1); |
1034 | 1068 |
listing->usedbuf+=l+1; |
1035 | 1069 |
} |
1036 | 1070 |
closedir(d),d=NULL; |
1037 | 1071 |
if(flag_sort) |
1038 |
- qsort(listing->elems,listing->usedelems,sizeof(char *),(int (*)(const void *, const void *)) strptrcmp); |
|
1072 |
+ qsort(listing->elems,listing->usedelems,sizeof(listingdata_t ),(int (*)(const void *, const void *)) strptrcmp); |
|
1039 | 1073 |
return(0); |
1040 | 1074 |
} |
1041 | 1075 |
|
... | ... |
@@ -9,6 +9,7 @@ |
9 | 9 |
* 20250213 Support sticky drop-down menus. |
10 | 10 |
* 20250216 Modularize menu handling. |
11 | 11 |
* 20250222 Able to list files. |
12 |
+ * 20250223 Draw pane titles and main dir list. |
|
12 | 13 |
* |
13 | 14 |
* Author: Dario Rodriguez dario@darionomono.com |
14 | 15 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -29,13 +30,23 @@ |
29 | 30 |
#define DEFAULTWIDTH 1280 |
30 | 31 |
#define DEFAULTHEIGHT 768 |
31 | 32 |
|
33 |
+#define UTF8DOWNARROW "\xe2\x86\x86" /* U+2186 in UTF-8 */ |
|
34 |
+ |
|
32 | 35 |
#define LEFTSIZE 720 |
33 |
-#define RIGHTELEMHEIGHT 280 |
|
36 |
+#define DEFAULTDIRDATAHEIGHT 150 |
|
37 |
+#define DEFAULTDIRDATATRIANGLEW 35 |
|
38 |
+ |
|
39 |
+#define FONTSIZE 18 |
|
40 |
+#define FONTBIGSIZE 32 |
|
41 |
+#define FONTHUGESIZE 48 |
|
42 |
+ |
|
43 |
+#define ROOTDIR "/var/www/default/animeshot/" |
|
34 | 44 |
|
35 | 45 |
#define SEP "/" |
36 | 46 |
|
37 | 47 |
#define BLOCKLISTINGBUF 2048 |
38 | 48 |
#define BLOCKLISTINGELEMS 1024 |
49 |
+#define BLOCKDIRDATA 16 |
|
39 | 50 |
|
40 | 51 |
#ifndef FILLXY |
41 | 52 |
#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
... | ... |
@@ -65,7 +76,6 @@ typedef struct font_t { |
65 | 76 |
int height; |
66 | 77 |
} font_t; |
67 | 78 |
|
68 |
- |
|
69 | 79 |
typedef struct menudata_t { |
70 | 80 |
char *title; |
71 | 81 |
xywh_t xywh; |
... | ... |
@@ -78,8 +88,10 @@ typedef struct menudata_t { |
78 | 88 |
} menudata_t; |
79 | 89 |
|
80 | 90 |
typedef struct menubar_t { |
91 |
+ int height; |
|
81 | 92 |
int sizemenudata; |
82 | 93 |
menudata_t **menudata; |
94 |
+ font_t *ptrfont; |
|
83 | 95 |
} menubar_t; |
84 | 96 |
|
85 | 97 |
typedef struct listing_t { |
... | ... |
@@ -97,33 +109,54 @@ typedef struct dirdata_t { |
97 | 109 |
listing_t listing; |
98 | 110 |
} dirdata_t; |
99 | 111 |
|
100 |
-typedef struct im_t { |
|
101 |
- int windowinit; |
|
102 |
- int w; |
|
103 |
- int h; |
|
112 |
+typedef struct body_t { |
|
113 |
+ char *rootdir; |
|
114 |
+ xywh_t xywh; |
|
115 |
+ xywh_t backxywh; |
|
116 |
+ int leftsize; |
|
104 | 117 |
int sizedirdata; |
105 | 118 |
dirdata_t **dirdata; |
106 | 119 |
int currentdirdata; |
107 | 120 |
int leftscrollpos; |
108 | 121 |
int rightscrollpos; |
122 |
+ font_t *ptrfont; |
|
123 |
+ font_t *ptrfontbig; |
|
124 |
+ font_t *ptrfonthuge; |
|
125 |
+} body_t; |
|
126 |
+ |
|
127 |
+typedef struct im_t { |
|
128 |
+ int windowinit; |
|
129 |
+ int w; |
|
130 |
+ int h; |
|
109 | 131 |
menubar_t *menubar; |
132 |
+ body_t *body; |
|
110 | 133 |
font_t *font; |
134 |
+ font_t *fontbig; |
|
135 |
+ font_t *fonthuge; |
|
111 | 136 |
} im_t; |
112 | 137 |
|
113 | 138 |
|
114 |
-im_t *im_init(char *menus); |
|
139 |
+im_t *im_init(char *menus, char *rootdir); |
|
115 | 140 |
void im_free(im_t *im); |
116 | 141 |
|
117 |
-font_t *im_font_init(void); |
|
142 |
+font_t *im_font_init(int size); |
|
118 | 143 |
void im_font_free(font_t *font); |
119 | 144 |
|
120 |
-menubar_t *im_menubar_init(char *menus); |
|
145 |
+menubar_t *im_menubar_init(char *menus, font_t *font); |
|
121 | 146 |
void im_menubar_free(menubar_t *menubar); |
122 | 147 |
|
123 | 148 |
int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
124 |
-int im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowheight); |
|
149 |
+int im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight); |
|
125 | 150 |
|
126 |
-int listing_get(listing_t *listing, char *path, int flag_sort); |
|
151 |
+body_t *im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir); |
|
152 |
+void im_body_free(body_t *body); |
|
153 |
+ |
|
154 |
+int im_body_add(body_t *body,char *dir); |
|
155 |
+ |
|
156 |
+int im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail); |
|
157 |
+int im_body_draw(body_t *body, int windowwidth, int windowheight); |
|
158 |
+ |
|
159 |
+int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort); |
|
127 | 160 |
void listing_freedata(listing_t *listing); |
128 | 161 |
|
129 | 162 |
int imutil_menu_count(char *menus); |
... | ... |
@@ -144,7 +177,7 @@ main(int argc, char *argv[]) |
144 | 177 |
int lmbpressed,lmbreleased,lmbdown; |
145 | 178 |
int click_avail; |
146 | 179 |
char *sel_menu,*sel_submenu; |
147 |
- if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n"))==NULL) { |
|
180 |
+ if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n",ROOTDIR))==NULL) { |
|
148 | 181 |
return(1); |
149 | 182 |
} |
150 | 183 |
flag_ignorelmb=0; |
... | ... |
@@ -164,16 +197,21 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
164 | 197 |
#endif |
165 | 198 |
} |
166 | 199 |
} |
200 |
+ if(click_avail) |
|
201 |
+ im_body_mouse(im->body, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail); |
|
202 |
+ |
|
203 |
+ |
|
167 | 204 |
/* draw screen contents */ |
168 | 205 |
BeginDrawing(); |
169 | 206 |
ClearBackground(RAYWHITE); |
170 |
- im_menubar_draw(im->menubar,im->font,im->w,im->h); |
|
171 |
-#if 1 |
|
207 |
+ im_body_draw(im->body,im->w,im->h); |
|
208 |
+ im_menubar_draw(im->menubar,im->w,im->h); |
|
209 |
+#if 0 |
|
172 | 210 |
{ |
173 | 211 |
int i,j; |
174 | 212 |
Vector2 v2; |
175 | 213 |
listing_t listing={0}; |
176 |
- if(listing_get(&listing,".." SEP ".",1)==0) { |
|
214 |
+ if(listing_get(&listing,"..",".",1)==0) { |
|
177 | 215 |
i=2; |
178 | 216 |
v2.x=(float) (im->font->height/2); |
179 | 217 |
v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
... | ... |
@@ -209,14 +247,12 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
209 | 247 |
} |
210 | 248 |
|
211 | 249 |
im_t * |
212 |
-im_init(char *menus) |
|
250 |
+im_init(char *menus, char *rootdir) |
|
213 | 251 |
{ |
214 | 252 |
im_t *im; |
215 | 253 |
if(menus==NULL) |
216 | 254 |
return(NULL); /* sanity check failed */ |
217 |
- if((im=calloc(1,sizeof(im_t)))==NULL |
|
218 |
- || (im->menubar=im_menubar_init(menus))==NULL |
|
219 |
- ) { |
|
255 |
+ if((im=calloc(1,sizeof(im_t)))==NULL) { |
|
220 | 256 |
im_free(im),im=NULL; |
221 | 257 |
return(NULL); /* insuf. mem. */ |
222 | 258 |
} |
... | ... |
@@ -225,35 +261,36 @@ im_init(char *menus) |
225 | 261 |
InitWindow((im->w=DEFAULTWIDTH),(im->h=DEFAULTHEIGHT),"Image Mover"); |
226 | 262 |
im->windowinit=1; |
227 | 263 |
SetTargetFPS(30); |
228 |
- /* init font */ |
|
229 |
- if((im->font=im_font_init())==NULL) { |
|
264 |
+ /* init fonts and contents */ |
|
265 |
+ if((im->font=im_font_init(FONTSIZE))==NULL |
|
266 |
+ || (im->fontbig=im_font_init(FONTBIGSIZE))==NULL |
|
267 |
+ || (im->fonthuge=im_font_init(FONTHUGESIZE))==NULL |
|
268 |
+ || (im->menubar=im_menubar_init(menus,im->font))==NULL |
|
269 |
+ || (im->body=im_body_init(0,im->menubar->height, im->font, im->fontbig, im->fonthuge, LEFTSIZE, rootdir))==NULL |
|
270 |
+ ) { |
|
230 | 271 |
im_free(im),im=NULL; |
231 | 272 |
return(NULL); /* insuf. mem. */ |
232 | 273 |
} |
274 |
+ /* add the starting directory */ |
|
275 |
+ im_body_add(im->body,"/"); |
|
233 | 276 |
return(im); |
234 | 277 |
} |
235 | 278 |
|
236 | 279 |
void |
237 | 280 |
im_free(im_t *im) |
238 | 281 |
{ |
239 |
- int i; |
|
240 | 282 |
if(im==NULL) |
241 | 283 |
return; |
242 | 284 |
if(im->menubar!=NULL) |
243 | 285 |
im_menubar_free(im->menubar),im->menubar=NULL; |
244 |
- if(im->dirdata!=NULL) { |
|
245 |
- dirdata_t *dirdata; |
|
246 |
- for(i=0;i<im->sizedirdata;i++) { |
|
247 |
- if((dirdata=im->dirdata[i])==NULL) |
|
248 |
- continue; |
|
249 |
- if(dirdata->dirname!=NULL) |
|
250 |
- free(dirdata->dirname),dirdata->dirname=NULL; |
|
251 |
- listing_freedata(&(dirdata->listing)); |
|
252 |
- } |
|
253 |
- free(im->dirdata),im->dirdata=NULL,im->sizedirdata=0; |
|
254 |
- } |
|
286 |
+ if(im->body!=NULL) |
|
287 |
+ im_body_free(im->body),im->body=NULL; |
|
255 | 288 |
if(im->font!=NULL) |
256 | 289 |
im_font_free(im->font),im->font=NULL; |
290 |
+ if(im->fontbig!=NULL) |
|
291 |
+ im_font_free(im->fontbig),im->fontbig=NULL; |
|
292 |
+ if(im->fonthuge!=NULL) |
|
293 |
+ im_font_free(im->fonthuge),im->fonthuge=NULL; |
|
257 | 294 |
#if 0 /* not working as intended */ |
258 | 295 |
if(im->windowinit) |
259 | 296 |
CloseWindow(),im->windowinit=0; |
... | ... |
@@ -263,14 +300,14 @@ im_free(im_t *im) |
263 | 300 |
} |
264 | 301 |
|
265 | 302 |
font_t * |
266 |
-im_font_init(void) |
|
303 |
+im_font_init(int size) |
|
267 | 304 |
{ |
268 | 305 |
font_t *font; |
269 | 306 |
int sizecodepoints; |
270 | 307 |
int *codepoints; |
271 | 308 |
if((font=calloc(1,sizeof(font_t)))==NULL) |
272 | 309 |
return(NULL); /* insuf. mem. */ |
273 |
- font->height=18; |
|
310 |
+ font->height=size; |
|
274 | 311 |
codepoints=getcodepoints(&sizecodepoints); |
275 | 312 |
font->font=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,font->height,codepoints,sizecodepoints); |
276 | 313 |
return(font); |
... | ... |
@@ -281,22 +318,20 @@ im_font_free(font_t *font) |
281 | 318 |
{ |
282 | 319 |
if(font==NULL) |
283 | 320 |
return; |
284 |
-#if 0 /* not working as intended */ |
|
285 |
- UnloadFont(font->font); |
|
286 |
-#endif |
|
321 |
+ /* NOTE: Cannot call UnloadFont(font->font) as the data was not malloc'd; see https://github.com/raysan5/raylib/blob/master/examples/others/embedded_files_loading.c */ |
|
287 | 322 |
free(font),font=NULL; |
288 | 323 |
return; |
289 | 324 |
} |
290 | 325 |
|
291 | 326 |
menubar_t * |
292 |
-im_menubar_init(char *menus) |
|
327 |
+im_menubar_init(char *menus, font_t *font) |
|
293 | 328 |
{ |
294 | 329 |
int i,j; |
295 | 330 |
char *str,*substr; |
296 | 331 |
int len,sublen; |
297 | 332 |
menubar_t *menubar; |
298 | 333 |
menudata_t *menudata; |
299 |
- if(menus==NULL) |
|
334 |
+ if(menus==NULL || font==NULL) |
|
300 | 335 |
return(NULL); /* sanity check failed */ |
301 | 336 |
if((menubar=calloc(1,sizeof(menubar_t)))==NULL |
302 | 337 |
|| (menubar->sizemenudata=imutil_menu_count(menus))<=0 |
... | ... |
@@ -305,6 +340,8 @@ im_menubar_init(char *menus) |
305 | 340 |
im_menubar_free(menubar),menubar=NULL; |
306 | 341 |
return(NULL); /* insuf. mem. */ |
307 | 342 |
} |
343 |
+ menubar->ptrfont=font; |
|
344 |
+ menubar->height=font->height+font->height/2; |
|
308 | 345 |
/* init menus */ |
309 | 346 |
for(i=0;i<menubar->sizemenudata;i++) { |
310 | 347 |
if((menudata=menubar->menudata[i]=calloc(1,sizeof(menudata_t)))==NULL |
... | ... |
@@ -465,12 +502,242 @@ im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbre |
465 | 502 |
} |
466 | 503 |
|
467 | 504 |
int |
468 |
-im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowheight) |
|
505 |
+im_menubar_draw(menubar_t *menubar, int windowwidth, int windowheight) |
|
469 | 506 |
{ |
470 | 507 |
int i,j,k,x; |
471 | 508 |
menudata_t *menudata; |
509 |
+ font_t *font; |
|
510 |
+ if(menubar==NULL) |
|
511 |
+ return(-1); /* sanity check failed */ |
|
512 |
+ font=menubar->ptrfont; |
|
513 |
+ DrawRectangle(0,0,windowwidth, font->height+font->height/2, (Color){ 235, 235, 235, 235 } ); |
|
514 |
+ for(i=0,x=0;i<menubar->sizemenudata;i++) { |
|
515 |
+ Vector2 v2; |
|
516 |
+ menudata=menubar->menudata[i]; |
|
517 |
+ v2=MeasureTextEx(font->font,menudata->title,font->height,0); |
|
518 |
+ FILLXYWH(menudata->xywh,x,0,((int)v2.x)+font->height,font->height+font->height/2); |
|
519 |
+ v2.x=(float) (menudata->xywh.x+font->height/2); |
|
520 |
+ v2.y=(float) (menudata->xywh.y+font->height/4); |
|
521 |
+ DrawTextEx(font->font |
|
522 |
+ ,menudata->title |
|
523 |
+ ,v2 |
|
524 |
+ ,font->height |
|
525 |
+ ,0 |
|
526 |
+ ,(Color){ 45, 45, 45, 255 } |
|
527 |
+ ); |
|
528 |
+ if(menudata->flag_open || menudata->flag_stickyopen) { |
|
529 |
+ int underline_height=3; |
|
530 |
+ int maxw; |
|
531 |
+ DrawRectangle(menudata->xywh.x,menudata->xywh.y+menudata->xywh.h-underline_height,menudata->xywh.w,underline_height, (Color){ 53,132,228,255 } ); |
|
532 |
+ for(j=0,maxw=0;j<menudata->sizeoptions;j++) { |
|
533 |
+ v2=MeasureTextEx(font->font,menudata->options[j],font->height,0); |
|
534 |
+ maxw=(((int)(v2.x))>maxw)?((int)(v2.x)):maxw; |
|
535 |
+ } |
|
536 |
+ maxw=(maxw<(menudata->xywh.w+font->height))?(menudata->xywh.w+font->height):maxw; |
|
537 |
+ maxw+=font->height; |
|
538 |
+ FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(font->height+font->height/2)*menudata->sizeoptions); |
|
539 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y-2,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y-2,(Color){ 255,255,255,255 } ); |
|
540 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y,menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 255,255,255,255 } ); |
|
541 |
+ DrawLine(menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
542 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
543 |
+ DrawRectangle(menudata->optionsxywh.x,menudata->optionsxywh.y,menudata->optionsxywh.w,menudata->optionsxywh.h,(Color){ 235, 235, 235, 235 }); |
|
544 |
+ for(k=0;k<menudata->sizeoptions;k++) { |
|
545 |
+ Color c; |
|
546 |
+ c=(k==menudata->currentoption)?((Color){ 255,255,255,255 }):((Color){ 45, 45, 45, 255 }); |
|
547 |
+ if(k==menudata->currentoption) |
|
548 |
+ DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(font->height+(font->height/2))*k,menudata->optionsxywh.w-2,font->height+font->height/2,(Color){ 53,132,228,255 }); |
|
549 |
+ v2.x=(float) (menudata->optionsxywh.x+font->height/2); |
|
550 |
+ v2.y=(float) (menudata->optionsxywh.y+(font->height/4)+(font->height+(font->height/2))*k); |
|
551 |
+ DrawTextEx(font->font |
|
552 |
+ ,menudata->options[k] |
|
553 |
+ ,v2 |
|
554 |
+ ,font->height |
|
555 |
+ ,0 |
|
556 |
+ ,c |
|
557 |
+ ); |
|
558 |
+ } |
|
559 |
+ } else { |
|
560 |
+ FILLXYWH(menudata->optionsxywh,0,0,0,0); |
|
561 |
+ } |
|
562 |
+ x=menudata->xywh.x+menudata->xywh.w; |
|
563 |
+ } |
|
564 |
+ return(0); |
|
565 |
+} |
|
566 |
+ |
|
567 |
+body_t * |
|
568 |
+im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int leftsize, char *rootdir) |
|
569 |
+{ |
|
570 |
+ body_t *body; |
|
571 |
+ if(font==NULL || fontbig==NULL || fonthuge==NULL || rootdir==NULL) |
|
572 |
+ return(NULL); /* sanity check failed */ |
|
573 |
+ if((body=calloc(1,sizeof(body_t)))==NULL |
|
574 |
+ || (body->rootdir=strdup(rootdir))==NULL |
|
575 |
+ ) { |
|
576 |
+ im_body_free(body),body=NULL; |
|
577 |
+ return(NULL); |
|
578 |
+ } |
|
579 |
+ FILLXY(body->xywh,x,y); |
|
580 |
+ body->leftsize=leftsize; |
|
581 |
+ body->ptrfont=font; |
|
582 |
+ body->ptrfontbig=fontbig; |
|
583 |
+ body->ptrfonthuge=fonthuge; |
|
584 |
+ return(body); |
|
585 |
+} |
|
586 |
+ |
|
587 |
+void |
|
588 |
+im_body_free(body_t *body) |
|
589 |
+{ |
|
590 |
+ int i; |
|
591 |
+ dirdata_t *dirdata; |
|
592 |
+ if(body==NULL) |
|
593 |
+ return; /* nothing to do */ |
|
594 |
+ if(body->rootdir!=NULL) |
|
595 |
+ free(body->rootdir),body->rootdir=NULL; |
|
596 |
+ if(body->dirdata!=NULL) { |
|
597 |
+ for(i=0;i<body->sizedirdata;i++) { |
|
598 |
+ if((dirdata=body->dirdata[i])==NULL) |
|
599 |
+ continue; |
|
600 |
+ if(dirdata->dirname!=NULL) |
|
601 |
+ free(dirdata->dirname),dirdata->dirname=NULL; |
|
602 |
+ listing_freedata(&(dirdata->listing)); |
|
603 |
+ free(dirdata),dirdata=body->dirdata[i]=NULL; |
|
604 |
+ } |
|
605 |
+ free(body->dirdata),body->dirdata=NULL,body->sizedirdata=0; |
|
606 |
+ } |
|
607 |
+ free(body),body=NULL; |
|
608 |
+ return; |
|
609 |
+} |
|
610 |
+ |
|
611 |
+int |
|
612 |
+im_body_add(body_t *body,char *dir) |
|
613 |
+{ |
|
614 |
+ int i; |
|
615 |
+ dirdata_t *dirdata; |
|
616 |
+ if(body==NULL || dir==NULL) |
|
617 |
+ return(-1); /* sanity check failed */ |
|
618 |
+ for(i=0;i<body->sizedirdata;i++) { |
|
619 |
+ if(body->dirdata[i]==NULL) |
|
620 |
+ break; |
|
621 |
+ } |
|
622 |
+ if(i==body->sizedirdata) { |
|
623 |
+ /* dirdata container full, add more slots */ |
|
624 |
+ dirdata_t **newdirdata; |
|
625 |
+ if((newdirdata=realloc(body->dirdata,sizeof(dirdata_t *)*(body->sizedirdata+BLOCKDIRDATA)))==NULL) |
|
626 |
+ return(-1); /* insuf. mem. */ |
|
627 |
+ body->dirdata=newdirdata; |
|
628 |
+ memset(body->dirdata+body->sizedirdata,0,sizeof(dirdata_t *)*BLOCKDIRDATA); |
|
629 |
+ body->sizedirdata+=BLOCKDIRDATA; |
|
630 |
+ } |
|
631 |
+ if((dirdata=body->dirdata[i]=calloc(1,sizeof(dirdata_t)))==NULL |
|
632 |
+ || (dirdata->dirname=strdup(dir))==NULL |
|
633 |
+ ) { |
|
634 |
+ if(dirdata!=NULL) |
|
635 |
+ free(dirdata),dirdata=body->dirdata[i]=NULL; |
|
636 |
+ return(-1); /* insuf. mem. */ |
|
637 |
+ } |
|
638 |
+ dirdata->height=DEFAULTDIRDATAHEIGHT; |
|
639 |
+ dirdata->dirname=strdup(dir); |
|
640 |
+ listing_get(&(dirdata->listing),body->rootdir,dir,1); |
|
641 |
+ return(0); |
|
642 |
+} |
|
643 |
+ |
|
644 |
+int |
|
645 |
+im_body_mouse(body_t *body, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail) |
|
646 |
+{ |
|
647 |
+#warning TODO |
|
648 |
+ return(0); |
|
649 |
+} |
|
650 |
+ |
|
651 |
+int |
|
652 |
+im_body_draw(body_t *body, int windowwidth, int windowheight) |
|
653 |
+{ |
|
654 |
+ int i,x,y,k,margin,righty; |
|
655 |
+ dirdata_t *dirdata; |
|
656 |
+ Vector2 v2,m2; |
|
657 |
+ font_t *font,*fontbig,*fonthuge; |
|
658 |
+ if(body==NULL) |
|
659 |
+ return(-1); |
|
660 |
+ font=body->ptrfont; |
|
661 |
+ fontbig=body->ptrfontbig; |
|
662 |
+ fonthuge=body->ptrfonthuge; |
|
663 |
+ FILLWH(body->xywh,windowwidth-body->xywh.x,windowheight-body->xywh.y); |
|
664 |
+ FILLXYWH(body->backxywh,0,0,0,0); |
|
665 |
+ /* draw left side background */ |
|
666 |
+ DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
|
667 |
+ /* draw right side background */ |
|
668 |
+ DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
|
669 |
+ for(i=0,y=righty=body->xywh.y;i<body->sizedirdata;i++) { |
|
670 |
+ if((dirdata=body->dirdata[i])==NULL) |
|
671 |
+ continue; |
|
672 |
+ /* draw left side if appropiate */ |
|
673 |
+ if(i==body->currentdirdata) { |
|
674 |
+ int x0,y0,x1,y1; |
|
675 |
+ /* draw left side */ |
|
676 |
+ /* ...back arrow */ |
|
677 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2); |
|
678 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
679 |
+ m2=MeasureTextEx(fontbig->font,UTF8DOWNARROW,fontbig->height,0); |
|
680 |
+ FILLXYWH(body->backxywh,v2.x-fontbig->height/4,v2.y-fontbig->height/8,m2.x+fontbig->height/4,m2.x+fontbig->height/4); |
|
681 |
+#if 0 |
|
682 |
+DrawTexture(fontbig->font.texture, 0, 0, WHITE); /* font glyphs -- see https://github.com/raysan5/raylib/issues/2022 */ |
|
683 |
+DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone */ |
|
684 |
+#endif |
|
685 |
+ DrawTextPro(fontbig->font,UTF8DOWNARROW,(Vector2){v2.x+m2.x,v2.y},(Vector2){0,0},90.0,fontbig->height,0,(Color){65,65,65,255}); |
|
686 |
+ /* ...dirname */ |
|
687 |
+ m2=MeasureTextEx(fontbig->font,dirdata->dirname,fontbig->height,0); |
|
688 |
+ v2.x=(float) (body->xywh.x+fontbig->height/2)+(body->leftsize-(body->xywh.x+fontbig->height)-m2.x)/2; |
|
689 |
+ v2.y=(float) (body->xywh.y+fontbig->height/4); |
|
690 |
+ DrawTextEx(fontbig->font |
|
691 |
+ ,dirdata->dirname |
|
692 |
+ ,v2 |
|
693 |
+ ,fontbig->height |
|
694 |
+ ,0 |
|
695 |
+ ,(Color){ 65, 65, 65, 255 } |
|
696 |
+ ); |
|
697 |
+ /* directories */ |
|
698 |
+ x0=body->xywh.x+font->height/2; |
|
699 |
+ x1=body->xywh.x+body->leftsize-font->height/2; |
|
700 |
+ y0=body->xywh.y+font->height/4+m2.y+font->height/2; |
|
701 |
+ y1=body->xywh.y+body->xywh.h-font->height/2; |
|
702 |
+ margin=font->height/4; |
|
703 |
+ for(k=0,x=x0,y=y0;k<dirdata->listing.usedelems;k++) { |
|
704 |
+ m2=MeasureTextEx(font->font,dirdata->listing.elems[k]+1,font->height,0); |
|
705 |
+ if((x+margin*2+m2.x)>x1) |
|
706 |
+ x=x0,y+=font->height+margin*2+font->height/4; |
|
707 |
+#warning TODO: store the bounding box of the element |
|
708 |
+ DrawRectangleLines(x,y,margin*2+m2.x,margin*2+font->height,((Color){0,0,0,255})); |
|
709 |
+ DrawTextEx(font->font,dirdata->listing.elems[k]+1,(Vector2){x+margin,y+margin},font->height,0,(Color){ 65, 65, 65, 255 }); |
|
710 |
+ x+=margin*2+m2.x+font->height/4; |
|
711 |
+ } |
|
712 |
+ |
|
713 |
+#warning TODO |
|
714 |
+ /* draw right side "current" marker inside left side area */ |
|
715 |
+ DrawTriangle((Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)}, (Vector2){((float)body->xywh.x)+body->leftsize-DEFAULTDIRDATATRIANGLEW,((float)righty)+dirdata->height/2}, (Vector2){((float)body->xywh.x)+body->leftsize,((float)righty)+dirdata->height-1}, (Color){ 168, 168, 168, 255 } ); |
|
716 |
+ } |
|
717 |
+ /* draw right side */ |
|
718 |
+ /* ...bg */ |
|
719 |
+ DrawRectangle(body->xywh.x+body->leftsize,righty,body->xywh.w-body->leftsize, dirdata->height,(i==body->currentdirdata)?((Color){ 168, 168, 168, 255 }):((Color){ 227, 227, 227, 255 })); |
|
720 |
+ /* ...bottom separator */ |
|
721 |
+ DrawRectangle(body->xywh.x+body->leftsize,righty+dirdata->height-1,body->xywh.w-body->leftsize, 1, (Color){ 221, 221, 221, 255 } ); |
|
722 |
+ /* ...dirname */ |
|
723 |
+ DrawTextEx(fontbig->font |
|
724 |
+ ,dirdata->dirname |
|
725 |
+ ,(Vector2) {body->xywh.x+body->leftsize+fontbig->height/2,righty+fontbig->height/4} |
|
726 |
+ ,fontbig->height |
|
727 |
+ ,0 |
|
728 |
+ ,(Color){ 65, 65, 65, 255 } |
|
729 |
+ ); |
|
730 |
+ /* advance to next element */ |
|
731 |
+ righty+=dirdata->height; |
|
732 |
+ } |
|
733 |
+#if 0 |
|
734 |
+ /* example from menubar */ |
|
735 |
+ int i,j,k,x; |
|
736 |
+ menudata_t *menudata; |
|
737 |
+ font_t *font; |
|
472 | 738 |
if(menubar==NULL || font==NULL) |
473 | 739 |
return(-1); /* sanity check failed */ |
740 |
+ font=menubar->ptrfont; |
|
474 | 741 |
DrawRectangle(0,0,windowwidth, font->height+font->height/2, (Color){ 235, 235, 235, 235 } ); |
475 | 742 |
for(i=0,x=0;i<menubar->sizemenudata;i++) { |
476 | 743 |
Vector2 v2; |
... | ... |
@@ -523,6 +790,8 @@ im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowhei |
523 | 790 |
x=menudata->xywh.x+menudata->xywh.w; |
524 | 791 |
} |
525 | 792 |
return(0); |
793 |
+#endif |
|
794 |
+ return(0); |
|
526 | 795 |
} |
527 | 796 |
|
528 | 797 |
int |
... | ... |
@@ -662,6 +931,8 @@ getcodepoints(int *sizecodepoints) |
662 | 931 |
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, |
663 | 932 |
/* Latin-1 Supplement */ |
664 | 933 |
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, |
934 |
+/* down arrow (U+2186 -- this font doesn't have arrows, this is old roman numeral 50 */ |
|
935 |
+(0x21<<8)|0x86, |
|
665 | 936 |
}; |
666 | 937 |
if(sizecodepoints!=NULL) |
667 | 938 |
*sizecodepoints=(int) (sizeof(codepoints)/sizeof(codepoints[0])); |
... | ... |
@@ -675,18 +946,21 @@ strptrcmp(void *a,void *b) |
675 | 946 |
} |
676 | 947 |
|
677 | 948 |
int |
678 |
-listing_get(listing_t *listing, char *path, int flag_sort) |
|
949 |
+listing_get(listing_t *listing, char *pathprefix, char *parampath, int flag_sort) |
|
679 | 950 |
{ |
680 | 951 |
int l; |
681 | 952 |
DIR *d; |
682 | 953 |
struct dirent *de; |
683 | 954 |
unsigned char dtype; |
955 |
+ char path[1024]; |
|
684 | 956 |
if(listing==NULL) |
685 | 957 |
return(-1); /* sanity check failed */ |
686 | 958 |
listing->usedelems=listing->usedbuf=0; |
687 |
- if(path==NULL) |
|
959 |
+ if(pathprefix==NULL && parampath==NULL) |
|
688 | 960 |
return(-1); /* nothing to fill */ |
689 |
- if((d=opendir(".." SEP "."))==NULL) |
|
961 |
+ snprintf(path,sizeof(path),"%s%s%s",(pathprefix!=NULL)?pathprefix:"",SEP,(parampath!=NULL)?parampath:""); |
|
962 |
+ path[sizeof(path)-1]='\0'; |
|
963 |
+ if((d=opendir(path))==NULL) |
|
690 | 964 |
return(-1); /* dir not found */ |
691 | 965 |
while((de=readdir(d))!=NULL) { |
692 | 966 |
l=strlen(de->d_name); |
... | ... |
@@ -702,7 +976,7 @@ listing_get(listing_t *listing, char *path, int flag_sort) |
702 | 976 |
:'u'; |
703 | 977 |
#endif |
704 | 978 |
if(dtype=='u') { |
705 |
- char stpath[1024]; |
|
979 |
+ char stpath[2048]; |
|
706 | 980 |
struct stat st; |
707 | 981 |
mode_t m; |
708 | 982 |
snprintf(stpath,sizeof(stpath),"%s%s%s",path,SEP,de->d_name); |
... | ... |
@@ -8,6 +8,7 @@ |
8 | 8 |
* 20250123 Load font. |
9 | 9 |
* 20250213 Support sticky drop-down menus. |
10 | 10 |
* 20250216 Modularize menu handling. |
11 |
+ * 20250222 Able to list files. |
|
11 | 12 |
* |
12 | 13 |
* Author: Dario Rodriguez dario@darionomono.com |
13 | 14 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -18,6 +19,9 @@ |
18 | 19 |
#include <stdlib.h> |
19 | 20 |
#include <unistd.h> |
20 | 21 |
#include <string.h> |
22 |
+#include <sys/types.h> |
|
23 |
+#include <dirent.h> |
|
24 |
+#include <sys/stat.h> |
|
21 | 25 |
|
22 | 26 |
#include "raylib.h" |
23 | 27 |
#include "roboto_regular.c" |
... | ... |
@@ -25,6 +29,14 @@ |
25 | 29 |
#define DEFAULTWIDTH 1280 |
26 | 30 |
#define DEFAULTHEIGHT 768 |
27 | 31 |
|
32 |
+#define LEFTSIZE 720 |
|
33 |
+#define RIGHTELEMHEIGHT 280 |
|
34 |
+ |
|
35 |
+#define SEP "/" |
|
36 |
+ |
|
37 |
+#define BLOCKLISTINGBUF 2048 |
|
38 |
+#define BLOCKLISTINGELEMS 1024 |
|
39 |
+ |
|
28 | 40 |
#ifndef FILLXY |
29 | 41 |
#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
30 | 42 |
#endif |
... | ... |
@@ -70,9 +82,19 @@ typedef struct menubar_t { |
70 | 82 |
menudata_t **menudata; |
71 | 83 |
} menubar_t; |
72 | 84 |
|
85 |
+typedef struct listing_t { |
|
86 |
+ int sizeelems; |
|
87 |
+ int usedelems; |
|
88 |
+ char **elems; /* first byte in the elem is the type, next is the name, i.e. a directory is "dhome" and a file is "f.bashrc" */ |
|
89 |
+ int sizebuf; |
|
90 |
+ int usedbuf; |
|
91 |
+ char *buf; |
|
92 |
+} listing_t; |
|
93 |
+ |
|
73 | 94 |
typedef struct dirdata_t { |
74 | 95 |
int height; |
75 | 96 |
char *dirname; |
97 |
+ listing_t listing; |
|
76 | 98 |
} dirdata_t; |
77 | 99 |
|
78 | 100 |
typedef struct im_t { |
... | ... |
@@ -88,6 +110,7 @@ typedef struct im_t { |
88 | 110 |
font_t *font; |
89 | 111 |
} im_t; |
90 | 112 |
|
113 |
+ |
|
91 | 114 |
im_t *im_init(char *menus); |
92 | 115 |
void im_free(im_t *im); |
93 | 116 |
|
... | ... |
@@ -100,6 +123,9 @@ void im_menubar_free(menubar_t *menubar); |
100 | 123 |
int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
101 | 124 |
int im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowheight); |
102 | 125 |
|
126 |
+int listing_get(listing_t *listing, char *path, int flag_sort); |
|
127 |
+void listing_freedata(listing_t *listing); |
|
128 |
+ |
|
103 | 129 |
int imutil_menu_count(char *menus); |
104 | 130 |
char *imutil_menu_get(char *menus, int targetn, int *len); |
105 | 131 |
int imutil_submenu_count(char *menus); |
... | ... |
@@ -142,6 +168,39 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
142 | 168 |
BeginDrawing(); |
143 | 169 |
ClearBackground(RAYWHITE); |
144 | 170 |
im_menubar_draw(im->menubar,im->font,im->w,im->h); |
171 |
+#if 1 |
|
172 |
+{ |
|
173 |
+ int i,j; |
|
174 |
+ Vector2 v2; |
|
175 |
+ listing_t listing={0}; |
|
176 |
+ if(listing_get(&listing,".." SEP ".",1)==0) { |
|
177 |
+ i=2; |
|
178 |
+ v2.x=(float) (im->font->height/2); |
|
179 |
+ v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
|
180 |
+ DrawTextEx(im->font->font |
|
181 |
+ ,SEP |
|
182 |
+ ,v2 |
|
183 |
+ ,im->font->height |
|
184 |
+ ,0 |
|
185 |
+ ,((Color){ 45, 45, 45, 255 }) |
|
186 |
+ ); |
|
187 |
+ for(j=0;j<listing.usedelems;j++) { |
|
188 |
+ Color c; |
|
189 |
+ i++; |
|
190 |
+ c=((Color){ 45, 45, 45, 255 }); |
|
191 |
+ v2.x=(float) (im->font->height/2); |
|
192 |
+ v2.y=(float) ((im->font->height+im->font->height/2)*i+(im->font->height/4)); |
|
193 |
+ DrawTextEx(im->font->font |
|
194 |
+ ,listing.elems[j] |
|
195 |
+ ,v2 |
|
196 |
+ ,im->font->height |
|
197 |
+ ,0 |
|
198 |
+ ,c |
|
199 |
+ ); |
|
200 |
+ } |
|
201 |
+ } |
|
202 |
+} |
|
203 |
+#endif |
|
145 | 204 |
EndDrawing(); |
146 | 205 |
} |
147 | 206 |
CloseWindow(); |
... | ... |
@@ -189,6 +248,7 @@ im_free(im_t *im) |
189 | 248 |
continue; |
190 | 249 |
if(dirdata->dirname!=NULL) |
191 | 250 |
free(dirdata->dirname),dirdata->dirname=NULL; |
251 |
+ listing_freedata(&(dirdata->listing)); |
|
192 | 252 |
} |
193 | 253 |
free(im->dirdata),im->dirdata=NULL,im->sizedirdata=0; |
194 | 254 |
} |
... | ... |
@@ -608,3 +668,112 @@ getcodepoints(int *sizecodepoints) |
608 | 668 |
return(codepoints); |
609 | 669 |
} |
610 | 670 |
|
671 |
+static int |
|
672 |
+strptrcmp(void *a,void *b) |
|
673 |
+{ |
|
674 |
+ return(strcmp(*((char **)a),*((char **)b))); |
|
675 |
+} |
|
676 |
+ |
|
677 |
+int |
|
678 |
+listing_get(listing_t *listing, char *path, int flag_sort) |
|
679 |
+{ |
|
680 |
+ int l; |
|
681 |
+ DIR *d; |
|
682 |
+ struct dirent *de; |
|
683 |
+ unsigned char dtype; |
|
684 |
+ if(listing==NULL) |
|
685 |
+ return(-1); /* sanity check failed */ |
|
686 |
+ listing->usedelems=listing->usedbuf=0; |
|
687 |
+ if(path==NULL) |
|
688 |
+ return(-1); /* nothing to fill */ |
|
689 |
+ if((d=opendir(".." SEP "."))==NULL) |
|
690 |
+ return(-1); /* dir not found */ |
|
691 |
+ while((de=readdir(d))!=NULL) { |
|
692 |
+ l=strlen(de->d_name); |
|
693 |
+ dtype='u'; |
|
694 |
+#ifdef _DIRENT_HAVE_D_TYPE |
|
695 |
+ dtype=(de->d_type==DT_BLK)?'b' |
|
696 |
+ :(de->d_type==DT_CHR)?'c' |
|
697 |
+ :(de->d_type==DT_DIR)?'d' |
|
698 |
+ :(de->d_type==DT_FIFO)?'p' |
|
699 |
+ :(de->d_type==DT_LNK)?'l' |
|
700 |
+ :(de->d_type==DT_REG)?'f' |
|
701 |
+ :(de->d_type==DT_SOCK)?'s' |
|
702 |
+ :'u'; |
|
703 |
+#endif |
|
704 |
+ if(dtype=='u') { |
|
705 |
+ char stpath[1024]; |
|
706 |
+ struct stat st; |
|
707 |
+ mode_t m; |
|
708 |
+ snprintf(stpath,sizeof(stpath),"%s%s%s",path,SEP,de->d_name); |
|
709 |
+ stpath[sizeof(stpath)-1]='\0'; |
|
710 |
+ if(stat(stpath,&st)==0 && (m=(st.st_mode&S_IFMT))!=0) { |
|
711 |
+ dtype=(m==S_IFBLK)?'b' |
|
712 |
+ :(m==S_IFCHR)?'c' |
|
713 |
+ :(m==S_IFDIR)?'d' |
|
714 |
+ :(m==S_IFIFO)?'p' |
|
715 |
+#ifdef S_IFLNK |
|
716 |
+ :(m==S_IFLNK)?'l' |
|
717 |
+#endif |
|
718 |
+ :(m==S_IFREG)?'f' |
|
719 |
+#ifdef S_IFSOCK |
|
720 |
+ :(m==S_IFSOCK)?'s' |
|
721 |
+#endif |
|
722 |
+ :'u'; |
|
723 |
+ } |
|
724 |
+ } |
|
725 |
+ /* check for space for this elem (and get space if necessary) */ |
|
726 |
+ if(listing->usedelems==listing->sizeelems) { |
|
727 |
+ char **newelems; |
|
728 |
+ if((newelems=realloc(listing->elems,sizeof(char *)*(listing->sizeelems+BLOCKLISTINGELEMS)))==NULL) { |
|
729 |
+ closedir(d),d=NULL; |
|
730 |
+ return(-1); /* insuf. mem. */ |
|
731 |
+ } |
|
732 |
+ listing->elems=newelems; |
|
733 |
+ listing->sizeelems+=BLOCKLISTINGELEMS; |
|
734 |
+ } |
|
735 |
+ /* check for space for this elem data (and get space if necessary) */ |
|
736 |
+ if((listing->sizebuf+l+2)>listing->sizebuf) { |
|
737 |
+ int i; |
|
738 |
+ char *newbuf; |
|
739 |
+ int newsize; |
|
740 |
+ int off; |
|
741 |
+ newsize=listing->sizebuf+l+2+BLOCKLISTINGBUF-1; |
|
742 |
+ newsize/=BLOCKLISTINGBUF; |
|
743 |
+ newsize*=BLOCKLISTINGBUF; |
|
744 |
+ if((newbuf=realloc(listing->buf,newsize))==NULL) { |
|
745 |
+ closedir(d),d=NULL; |
|
746 |
+ return(-1); /* insuf. mem. */ |
|
747 |
+ } |
|
748 |
+ /* the elem data buffer has a new pointer, fix previous entries */ |
|
749 |
+ for(i=0;i<listing->usedelems;i++) { |
|
750 |
+ off=(listing->elems[i])-listing->buf; |
|
751 |
+ listing->elems[i]=newbuf+off; |
|
752 |
+ } |
|
753 |
+ listing->buf=newbuf; |
|
754 |
+ listing->sizebuf+=BLOCKLISTINGELEMS; |
|
755 |
+ } |
|
756 |
+ /* store the data */ |
|
757 |
+ listing->elems[listing->usedelems++]=listing->buf+listing->usedbuf; |
|
758 |
+ listing->buf[listing->usedbuf++]=dtype; |
|
759 |
+ memcpy(listing->buf+listing->usedbuf,de->d_name,l+1); |
|
760 |
+ listing->usedbuf+=l+1; |
|
761 |
+ } |
|
762 |
+ closedir(d),d=NULL; |
|
763 |
+ if(flag_sort) |
|
764 |
+ qsort(listing->elems,listing->usedelems,sizeof(char *),(int (*)(const void *, const void *)) strptrcmp); |
|
765 |
+ return(0); |
|
766 |
+} |
|
767 |
+ |
|
768 |
+void |
|
769 |
+listing_freedata(listing_t *listing) |
|
770 |
+{ |
|
771 |
+ if(listing==NULL) |
|
772 |
+ return; /* nothing to do */ |
|
773 |
+ if(listing->elems!=NULL) |
|
774 |
+ free(listing->elems),listing->elems=NULL,listing->sizeelems=listing->usedelems=0; |
|
775 |
+ if(listing->buf!=NULL) |
|
776 |
+ free(listing->buf),listing->buf=NULL,listing->sizebuf=listing->usedbuf=0; |
|
777 |
+ return; |
|
778 |
+} |
|
779 |
+ |
... | ... |
@@ -7,6 +7,7 @@ |
7 | 7 |
* 20250119 Creation. Menu bar. |
8 | 8 |
* 20250123 Load font. |
9 | 9 |
* 20250213 Support sticky drop-down menus. |
10 |
+ * 20250216 Modularize menu handling. |
|
10 | 11 |
* |
11 | 12 |
* Author: Dario Rodriguez dario@darionomono.com |
12 | 13 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -47,6 +48,12 @@ typedef struct xywh_t { |
47 | 48 |
int h; |
48 | 49 |
} xywh_t; |
49 | 50 |
|
51 |
+typedef struct font_t { |
|
52 |
+ Font font; |
|
53 |
+ int height; |
|
54 |
+} font_t; |
|
55 |
+ |
|
56 |
+ |
|
50 | 57 |
typedef struct menudata_t { |
51 | 58 |
char *title; |
52 | 59 |
xywh_t xywh; |
... | ... |
@@ -58,29 +65,40 @@ typedef struct menudata_t { |
58 | 65 |
int currentoption; |
59 | 66 |
} menudata_t; |
60 | 67 |
|
68 |
+typedef struct menubar_t { |
|
69 |
+ int sizemenudata; |
|
70 |
+ menudata_t **menudata; |
|
71 |
+} menubar_t; |
|
72 |
+ |
|
61 | 73 |
typedef struct dirdata_t { |
62 | 74 |
int height; |
63 | 75 |
char *dirname; |
64 | 76 |
} dirdata_t; |
65 | 77 |
|
66 | 78 |
typedef struct im_t { |
79 |
+ int windowinit; |
|
67 | 80 |
int w; |
68 | 81 |
int h; |
69 |
- int sizemenudata; |
|
70 |
- menudata_t **menudata; |
|
71 | 82 |
int sizedirdata; |
72 | 83 |
dirdata_t **dirdata; |
73 | 84 |
int currentdirdata; |
74 | 85 |
int leftscrollpos; |
75 | 86 |
int rightscrollpos; |
76 |
- Font font; |
|
77 |
- int font_height; |
|
87 |
+ menubar_t *menubar; |
|
88 |
+ font_t *font; |
|
78 | 89 |
} im_t; |
79 | 90 |
|
80 | 91 |
im_t *im_init(char *menus); |
81 | 92 |
void im_free(im_t *im); |
82 | 93 |
|
83 |
-int imdraw_menus(im_t *im); |
|
94 |
+font_t *im_font_init(void); |
|
95 |
+void im_font_free(font_t *font); |
|
96 |
+ |
|
97 |
+menubar_t *im_menubar_init(char *menus); |
|
98 |
+void im_menubar_free(menubar_t *menubar); |
|
99 |
+ |
|
100 |
+int im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu); |
|
101 |
+int im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowheight); |
|
84 | 102 |
|
85 | 103 |
int imutil_menu_count(char *menus); |
86 | 104 |
char *imutil_menu_get(char *menus, int targetn, int *len); |
... | ... |
@@ -97,9 +115,9 @@ main(int argc, char *argv[]) |
97 | 115 |
im_t *im; |
98 | 116 |
Vector2 mousepos; |
99 | 117 |
int flag_ignorelmb; |
100 |
- int i,j; |
|
101 | 118 |
int lmbpressed,lmbreleased,lmbdown; |
102 |
- int flag_outsideall; |
|
119 |
+ int click_avail; |
|
120 |
+ char *sel_menu,*sel_submenu; |
|
103 | 121 |
if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n"))==NULL) { |
104 | 122 |
return(1); |
105 | 123 |
} |
... | ... |
@@ -109,69 +127,21 @@ main(int argc, char *argv[]) |
109 | 127 |
lmbpressed=IsMouseButtonPressed(0); |
110 | 128 |
lmbreleased=IsMouseButtonReleased(0); |
111 | 129 |
lmbdown=IsMouseButtonDown(0); |
112 |
- /* check if we have to open a menu */ |
|
113 |
- flag_outsideall=1; |
|
114 |
- for(i=0;i<im->sizemenudata;i++) { |
|
115 |
- int insidetitle,currentoption; |
|
116 |
- insidetitle=is_imutil_insidexywh(mousepos,&(im->menudata[i]->xywh)); |
|
117 |
- currentoption=menudata_pos2option(im->menudata[i],mousepos); |
|
118 |
- flag_outsideall=(currentoption!=-1 || insidetitle)?0:flag_outsideall; |
|
119 |
- if(lmbreleased && insidetitle) { |
|
120 |
- for(j=0;j<im->sizemenudata;j++) { |
|
121 |
- im->menudata[j]->flag_stickyopen=(j==i)?1:0; |
|
122 |
- im->menudata[j]->flag_open=0; |
|
123 |
- im->menudata[j]->currentoption=-1; |
|
124 |
- } |
|
125 |
- } else if((lmbpressed || lmbdown) && insidetitle) { |
|
126 |
- for(j=0;j<im->sizemenudata;j++) { |
|
127 |
- im->menudata[j]->flag_open=(j==i)?1:0; |
|
128 |
- im->menudata[j]->flag_stickyopen=0; |
|
129 |
- im->menudata[j]->currentoption=-1; |
|
130 |
- } |
|
131 |
- } else if((lmbdown || im->menudata[i]->flag_stickyopen) && currentoption!=-1) { |
|
132 |
- for(j=0;j<im->sizemenudata;j++) { |
|
133 |
- if(lmbreleased==0 || j!=i || im->menudata[i]->flag_stickyopen==0) { |
|
134 |
- im->menudata[j]->flag_open=(j==i)?im->menudata[i]->flag_open:0; |
|
135 |
- im->menudata[j]->flag_stickyopen=(j==i)?im->menudata[i]->flag_stickyopen:0; |
|
136 |
- im->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
137 |
- } else { |
|
138 |
- im->menudata[j]->flag_open=0; |
|
139 |
- im->menudata[j]->flag_stickyopen=0; |
|
140 |
- im->menudata[j]->currentoption=-1; |
|
130 |
+ click_avail=1; |
|
131 |
+ /* process clicks on menus */ |
|
132 |
+ if(click_avail) { |
|
133 |
+ sel_menu=sel_submenu=NULL; |
|
134 |
+ im_menubar_mouse(im->menubar, mousepos, lmbpressed, lmbreleased, lmbdown, &click_avail, &sel_menu, &sel_submenu); |
|
135 |
+ if(sel_menu!=NULL && sel_submenu!=NULL) { |
|
141 | 136 |
#if 1 |
142 |
-fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",im->menudata[i]->title,im->menudata[i]->options[currentoption]); |
|
137 |
+fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
|
143 | 138 |
#endif |
144 |
- } |
|
145 |
- } |
|
146 |
- } else if(im->menudata[i]->flag_stickyopen && currentoption==-1) { |
|
147 |
- if(lmbreleased) { |
|
148 |
- im->menudata[i]->flag_open=0; |
|
149 |
- im->menudata[i]->flag_stickyopen=0; |
|
150 |
- } |
|
151 |
- im->menudata[i]->currentoption=-1; |
|
152 |
- } else if(lmbreleased && currentoption!=-1) { |
|
153 |
- for(j=0;j<im->sizemenudata;j++) { |
|
154 |
- im->menudata[j]->flag_open=0; |
|
155 |
- im->menudata[j]->flag_stickyopen=0; |
|
156 |
- im->menudata[j]->currentoption=-1; |
|
157 |
- } |
|
158 |
-#if 1 |
|
159 |
-fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",im->menudata[i]->title,im->menudata[i]->options[currentoption]); |
|
160 |
-#endif |
|
161 |
- } else if(lmbdown==0) { |
|
162 |
- im->menudata[i]->flag_open=0; |
|
163 |
- im->menudata[i]->flag_stickyopen=0; |
|
164 |
- im->menudata[i]->currentoption=-1; |
|
165 |
- } |
|
166 |
- } |
|
167 |
- if(flag_outsideall) { |
|
168 |
- for(j=0;j<im->sizemenudata;j++) { |
|
169 |
- im->menudata[j]->currentoption=-1; |
|
170 | 139 |
} |
171 | 140 |
} |
141 |
+ /* draw screen contents */ |
|
172 | 142 |
BeginDrawing(); |
173 | 143 |
ClearBackground(RAYWHITE); |
174 |
- imdraw_menus(im); |
|
144 |
+ im_menubar_draw(im->menubar,im->font,im->w,im->h); |
|
175 | 145 |
EndDrawing(); |
176 | 146 |
} |
177 | 147 |
CloseWindow(); |
... | ... |
@@ -183,51 +153,118 @@ im_t * |
183 | 153 |
im_init(char *menus) |
184 | 154 |
{ |
185 | 155 |
im_t *im; |
156 |
+ if(menus==NULL) |
|
157 |
+ return(NULL); /* sanity check failed */ |
|
158 |
+ if((im=calloc(1,sizeof(im_t)))==NULL |
|
159 |
+ || (im->menubar=im_menubar_init(menus))==NULL |
|
160 |
+ ) { |
|
161 |
+ im_free(im),im=NULL; |
|
162 |
+ return(NULL); /* insuf. mem. */ |
|
163 |
+ } |
|
164 |
+ /* init window */ |
|
165 |
+ SetTraceLogLevel(LOG_ERROR); |
|
166 |
+ InitWindow((im->w=DEFAULTWIDTH),(im->h=DEFAULTHEIGHT),"Image Mover"); |
|
167 |
+ im->windowinit=1; |
|
168 |
+ SetTargetFPS(30); |
|
169 |
+ /* init font */ |
|
170 |
+ if((im->font=im_font_init())==NULL) { |
|
171 |
+ im_free(im),im=NULL; |
|
172 |
+ return(NULL); /* insuf. mem. */ |
|
173 |
+ } |
|
174 |
+ return(im); |
|
175 |
+} |
|
176 |
+ |
|
177 |
+void |
|
178 |
+im_free(im_t *im) |
|
179 |
+{ |
|
180 |
+ int i; |
|
181 |
+ if(im==NULL) |
|
182 |
+ return; |
|
183 |
+ if(im->menubar!=NULL) |
|
184 |
+ im_menubar_free(im->menubar),im->menubar=NULL; |
|
185 |
+ if(im->dirdata!=NULL) { |
|
186 |
+ dirdata_t *dirdata; |
|
187 |
+ for(i=0;i<im->sizedirdata;i++) { |
|
188 |
+ if((dirdata=im->dirdata[i])==NULL) |
|
189 |
+ continue; |
|
190 |
+ if(dirdata->dirname!=NULL) |
|
191 |
+ free(dirdata->dirname),dirdata->dirname=NULL; |
|
192 |
+ } |
|
193 |
+ free(im->dirdata),im->dirdata=NULL,im->sizedirdata=0; |
|
194 |
+ } |
|
195 |
+ if(im->font!=NULL) |
|
196 |
+ im_font_free(im->font),im->font=NULL; |
|
197 |
+#if 0 /* not working as intended */ |
|
198 |
+ if(im->windowinit) |
|
199 |
+ CloseWindow(),im->windowinit=0; |
|
200 |
+#endif |
|
201 |
+ free(im),im=NULL; |
|
202 |
+ return; |
|
203 |
+} |
|
204 |
+ |
|
205 |
+font_t * |
|
206 |
+im_font_init(void) |
|
207 |
+{ |
|
208 |
+ font_t *font; |
|
209 |
+ int sizecodepoints; |
|
210 |
+ int *codepoints; |
|
211 |
+ if((font=calloc(1,sizeof(font_t)))==NULL) |
|
212 |
+ return(NULL); /* insuf. mem. */ |
|
213 |
+ font->height=18; |
|
214 |
+ codepoints=getcodepoints(&sizecodepoints); |
|
215 |
+ font->font=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,font->height,codepoints,sizecodepoints); |
|
216 |
+ return(font); |
|
217 |
+} |
|
218 |
+ |
|
219 |
+void |
|
220 |
+im_font_free(font_t *font) |
|
221 |
+{ |
|
222 |
+ if(font==NULL) |
|
223 |
+ return; |
|
224 |
+#if 0 /* not working as intended */ |
|
225 |
+ UnloadFont(font->font); |
|
226 |
+#endif |
|
227 |
+ free(font),font=NULL; |
|
228 |
+ return; |
|
229 |
+} |
|
230 |
+ |
|
231 |
+menubar_t * |
|
232 |
+im_menubar_init(char *menus) |
|
233 |
+{ |
|
186 | 234 |
int i,j; |
187 | 235 |
char *str,*substr; |
188 | 236 |
int len,sublen; |
237 |
+ menubar_t *menubar; |
|
189 | 238 |
menudata_t *menudata; |
190 | 239 |
if(menus==NULL) |
191 | 240 |
return(NULL); /* sanity check failed */ |
192 |
- if((im=calloc(1,sizeof(im_t)))==NULL |
|
193 |
- || (im->sizemenudata=imutil_menu_count(menus))<=0 |
|
194 |
- || (im->menudata=calloc(im->sizemenudata,sizeof(menudata_t)))==NULL |
|
241 |
+ if((menubar=calloc(1,sizeof(menubar_t)))==NULL |
|
242 |
+ || (menubar->sizemenudata=imutil_menu_count(menus))<=0 |
|
243 |
+ || (menubar->menudata=calloc(menubar->sizemenudata,sizeof(menudata_t)))==NULL |
|
195 | 244 |
) { |
196 |
- im_free(im),im=NULL; |
|
245 |
+ im_menubar_free(menubar),menubar=NULL; |
|
197 | 246 |
return(NULL); /* insuf. mem. */ |
198 | 247 |
} |
199 | 248 |
/* init menus */ |
200 |
- for(i=0;i<im->sizemenudata;i++) { |
|
201 |
- if((menudata=im->menudata[i]=calloc(1,sizeof(menudata_t)))==NULL |
|
249 |
+ for(i=0;i<menubar->sizemenudata;i++) { |
|
250 |
+ if((menudata=menubar->menudata[i]=calloc(1,sizeof(menudata_t)))==NULL |
|
202 | 251 |
|| (str=imutil_menu_get(menus,i,&len))==NULL |
203 | 252 |
|| (menudata->title=imutil_strduplen(str,len))==NULL |
204 | 253 |
|| (menudata->sizeoptions=imutil_submenu_count(str))<=0 |
205 | 254 |
|| (menudata->options=calloc(menudata->sizeoptions,sizeof(char *)))==NULL |
206 | 255 |
) { |
207 |
- im_free(im),im=NULL; |
|
256 |
+ im_menubar_free(menubar),menubar=NULL; |
|
208 | 257 |
return(NULL); /* insuf. mem. */ |
209 | 258 |
} |
210 | 259 |
for(j=0;j<menudata->sizeoptions;j++) { |
211 | 260 |
if((substr=imutil_submenu_get(str,j,&sublen))==NULL |
212 | 261 |
|| (menudata->options[j]=imutil_strduplen(substr,sublen))==NULL |
213 | 262 |
) { |
214 |
- im_free(im),im=NULL; |
|
263 |
+ im_menubar_free(menubar),menubar=NULL; |
|
215 | 264 |
return(NULL); /* insuf. mem. */ |
216 | 265 |
} |
217 | 266 |
} |
218 | 267 |
} |
219 |
- /* init window */ |
|
220 |
- SetTraceLogLevel(LOG_ERROR); |
|
221 |
- InitWindow((im->w=DEFAULTWIDTH),(im->h=DEFAULTHEIGHT),"Image Mover"); |
|
222 |
- SetTargetFPS(30); |
|
223 |
- /* init font */ |
|
224 |
- { |
|
225 |
- int sizecodepoints; |
|
226 |
- int *codepoints; |
|
227 |
- im->font_height=18; |
|
228 |
- codepoints=getcodepoints(&sizecodepoints); |
|
229 |
- im->font=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,im->font_height,codepoints,sizecodepoints); |
|
230 |
- } |
|
231 | 268 |
#if 0 |
232 | 269 |
/* test imutil_menu_xxx */ |
233 | 270 |
int n,m,l,ml,len,mlen; |
... | ... |
@@ -248,26 +285,26 @@ im_init(char *menus) |
248 | 285 |
#endif |
249 | 286 |
#if 0 |
250 | 287 |
/* test menudata */ |
251 |
- for(i=0;i<im->sizemenudata;i++) { |
|
252 |
- fprintf(stderr,"menu[%i]:\"%s\"->",i,im->menudata[i]->title); |
|
253 |
- for(j=0;j<im->menudata[i]->sizeoptions;j++) |
|
254 |
- fprintf(stderr,"|\"%s\"",im->menudata[i]->options[j]); |
|
288 |
+ for(i=0;i<menubar->sizemenudata;i++) { |
|
289 |
+ fprintf(stderr,"menu[%i]:\"%s\"->",i,menubar->menudata[i]->title); |
|
290 |
+ for(j=0;j<menubar->menudata[i]->sizeoptions;j++) |
|
291 |
+ fprintf(stderr,"|\"%s\"",menubar->menudata[i]->options[j]); |
|
255 | 292 |
fprintf(stderr,"\n"); |
256 | 293 |
} |
257 | 294 |
#endif |
258 |
- return(im); |
|
295 |
+ return(menubar); |
|
259 | 296 |
} |
260 | 297 |
|
261 | 298 |
void |
262 |
-im_free(im_t *im) |
|
299 |
+im_menubar_free(menubar_t *menubar) |
|
263 | 300 |
{ |
264 | 301 |
int i,j; |
265 |
- if(im==NULL) |
|
302 |
+ menudata_t *menudata; |
|
303 |
+ if(menubar==NULL) |
|
266 | 304 |
return; |
267 |
- if(im->menudata!=NULL) { |
|
268 |
- menudata_t *menudata; |
|
269 |
- for(i=0;i<im->sizemenudata;i++) { |
|
270 |
- if((menudata=im->menudata[i])==NULL) |
|
305 |
+ if(menubar->menudata!=NULL) { |
|
306 |
+ for(i=0;i<menubar->sizemenudata;i++) { |
|
307 |
+ if((menudata=menubar->menudata[i])==NULL) |
|
271 | 308 |
continue; |
272 | 309 |
if(menudata->title!=NULL) |
273 | 310 |
free(menudata->title),menudata->title=NULL; |
... | ... |
@@ -278,41 +315,114 @@ im_free(im_t *im) |
278 | 315 |
} |
279 | 316 |
free(menudata->options),menudata->options=NULL,menudata->sizeoptions=0; |
280 | 317 |
} |
281 |
- free(im->menudata[i]),im->menudata[i]=NULL,menudata=NULL; |
|
318 |
+ free(menubar->menudata[i]),menubar->menudata[i]=NULL,menudata=NULL; |
|
282 | 319 |
} |
283 |
- free(im->menudata),im->menudata=NULL,im->sizemenudata=0; |
|
320 |
+ free(menubar->menudata),menubar->menudata=NULL,menubar->sizemenudata=0; |
|
284 | 321 |
} |
285 |
- if(im->dirdata!=NULL) { |
|
286 |
- dirdata_t *dirdata; |
|
287 |
- for(i=0;i<im->sizedirdata;i++) { |
|
288 |
- if((dirdata=im->dirdata[i])==NULL) |
|
289 |
- continue; |
|
290 |
- if(dirdata->dirname!=NULL) |
|
291 |
- free(dirdata->dirname),dirdata->dirname=NULL; |
|
322 |
+ free(menubar),menubar=NULL; |
|
323 |
+ return; |
|
324 |
+} |
|
325 |
+ |
|
326 |
+int |
|
327 |
+im_menubar_mouse(menubar_t *menubar, Vector2 mousepos, int lmbpressed, int lmbreleased, int lmbdown, int *click_avail, char **sel_menu, char **sel_submenu) |
|
328 |
+{ |
|
329 |
+ int flag_outsideall; |
|
330 |
+ int i,j; |
|
331 |
+ if(menubar==NULL || click_avail==NULL || sel_menu==NULL || sel_submenu==NULL) |
|
332 |
+ return(-1); |
|
333 |
+ *click_avail=1; |
|
334 |
+ *sel_menu=NULL; |
|
335 |
+ *sel_submenu=NULL; |
|
336 |
+ flag_outsideall=1; |
|
337 |
+ for(i=0;i<menubar->sizemenudata;i++) { |
|
338 |
+ int insidetitle,currentoption; |
|
339 |
+ insidetitle=is_imutil_insidexywh(mousepos,&(menubar->menudata[i]->xywh)); |
|
340 |
+ currentoption=menudata_pos2option(menubar->menudata[i],mousepos); |
|
341 |
+ flag_outsideall=(currentoption!=-1 || insidetitle)?0:flag_outsideall; |
|
342 |
+ if(lmbreleased && insidetitle) { |
|
343 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
344 |
+ menubar->menudata[j]->flag_stickyopen=(j==i)?1:0; |
|
345 |
+ menubar->menudata[j]->flag_open=0; |
|
346 |
+ menubar->menudata[j]->currentoption=-1; |
|
347 |
+ } |
|
348 |
+ } else if((lmbpressed || lmbdown) && insidetitle) { |
|
349 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
350 |
+ menubar->menudata[j]->flag_open=(j==i)?1:0; |
|
351 |
+ menubar->menudata[j]->flag_stickyopen=0; |
|
352 |
+ menubar->menudata[j]->currentoption=-1; |
|
353 |
+ } |
|
354 |
+ } else if((lmbdown || menubar->menudata[i]->flag_stickyopen) && currentoption!=-1) { |
|
355 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
356 |
+ if(lmbreleased==0 || j!=i || menubar->menudata[i]->flag_stickyopen==0) { |
|
357 |
+ menubar->menudata[j]->flag_open=(j==i)?menubar->menudata[i]->flag_open:0; |
|
358 |
+ menubar->menudata[j]->flag_stickyopen=(j==i)?menubar->menudata[i]->flag_stickyopen:0; |
|
359 |
+ menubar->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
360 |
+ } else { |
|
361 |
+ menubar->menudata[j]->flag_open=0; |
|
362 |
+ menubar->menudata[j]->flag_stickyopen=0; |
|
363 |
+ menubar->menudata[j]->currentoption=-1; |
|
364 |
+ /* has selected this submenu */ |
|
365 |
+ *click_avail=0; |
|
366 |
+ *sel_menu=menubar->menudata[j]->title; |
|
367 |
+ *sel_submenu=menubar->menudata[j]->options[currentoption]; |
|
368 |
+ } |
|
369 |
+ } |
|
370 |
+ } else if(menubar->menudata[i]->flag_stickyopen && currentoption==-1) { |
|
371 |
+ if(lmbreleased) { |
|
372 |
+ menubar->menudata[i]->flag_open=0; |
|
373 |
+ menubar->menudata[i]->flag_stickyopen=0; |
|
374 |
+ } |
|
375 |
+ menubar->menudata[i]->currentoption=-1; |
|
376 |
+ } else if(lmbreleased && currentoption!=-1) { |
|
377 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
378 |
+ menubar->menudata[j]->flag_open=0; |
|
379 |
+ menubar->menudata[j]->flag_stickyopen=0; |
|
380 |
+ menubar->menudata[j]->currentoption=-1; |
|
381 |
+ } |
|
382 |
+ /* has selected this submenu */ |
|
383 |
+ *click_avail=0; |
|
384 |
+ *sel_menu=menubar->menudata[i]->title; |
|
385 |
+ *sel_submenu=menubar->menudata[i]->options[currentoption]; |
|
386 |
+ } else if(lmbdown==0) { |
|
387 |
+ menubar->menudata[i]->flag_open=0; |
|
388 |
+ menubar->menudata[i]->flag_stickyopen=0; |
|
389 |
+ menubar->menudata[i]->currentoption=-1; |
|
292 | 390 |
} |
293 |
- free(im->dirdata),im->dirdata=NULL,im->sizedirdata=0; |
|
294 | 391 |
} |
295 |
- free(im),im=NULL; |
|
296 |
- return; |
|
392 |
+ if(flag_outsideall) { |
|
393 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
394 |
+ menubar->menudata[j]->currentoption=-1; |
|
395 |
+ } |
|
396 |
+ } |
|
397 |
+ /* update click_avail */ |
|
398 |
+ for(j=0;j<menubar->sizemenudata;j++) { |
|
399 |
+ if(menubar->menudata[j]->flag_open || menubar->menudata[j]->flag_stickyopen) { |
|
400 |
+ *click_avail=0; |
|
401 |
+ break; |
|
402 |
+ } |
|
403 |
+ } |
|
404 |
+ return(0); |
|
297 | 405 |
} |
298 | 406 |
|
299 | 407 |
int |
300 |
-imdraw_menus(im_t *im) |
|
408 |
+im_menubar_draw(menubar_t *menubar, font_t *font, int windowwidth, int windowheight) |
|
301 | 409 |
{ |
302 | 410 |
int i,j,k,x; |
303 | 411 |
menudata_t *menudata; |
304 |
- DrawRectangle(0,0,im->w, im->font_height+im->font_height/2, (Color){ 235, 235, 235, 235 } ); |
|
305 |
- for(i=0,x=0;i<im->sizemenudata;i++) { |
|
412 |
+ if(menubar==NULL || font==NULL) |
|
413 |
+ return(-1); /* sanity check failed */ |
|
414 |
+ DrawRectangle(0,0,windowwidth, font->height+font->height/2, (Color){ 235, 235, 235, 235 } ); |
|
415 |
+ for(i=0,x=0;i<menubar->sizemenudata;i++) { |
|
306 | 416 |
Vector2 v2; |
307 |
- menudata=im->menudata[i]; |
|
308 |
- v2=MeasureTextEx(im->font,menudata->title,im->font_height,0); |
|
309 |
- FILLXYWH(menudata->xywh,x,0,((int)v2.x)+im->font_height,im->font_height+im->font_height/2); |
|
310 |
- v2.x=(float) (menudata->xywh.x+im->font_height/2); |
|
311 |
- v2.y=(float) (menudata->xywh.y+im->font_height/4); |
|
312 |
- DrawTextEx(im->font |
|
417 |
+ menudata=menubar->menudata[i]; |
|
418 |
+ v2=MeasureTextEx(font->font,menudata->title,font->height,0); |
|
419 |
+ FILLXYWH(menudata->xywh,x,0,((int)v2.x)+font->height,font->height+font->height/2); |
|
420 |
+ v2.x=(float) (menudata->xywh.x+font->height/2); |
|
421 |
+ v2.y=(float) (menudata->xywh.y+font->height/4); |
|
422 |
+ DrawTextEx(font->font |
|
313 | 423 |
,menudata->title |
314 | 424 |
,v2 |
315 |
- ,im->font_height |
|
425 |
+ ,font->height |
|
316 | 426 |
,0 |
317 | 427 |
,(Color){ 45, 45, 45, 255 } |
318 | 428 |
); |
... | ... |
@@ -321,12 +431,12 @@ imdraw_menus(im_t *im) |
321 | 431 |
int maxw; |
322 | 432 |
DrawRectangle(menudata->xywh.x,menudata->xywh.y+menudata->xywh.h-underline_height,menudata->xywh.w,underline_height, (Color){ 53,132,228,255 } ); |
323 | 433 |
for(j=0,maxw=0;j<menudata->sizeoptions;j++) { |
324 |
- v2=MeasureTextEx(im->font,menudata->options[j],im->font_height,0); |
|
434 |
+ v2=MeasureTextEx(font->font,menudata->options[j],font->height,0); |
|
325 | 435 |
maxw=(((int)(v2.x))>maxw)?((int)(v2.x)):maxw; |
326 | 436 |
} |
327 |
- maxw=(maxw<(menudata->xywh.w+im->font_height))?(menudata->xywh.w+im->font_height):maxw; |
|
328 |
- maxw+=im->font_height; |
|
329 |
- FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(im->font_height+im->font_height/2)*menudata->sizeoptions); |
|
437 |
+ maxw=(maxw<(menudata->xywh.w+font->height))?(menudata->xywh.w+font->height):maxw; |
|
438 |
+ maxw+=font->height; |
|
439 |
+ FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(font->height+font->height/2)*menudata->sizeoptions); |
|
330 | 440 |
DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y-2,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y-2,(Color){ 255,255,255,255 } ); |
331 | 441 |
DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y,menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 255,255,255,255 } ); |
332 | 442 |
DrawLine(menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
... | ... |
@@ -336,13 +446,13 @@ imdraw_menus(im_t *im) |
336 | 446 |
Color c; |
337 | 447 |
c=(k==menudata->currentoption)?((Color){ 255,255,255,255 }):((Color){ 45, 45, 45, 255 }); |
338 | 448 |
if(k==menudata->currentoption) |
339 |
- DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(im->font_height+(im->font_height/2))*k,menudata->optionsxywh.w-2,im->font_height+im->font_height/2,(Color){ 53,132,228,255 }); |
|
340 |
- v2.x=(float) (menudata->optionsxywh.x+im->font_height/2); |
|
341 |
- v2.y=(float) (menudata->optionsxywh.y+(im->font_height/4)+(im->font_height+(im->font_height/2))*k); |
|
342 |
- DrawTextEx(im->font |
|
449 |
+ DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(font->height+(font->height/2))*k,menudata->optionsxywh.w-2,font->height+font->height/2,(Color){ 53,132,228,255 }); |
|
450 |
+ v2.x=(float) (menudata->optionsxywh.x+font->height/2); |
|
451 |
+ v2.y=(float) (menudata->optionsxywh.y+(font->height/4)+(font->height+(font->height/2))*k); |
|
452 |
+ DrawTextEx(font->font |
|
343 | 453 |
,menudata->options[k] |
344 | 454 |
,v2 |
345 |
- ,im->font_height |
|
455 |
+ ,font->height |
|
346 | 456 |
,0 |
347 | 457 |
,c |
348 | 458 |
); |
... | ... |
@@ -352,7 +462,6 @@ imdraw_menus(im_t *im) |
352 | 462 |
} |
353 | 463 |
x=menudata->xywh.x+menudata->xywh.w; |
354 | 464 |
} |
355 |
-#warning TODO |
|
356 | 465 |
return(0); |
357 | 466 |
} |
358 | 467 |
|
... | ... |
@@ -6,6 +6,7 @@ |
6 | 6 |
* History: |
7 | 7 |
* 20250119 Creation. Menu bar. |
8 | 8 |
* 20250123 Load font. |
9 |
+ * 20250213 Support sticky drop-down menus. |
|
9 | 10 |
* |
10 | 11 |
* Author: Dario Rodriguez dario@darionomono.com |
11 | 12 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -114,7 +115,7 @@ main(int argc, char *argv[]) |
114 | 115 |
int insidetitle,currentoption; |
115 | 116 |
insidetitle=is_imutil_insidexywh(mousepos,&(im->menudata[i]->xywh)); |
116 | 117 |
currentoption=menudata_pos2option(im->menudata[i],mousepos); |
117 |
- flag_outsideall=(currentoption!=-1)?0:flag_outsideall; |
|
118 |
+ flag_outsideall=(currentoption!=-1 || insidetitle)?0:flag_outsideall; |
|
118 | 119 |
if(lmbreleased && insidetitle) { |
119 | 120 |
for(j=0;j<im->sizemenudata;j++) { |
120 | 121 |
im->menudata[j]->flag_stickyopen=(j==i)?1:0; |
... | ... |
@@ -127,12 +128,27 @@ main(int argc, char *argv[]) |
127 | 128 |
im->menudata[j]->flag_stickyopen=0; |
128 | 129 |
im->menudata[j]->currentoption=-1; |
129 | 130 |
} |
130 |
- } else if(lmbdown && currentoption!=-1) { |
|
131 |
+ } else if((lmbdown || im->menudata[i]->flag_stickyopen) && currentoption!=-1) { |
|
131 | 132 |
for(j=0;j<im->sizemenudata;j++) { |
132 |
- im->menudata[j]->flag_open=(j==i)?im->menudata[i]->flag_open:0; |
|
133 |
- im->menudata[j]->flag_stickyopen=(j==i)?im->menudata[i]->flag_stickyopen:0; |
|
134 |
- im->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
133 |
+ if(lmbreleased==0 || j!=i || im->menudata[i]->flag_stickyopen==0) { |
|
134 |
+ im->menudata[j]->flag_open=(j==i)?im->menudata[i]->flag_open:0; |
|
135 |
+ im->menudata[j]->flag_stickyopen=(j==i)?im->menudata[i]->flag_stickyopen:0; |
|
136 |
+ im->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
137 |
+ } else { |
|
138 |
+ im->menudata[j]->flag_open=0; |
|
139 |
+ im->menudata[j]->flag_stickyopen=0; |
|
140 |
+ im->menudata[j]->currentoption=-1; |
|
141 |
+#if 1 |
|
142 |
+fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",im->menudata[i]->title,im->menudata[i]->options[currentoption]); |
|
143 |
+#endif |
|
144 |
+ } |
|
135 | 145 |
} |
146 |
+ } else if(im->menudata[i]->flag_stickyopen && currentoption==-1) { |
|
147 |
+ if(lmbreleased) { |
|
148 |
+ im->menudata[i]->flag_open=0; |
|
149 |
+ im->menudata[i]->flag_stickyopen=0; |
|
150 |
+ } |
|
151 |
+ im->menudata[i]->currentoption=-1; |
|
136 | 152 |
} else if(lmbreleased && currentoption!=-1) { |
137 | 153 |
for(j=0;j<im->sizemenudata;j++) { |
138 | 154 |
im->menudata[j]->flag_open=0; |
... | ... |
@@ -145,7 +161,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",im->menudata[i]->title,im->menudata[ |
145 | 161 |
} else if(lmbdown==0) { |
146 | 162 |
im->menudata[i]->flag_open=0; |
147 | 163 |
im->menudata[i]->flag_stickyopen=0; |
148 |
- im->menudata[i]->flag_open=0; |
|
164 |
+ im->menudata[i]->currentoption=-1; |
|
149 | 165 |
} |
150 | 166 |
} |
151 | 167 |
if(flag_outsideall) { |
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,485 @@ |
1 |
+/* |
|
2 |
+ * imgmover.c |
|
3 |
+ * |
|
4 |
+ * Simple C application using raylib to move images between directories. |
|
5 |
+ * |
|
6 |
+ * History: |
|
7 |
+ * 20250119 Creation. Menu bar. |
|
8 |
+ * 20250123 Load font. |
|
9 |
+ * |
|
10 |
+ * Author: Dario Rodriguez dario@darionomono.com |
|
11 |
+ * (c) Dario Rodriguez 2025 |
|
12 |
+ * This program is licensed under the terms of GNU GPL v2.1+ |
|
13 |
+ */ |
|
14 |
+ |
|
15 |
+#include <stdio.h> |
|
16 |
+#include <stdlib.h> |
|
17 |
+#include <unistd.h> |
|
18 |
+#include <string.h> |
|
19 |
+ |
|
20 |
+#include "raylib.h" |
|
21 |
+#include "roboto_regular.c" |
|
22 |
+ |
|
23 |
+#define DEFAULTWIDTH 1280 |
|
24 |
+#define DEFAULTHEIGHT 768 |
|
25 |
+ |
|
26 |
+#ifndef FILLXY |
|
27 |
+#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
|
28 |
+#endif |
|
29 |
+ |
|
30 |
+#ifndef FILLWH |
|
31 |
+#define FILLWH(xywh,valw,valh) (xywh).w=(valw),(xywh).h=(valh) |
|
32 |
+#endif |
|
33 |
+ |
|
34 |
+#ifndef FILLXYWH |
|
35 |
+#define FILLXYWH(xywh,valx,valy,valw,valh) (xywh).x=(valx),(xywh).y=(valy),(xywh).w=(valw),(xywh).h=(valh) |
|
36 |
+#endif |
|
37 |
+ |
|
38 |
+#ifndef UNROLLXYWH |
|
39 |
+#define UNROLLXYWH(xywh) (xywh).x,(xywh).y,(xywh).w,(xywh).h |
|
40 |
+#endif |
|
41 |
+ |
|
42 |
+typedef struct xywh_t { |
|
43 |
+ int x; |
|
44 |
+ int y; |
|
45 |
+ int w; |
|
46 |
+ int h; |
|
47 |
+} xywh_t; |
|
48 |
+ |
|
49 |
+typedef struct menudata_t { |
|
50 |
+ char *title; |
|
51 |
+ xywh_t xywh; |
|
52 |
+ int sizeoptions; |
|
53 |
+ char **options; |
|
54 |
+ xywh_t optionsxywh; |
|
55 |
+ int flag_open; |
|
56 |
+ int flag_stickyopen; |
|
57 |
+ int currentoption; |
|
58 |
+} menudata_t; |
|
59 |
+ |
|
60 |
+typedef struct dirdata_t { |
|
61 |
+ int height; |
|
62 |
+ char *dirname; |
|
63 |
+} dirdata_t; |
|
64 |
+ |
|
65 |
+typedef struct im_t { |
|
66 |
+ int w; |
|
67 |
+ int h; |
|
68 |
+ int sizemenudata; |
|
69 |
+ menudata_t **menudata; |
|
70 |
+ int sizedirdata; |
|
71 |
+ dirdata_t **dirdata; |
|
72 |
+ int currentdirdata; |
|
73 |
+ int leftscrollpos; |
|
74 |
+ int rightscrollpos; |
|
75 |
+ Font font; |
|
76 |
+ int font_height; |
|
77 |
+} im_t; |
|
78 |
+ |
|
79 |
+im_t *im_init(char *menus); |
|
80 |
+void im_free(im_t *im); |
|
81 |
+ |
|
82 |
+int imdraw_menus(im_t *im); |
|
83 |
+ |
|
84 |
+int imutil_menu_count(char *menus); |
|
85 |
+char *imutil_menu_get(char *menus, int targetn, int *len); |
|
86 |
+int imutil_submenu_count(char *menus); |
|
87 |
+char *imutil_submenu_get(char *menus, int targetn, int *len); |
|
88 |
+char *imutil_strduplen(char *str, int len); |
|
89 |
+int is_imutil_insidexywh(Vector2 pos, xywh_t *xywh); |
|
90 |
+int menudata_pos2option(menudata_t *menudata, Vector2 pos); |
|
91 |
+int *getcodepoints(int *sizecodepoints); |
|
92 |
+ |
|
93 |
+int |
|
94 |
+main(int argc, char *argv[]) |
|
95 |
+{ |
|
96 |
+ im_t *im; |
|
97 |
+ Vector2 mousepos; |
|
98 |
+ int flag_ignorelmb; |
|
99 |
+ int i,j; |
|
100 |
+ int lmbpressed,lmbreleased,lmbdown; |
|
101 |
+ int flag_outsideall; |
|
102 |
+ if((im=im_init("Fichero\nAjustes\nSalir\n\nEditar\nNuevo directorio\n\nAyuda\nInformación sobre el programa\n\n"))==NULL) { |
|
103 |
+ return(1); |
|
104 |
+ } |
|
105 |
+ flag_ignorelmb=0; |
|
106 |
+ while(!WindowShouldClose()) { |
|
107 |
+ mousepos=GetMousePosition(); |
|
108 |
+ lmbpressed=IsMouseButtonPressed(0); |
|
109 |
+ lmbreleased=IsMouseButtonReleased(0); |
|
110 |
+ lmbdown=IsMouseButtonDown(0); |
|
111 |
+ /* check if we have to open a menu */ |
|
112 |
+ flag_outsideall=1; |
|
113 |
+ for(i=0;i<im->sizemenudata;i++) { |
|
114 |
+ int insidetitle,currentoption; |
|
115 |
+ insidetitle=is_imutil_insidexywh(mousepos,&(im->menudata[i]->xywh)); |
|
116 |
+ currentoption=menudata_pos2option(im->menudata[i],mousepos); |
|
117 |
+ flag_outsideall=(currentoption!=-1)?0:flag_outsideall; |
|
118 |
+ if(lmbreleased && insidetitle) { |
|
119 |
+ for(j=0;j<im->sizemenudata;j++) { |
|
120 |
+ im->menudata[j]->flag_stickyopen=(j==i)?1:0; |
|
121 |
+ im->menudata[j]->flag_open=0; |
|
122 |
+ im->menudata[j]->currentoption=-1; |
|
123 |
+ } |
|
124 |
+ } else if((lmbpressed || lmbdown) && insidetitle) { |
|
125 |
+ for(j=0;j<im->sizemenudata;j++) { |
|
126 |
+ im->menudata[j]->flag_open=(j==i)?1:0; |
|
127 |
+ im->menudata[j]->flag_stickyopen=0; |
|
128 |
+ im->menudata[j]->currentoption=-1; |
|
129 |
+ } |
|
130 |
+ } else if(lmbdown && currentoption!=-1) { |
|
131 |
+ for(j=0;j<im->sizemenudata;j++) { |
|
132 |
+ im->menudata[j]->flag_open=(j==i)?im->menudata[i]->flag_open:0; |
|
133 |
+ im->menudata[j]->flag_stickyopen=(j==i)?im->menudata[i]->flag_stickyopen:0; |
|
134 |
+ im->menudata[j]->currentoption=(j==i)?currentoption:-1; |
|
135 |
+ } |
|
136 |
+ } else if(lmbreleased && currentoption!=-1) { |
|
137 |
+ for(j=0;j<im->sizemenudata;j++) { |
|
138 |
+ im->menudata[j]->flag_open=0; |
|
139 |
+ im->menudata[j]->flag_stickyopen=0; |
|
140 |
+ im->menudata[j]->currentoption=-1; |
|
141 |
+ } |
|
142 |
+#if 1 |
|
143 |
+fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",im->menudata[i]->title,im->menudata[i]->options[currentoption]); |
|
144 |
+#endif |
|
145 |
+ } else if(lmbdown==0) { |
|
146 |
+ im->menudata[i]->flag_open=0; |
|
147 |
+ im->menudata[i]->flag_stickyopen=0; |
|
148 |
+ im->menudata[i]->flag_open=0; |
|
149 |
+ } |
|
150 |
+ } |
|
151 |
+ if(flag_outsideall) { |
|
152 |
+ for(j=0;j<im->sizemenudata;j++) { |
|
153 |
+ im->menudata[j]->currentoption=-1; |
|
154 |
+ } |
|
155 |
+ } |
|
156 |
+ BeginDrawing(); |
|
157 |
+ ClearBackground(RAYWHITE); |
|
158 |
+ imdraw_menus(im); |
|
159 |
+ EndDrawing(); |
|
160 |
+ } |
|
161 |
+ CloseWindow(); |
|
162 |
+ im_free(im),im=NULL; |
|
163 |
+ return(0); |
|
164 |
+} |
|
165 |
+ |
|
166 |
+im_t * |
|
167 |
+im_init(char *menus) |
|
168 |
+{ |
|
169 |
+ im_t *im; |
|
170 |
+ int i,j; |
|
171 |
+ char *str,*substr; |
|
172 |
+ int len,sublen; |
|
173 |
+ menudata_t *menudata; |
|
174 |
+ if(menus==NULL) |
|
175 |
+ return(NULL); /* sanity check failed */ |
|
176 |
+ if((im=calloc(1,sizeof(im_t)))==NULL |
|
177 |
+ || (im->sizemenudata=imutil_menu_count(menus))<=0 |
|
178 |
+ || (im->menudata=calloc(im->sizemenudata,sizeof(menudata_t)))==NULL |
|
179 |
+ ) { |
|
180 |
+ im_free(im),im=NULL; |
|
181 |
+ return(NULL); /* insuf. mem. */ |
|
182 |
+ } |
|
183 |
+ /* init menus */ |
|
184 |
+ for(i=0;i<im->sizemenudata;i++) { |
|
185 |
+ if((menudata=im->menudata[i]=calloc(1,sizeof(menudata_t)))==NULL |
|
186 |
+ || (str=imutil_menu_get(menus,i,&len))==NULL |
|
187 |
+ || (menudata->title=imutil_strduplen(str,len))==NULL |
|
188 |
+ || (menudata->sizeoptions=imutil_submenu_count(str))<=0 |
|
189 |
+ || (menudata->options=calloc(menudata->sizeoptions,sizeof(char *)))==NULL |
|
190 |
+ ) { |
|
191 |
+ im_free(im),im=NULL; |
|
192 |
+ return(NULL); /* insuf. mem. */ |
|
193 |
+ } |
|
194 |
+ for(j=0;j<menudata->sizeoptions;j++) { |
|
195 |
+ if((substr=imutil_submenu_get(str,j,&sublen))==NULL |
|
196 |
+ || (menudata->options[j]=imutil_strduplen(substr,sublen))==NULL |
|
197 |
+ ) { |
|
198 |
+ im_free(im),im=NULL; |
|
199 |
+ return(NULL); /* insuf. mem. */ |
|
200 |
+ } |
|
201 |
+ } |
|
202 |
+ } |
|
203 |
+ /* init window */ |
|
204 |
+ SetTraceLogLevel(LOG_ERROR); |
|
205 |
+ InitWindow((im->w=DEFAULTWIDTH),(im->h=DEFAULTHEIGHT),"Image Mover"); |
|
206 |
+ SetTargetFPS(30); |
|
207 |
+ /* init font */ |
|
208 |
+ { |
|
209 |
+ int sizecodepoints; |
|
210 |
+ int *codepoints; |
|
211 |
+ im->font_height=18; |
|
212 |
+ codepoints=getcodepoints(&sizecodepoints); |
|
213 |
+ im->font=LoadFontFromMemory(".ttf",(const unsigned char *)roboto_regular,sizeof(roboto_regular)-1,im->font_height,codepoints,sizecodepoints); |
|
214 |
+ } |
|
215 |
+#if 0 |
|
216 |
+ /* test imutil_menu_xxx */ |
|
217 |
+ int n,m,l,ml,len,mlen; |
|
218 |
+ char *ptr,*mptr; |
|
219 |
+ for(n=0,l=imutil_menu_count(menus);n<l;n++) { |
|
220 |
+ ptr=imutil_menu_get(menus,n,&len); |
|
221 |
+ fprintf(stderr,"menu[%i]:\"",n); |
|
222 |
+ fwrite(ptr,1,len,stderr); |
|
223 |
+ fprintf(stderr,"\"->"); |
|
224 |
+ for(m=0,ml=imutil_submenu_count(ptr);m<ml;m++) { |
|
225 |
+ mptr=imutil_submenu_get(ptr,m,&mlen); |
|
226 |
+ fprintf(stderr,"|\""); |
|
227 |
+ fwrite(mptr,1,mlen,stderr); |
|
228 |
+ fprintf(stderr,"\""); |
|
229 |
+ } |
|
230 |
+ fprintf(stderr,"\n"); |
|
231 |
+ } |
|
232 |
+#endif |
|
233 |
+#if 0 |
|
234 |
+ /* test menudata */ |
|
235 |
+ for(i=0;i<im->sizemenudata;i++) { |
|
236 |
+ fprintf(stderr,"menu[%i]:\"%s\"->",i,im->menudata[i]->title); |
|
237 |
+ for(j=0;j<im->menudata[i]->sizeoptions;j++) |
|
238 |
+ fprintf(stderr,"|\"%s\"",im->menudata[i]->options[j]); |
|
239 |
+ fprintf(stderr,"\n"); |
|
240 |
+ } |
|
241 |
+#endif |
|
242 |
+ return(im); |
|
243 |
+} |
|
244 |
+ |
|
245 |
+void |
|
246 |
+im_free(im_t *im) |
|
247 |
+{ |
|
248 |
+ int i,j; |
|
249 |
+ if(im==NULL) |
|
250 |
+ return; |
|
251 |
+ if(im->menudata!=NULL) { |
|
252 |
+ menudata_t *menudata; |
|
253 |
+ for(i=0;i<im->sizemenudata;i++) { |
|
254 |
+ if((menudata=im->menudata[i])==NULL) |
|
255 |
+ continue; |
|
256 |
+ if(menudata->title!=NULL) |
|
257 |
+ free(menudata->title),menudata->title=NULL; |
|
258 |
+ if(menudata->options!=NULL) { |
|
259 |
+ for(j=0;j<menudata->sizeoptions;j++) { |
|
260 |
+ if(menudata->options[j]!=NULL) |
|
261 |
+ free(menudata->options[j]),menudata->options[j]=NULL; |
|
262 |
+ } |
|
263 |
+ free(menudata->options),menudata->options=NULL,menudata->sizeoptions=0; |
|
264 |
+ } |
|
265 |
+ free(im->menudata[i]),im->menudata[i]=NULL,menudata=NULL; |
|
266 |
+ } |
|
267 |
+ free(im->menudata),im->menudata=NULL,im->sizemenudata=0; |
|
268 |
+ } |
|
269 |
+ if(im->dirdata!=NULL) { |
|
270 |
+ dirdata_t *dirdata; |
|
271 |
+ for(i=0;i<im->sizedirdata;i++) { |
|
272 |
+ if((dirdata=im->dirdata[i])==NULL) |
|
273 |
+ continue; |
|
274 |
+ if(dirdata->dirname!=NULL) |
|
275 |
+ free(dirdata->dirname),dirdata->dirname=NULL; |
|
276 |
+ } |
|
277 |
+ free(im->dirdata),im->dirdata=NULL,im->sizedirdata=0; |
|
278 |
+ } |
|
279 |
+ free(im),im=NULL; |
|
280 |
+ return; |
|
281 |
+} |
|
282 |
+ |
|
283 |
+int |
|
284 |
+imdraw_menus(im_t *im) |
|
285 |
+{ |
|
286 |
+ int i,j,k,x; |
|
287 |
+ menudata_t *menudata; |
|
288 |
+ DrawRectangle(0,0,im->w, im->font_height+im->font_height/2, (Color){ 235, 235, 235, 235 } ); |
|
289 |
+ for(i=0,x=0;i<im->sizemenudata;i++) { |
|
290 |
+ Vector2 v2; |
|
291 |
+ menudata=im->menudata[i]; |
|
292 |
+ v2=MeasureTextEx(im->font,menudata->title,im->font_height,0); |
|
293 |
+ FILLXYWH(menudata->xywh,x,0,((int)v2.x)+im->font_height,im->font_height+im->font_height/2); |
|
294 |
+ v2.x=(float) (menudata->xywh.x+im->font_height/2); |
|
295 |
+ v2.y=(float) (menudata->xywh.y+im->font_height/4); |
|
296 |
+ DrawTextEx(im->font |
|
297 |
+ ,menudata->title |
|
298 |
+ ,v2 |
|
299 |
+ ,im->font_height |
|
300 |
+ ,0 |
|
301 |
+ ,(Color){ 45, 45, 45, 255 } |
|
302 |
+ ); |
|
303 |
+ if(menudata->flag_open || menudata->flag_stickyopen) { |
|
304 |
+ int underline_height=3; |
|
305 |
+ int maxw; |
|
306 |
+ DrawRectangle(menudata->xywh.x,menudata->xywh.y+menudata->xywh.h-underline_height,menudata->xywh.w,underline_height, (Color){ 53,132,228,255 } ); |
|
307 |
+ for(j=0,maxw=0;j<menudata->sizeoptions;j++) { |
|
308 |
+ v2=MeasureTextEx(im->font,menudata->options[j],im->font_height,0); |
|
309 |
+ maxw=(((int)(v2.x))>maxw)?((int)(v2.x)):maxw; |
|
310 |
+ } |
|
311 |
+ maxw=(maxw<(menudata->xywh.w+im->font_height))?(menudata->xywh.w+im->font_height):maxw; |
|
312 |
+ maxw+=im->font_height; |
|
313 |
+ FILLXYWH(menudata->optionsxywh,menudata->xywh.x+1,menudata->xywh.y+menudata->xywh.h+2,maxw,(im->font_height+im->font_height/2)*menudata->sizeoptions); |
|
314 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y-2,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y-2,(Color){ 255,255,255,255 } ); |
|
315 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y,menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 255,255,255,255 } ); |
|
316 |
+ DrawLine(menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
317 |
+ DrawLine(menudata->optionsxywh.x-1,menudata->optionsxywh.y+menudata->optionsxywh.h+1,menudata->optionsxywh.x+menudata->optionsxywh.w+2,menudata->optionsxywh.y+menudata->optionsxywh.h+1,(Color){ 192,192,192,255 } ); |
|
318 |
+ DrawRectangle(menudata->optionsxywh.x,menudata->optionsxywh.y,menudata->optionsxywh.w,menudata->optionsxywh.h,(Color){ 235, 235, 235, 235 }); |
|
319 |
+ for(k=0;k<menudata->sizeoptions;k++) { |
|
320 |
+ Color c; |
|
321 |
+ c=(k==menudata->currentoption)?((Color){ 255,255,255,255 }):((Color){ 45, 45, 45, 255 }); |
|
322 |
+ if(k==menudata->currentoption) |
|
323 |
+ DrawRectangle(menudata->optionsxywh.x+1,menudata->optionsxywh.y+(im->font_height+(im->font_height/2))*k,menudata->optionsxywh.w-2,im->font_height+im->font_height/2,(Color){ 53,132,228,255 }); |
|
324 |
+ v2.x=(float) (menudata->optionsxywh.x+im->font_height/2); |
|
325 |
+ v2.y=(float) (menudata->optionsxywh.y+(im->font_height/4)+(im->font_height+(im->font_height/2))*k); |
|
326 |
+ DrawTextEx(im->font |
|
327 |
+ ,menudata->options[k] |
|
328 |
+ ,v2 |
|
329 |
+ ,im->font_height |
|
330 |
+ ,0 |
|
331 |
+ ,c |
|
332 |
+ ); |
|
333 |
+ } |
|
334 |
+ } else { |
|
335 |
+ FILLXYWH(menudata->optionsxywh,0,0,0,0); |
|
336 |
+ } |
|
337 |
+ x=menudata->xywh.x+menudata->xywh.w; |
|
338 |
+ } |
|
339 |
+#warning TODO |
|
340 |
+ return(0); |
|
341 |
+} |
|
342 |
+ |
|
343 |
+int |
|
344 |
+imutil_menu_count(char *menus) |
|
345 |
+{ |
|
346 |
+ int n; |
|
347 |
+ char *ptr,*next; |
|
348 |
+ if(menus==NULL) |
|
349 |
+ return(0); /* sanity check error */ |
|
350 |
+ for(ptr=menus,n=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
351 |
+ if(next[1]=='\n') { |
|
352 |
+ next++; |
|
353 |
+ n++; |
|
354 |
+ } |
|
355 |
+ } |
|
356 |
+ return(n); |
|
357 |
+} |
|
358 |
+ |
|
359 |
+char * |
|
360 |
+imutil_menu_get(char *menus, int targetn, int *len) |
|
361 |
+{ |
|
362 |
+ int n; |
|
363 |
+ char *ptr,*next,*end; |
|
364 |
+ int is_title; |
|
365 |
+ if(len!=NULL) |
|
366 |
+ *len=0; |
|
367 |
+ if(menus==NULL || targetn<0) |
|
368 |
+ return(NULL); /* sanity check error */ |
|
369 |
+ end=menus+strlen(menus); |
|
370 |
+ for(ptr=menus,is_title=1,n=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
371 |
+ if(targetn==n && is_title==1) { |
|
372 |
+ if(len!=NULL) |
|
373 |
+ *len=next-ptr; |
|
374 |
+ return(ptr); /* found, return start of menu string */ |
|
375 |
+ } |
|
376 |
+ is_title=0; |
|
377 |
+ if(next[1]=='\n') { |
|
378 |
+ n++; |
|
379 |
+ next++; |
|
380 |
+ is_title=1; |
|
381 |
+ } |
|
382 |
+ } |
|
383 |
+ return(end); /* not found, return end of menus */ |
|
384 |
+} |
|
385 |
+ |
|
386 |
+int |
|
387 |
+imutil_submenu_count(char *menus) |
|
388 |
+{ |
|
389 |
+ int subn; |
|
390 |
+ char *ptr,*next; |
|
391 |
+ if(menus==NULL) |
|
392 |
+ return(0); /* sanity check error */ |
|
393 |
+ next=strchr(menus,'\n'); |
|
394 |
+ if(next==NULL) |
|
395 |
+ return(0); /* no title */ |
|
396 |
+ for(subn=0,ptr=next+1;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1) { |
|
397 |
+ subn++; |
|
398 |
+ if(next[1]=='\n') |
|
399 |
+ break; |
|
400 |
+ } |
|
401 |
+ return(subn); |
|
402 |
+} |
|
403 |
+ |
|
404 |
+char * |
|
405 |
+imutil_submenu_get(char *menus, int targetsubn, int *len) |
|
406 |
+{ |
|
407 |
+ char *ptr,*next,*end; |
|
408 |
+ int subn; |
|
409 |
+ if(len!=NULL) |
|
410 |
+ *len=0; |
|
411 |
+ if(menus==NULL || targetsubn<0) |
|
412 |
+ return(NULL); /* sanity check error */ |
|
413 |
+ end=menus+strlen(menus); |
|
414 |
+ next=strchr(menus,'\n'); |
|
415 |
+ if(next==NULL) |
|
416 |
+ return(end); /* no title */ |
|
417 |
+ for(ptr=next+1,subn=0;(next=strchr(ptr,'\n'))!=NULL;ptr=next+1,subn++) { |
|
418 |
+ if(targetsubn==subn) { |
|
419 |
+ if(len!=NULL) |
|
420 |
+ *len=next-ptr; |
|
421 |
+ return(ptr); |
|
422 |
+ } |
|
423 |
+ if(next[1]=='\n') |
|
424 |
+ break; /* "\n\n" marks the end of submenus */ |
|
425 |
+ } |
|
426 |
+ return(end); |
|
427 |
+} |
|
428 |
+ |
|
429 |
+char * |
|
430 |
+imutil_strduplen(char *str, int len) |
|
431 |
+{ |
|
432 |
+ char *res; |
|
433 |
+ if(len<0 || (str==NULL && len!=0)) |
|
434 |
+ return(NULL); |
|
435 |
+ if((res=malloc(len+1))==NULL) |
|
436 |
+ return(NULL); |
|
437 |
+ memcpy(res,str,len); |
|
438 |
+ res[len]='\0'; |
|
439 |
+ return(res); |
|
440 |
+} |
|
441 |
+ |
|
442 |
+int |
|
443 |
+is_imutil_insidexywh(Vector2 pos, xywh_t *xywh) |
|
444 |
+{ |
|
445 |
+ if(xywh==NULL) |
|
446 |
+ return(0); /* sanity check error */ |
|
447 |
+ if(pos.x>=(float)(xywh->x) |
|
448 |
+ && pos.x<=(float)(xywh->x+xywh->w) |
|
449 |
+ && pos.y>=(float)(xywh->y) |
|
450 |
+ && pos.y<=(float)(xywh->y+xywh->h) |
|
451 |
+ ) { |
|
452 |
+ return(1); |
|
453 |
+ } |
|
454 |
+ return(0); |
|
455 |
+} |
|
456 |
+ |
|
457 |
+int |
|
458 |
+menudata_pos2option(menudata_t *menudata, Vector2 pos) |
|
459 |
+{ |
|
460 |
+ int n,h; |
|
461 |
+ if(menudata==NULL |
|
462 |
+ || (menudata->flag_open==0 && menudata->flag_stickyopen==0) |
|
463 |
+ || is_imutil_insidexywh(pos, &(menudata->optionsxywh))==0 |
|
464 |
+ ) { |
|
465 |
+ return(-1); |
|
466 |
+ } |
|
467 |
+ h=(menudata->sizeoptions==0)?0:menudata->optionsxywh.h/menudata->sizeoptions; |
|
468 |
+ n=(((int)pos.y)-menudata->optionsxywh.y)/h; |
|
469 |
+ return(n); |
|
470 |
+} |
|
471 |
+ |
|
472 |
+int * |
|
473 |
+getcodepoints(int *sizecodepoints) |
|
474 |
+{ |
|
475 |
+ static int codepoints[]={ |
|
476 |
+/* Basic Latin */ |
|
477 |
+32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, |
|
478 |
+/* Latin-1 Supplement */ |
|
479 |
+160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, |
|
480 |
+}; |
|
481 |
+ if(sizecodepoints!=NULL) |
|
482 |
+ *sizecodepoints=(int) (sizeof(codepoints)/sizeof(codepoints[0])); |
|
483 |
+ return(codepoints); |
|
484 |
+} |
|
485 |
+ |