summaryrefslogtreecommitdiff
path: root/src/gui.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui.c')
-rw-r--r--src/gui.c177
1 files changed, 170 insertions, 7 deletions
diff --git a/src/gui.c b/src/gui.c
index 3340de1..37a48ec 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -31,6 +31,11 @@ static const char ident[]="$Id$";
#include <stdarg.h>
#include <ctype.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
#include "gui.h"
#include "gfx.h"
#include "exit.h"
@@ -56,6 +61,17 @@ static const char ident_h[]=ESPEC_GUI_H;
#define LOGREY GFXRGB(100,100,100)
#define GREEN GFXRGB(100,255,100)
+
+/* ---------------------------------------- TYPES
+*/
+typedef struct
+{
+ char name[MAXPATHLEN+1];
+ unsigned size;
+ int is_dir;
+} FileEnt;
+
+
/* ---------------------------------------- STATICS
*/
@@ -216,6 +232,32 @@ static int DoList(const char *title, int no, char * const list[], int *option)
}
break;
+ case SDLK_PAGEUP:
+ if (cur>0)
+ {
+ cur-=(max-1);
+
+ if (cur<0)
+ cur=0;
+
+ if (cur<top)
+ top=cur;
+ }
+ break;
+
+ case SDLK_PAGEDOWN:
+ if (cur<no-1)
+ {
+ cur+=(max-1);
+
+ if (cur>=no)
+ cur=no-1;
+
+ if (cur>top+max-2)
+ top=cur-max+2;
+ }
+ break;
+
default:
break;
}
@@ -225,6 +267,21 @@ static int DoList(const char *title, int no, char * const list[], int *option)
}
+static int CmpFile(const void *va,const void *vb)
+{
+ const FileEnt *a=(FileEnt *)va;
+ const FileEnt *b=(FileEnt *)vb;
+
+ if ((a->is_dir)&&(!b->is_dir))
+ return -1;
+
+ if ((!a->is_dir)&&(b->is_dir))
+ return 1;
+
+ return strcmp(a->name,b->name);
+}
+
+
/* ---------------------------------------- EXPORTED INTERFACES
*/
int GUIMessage(GUIBoxType type, const char *title, const char *format,...)
@@ -425,14 +482,120 @@ int GUIListOption(const char *title, int no, char * const list[], int option[])
int GUIFileSelect(const char *prompt, int load,
const char *start_dir, char path[])
{
- /* TODO */
- if (load)
- strcpy(path,"/files/emu/spectrum/thrust1.tap");
- else
- strcpy(path,"/files/emu/spectrum/testespec.tap");
+ int done=FALSE;
+ int ret=FALSE;
+ char olddir[MAXPATHLEN+1];
+ char pwd[MAXPATHLEN+1];
+
+ if (!load)
+ {
+ GUIMessage(eMessageBox,"OOPS","Save dialog not yet done");
+ return FALSE;
+ }
+
+ getcwd(olddir,MAXPATHLEN);
+
+ chdir(start_dir);
+
+ while(!done)
+ {
+ int f;
+ int sel;
+ DIR *d;
+ struct dirent *de;
+ struct stat sbuf;
+ FileEnt *fe=NULL;
+ char **list;
+ int no=0;
+
+ getcwd(pwd,MAXPATHLEN);
- /* strcpy(path,"/files/emu/spectrum/testespec.tap"); */
- return TRUE;
+ d=opendir(".");
+
+ while(readdir(d))
+ no++;
+
+ rewinddir(d);
+
+ fe=Malloc(sizeof *fe * no);
+ no=1;
+
+ strcpy(fe[0].name,"..");
+ fe[0].is_dir=TRUE;
+
+ while((de=readdir(d)))
+ {
+ if (stat(de->d_name,&sbuf)!=-1)
+ {
+ if (S_ISDIR(sbuf.st_mode) && de->d_name[0]!='.')
+ {
+ strcpy(fe[no].name,de->d_name);
+ fe[no].is_dir=TRUE;
+ no++;
+ }
+ else if (S_ISREG(sbuf.st_mode) && de->d_name[0]!='.')
+ {
+ strcpy(fe[no].name,de->d_name);
+ fe[no].is_dir=FALSE;
+ fe[no].size=(unsigned)sbuf.st_size;
+ no++;
+ }
+ }
+ }
+
+ closedir(d);
+
+ qsort(fe,no,sizeof *fe,CmpFile);
+
+ list=Malloc(sizeof *list * no);
+
+ for(f=0;f<no;f++)
+ {
+ list[f]=Malloc(80);
+
+ if (fe[f].is_dir)
+ sprintf(list[f],"%-20.20s %9s",fe[f].name,"<DIR>");
+ else
+ sprintf(list[f],"%-20.20s %9u",fe[f].name,fe[f].size);
+ }
+
+ sel=DoList(pwd,no,list,NULL);
+
+ if (sel==-1)
+ {
+ ret=FALSE;
+ done=TRUE;
+ }
+ else
+ {
+ if (fe[sel].is_dir)
+ {
+ chdir(fe[sel].name);
+ }
+ else
+ {
+ strcpy(path,pwd);
+
+ if (path[strlen(path)]!='/')
+ strcat(path,"/");
+
+ strcat(path,fe[sel].name);
+
+ done=TRUE;
+ ret=TRUE;
+ }
+ }
+
+ for(f=0;f<no;f++)
+ {
+ free(list[f]);
+ }
+
+ free(list);
+ free(de);
+ }
+
+ return ret;
}