...
|
...
|
@@ -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;
|