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