Browse code

Draw pane titles and main dir list

Dario Rodriguez authored on 23/02/2025 21:01:31
Showing 1 changed files
... ...
@@ -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);