Browse code

Able to list files

Dario Rodriguez authored on 22/02/2025 16:22:20
Showing 1 changed files
... ...
@@ -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
+