--- hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:11:38 1.1.1.1 +++ hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:14:59 1.1.1.5 @@ -6,29 +6,33 @@ A file selection dialog for the graphical user interface for Hatari. */ -char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.1 2019/04/01 07:11:38 root Exp $"; +const char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.5 2019/04/01 07:14:59 root Exp $"; #include #include #include -#include #include "main.h" -#include "screen.h" +#include "scandir.h" #include "sdlgui.h" #include "file.h" #include "zip.h" +#define SGFS_NUMENTRIES 16 /* How many entries are displayed at once */ + + #define SGFSDLG_FILENAME 5 #define SGFSDLG_UPDIR 6 -#define SGFSDLG_ROOTDIR 7 -#define SGFSDLG_ENTRY1 10 -#define SGFSDLG_ENTRY16 25 -#define SGFSDLG_UP 26 -#define SGFSDLG_DOWN 27 -#define SGFSDLG_OKAY 28 -#define SGFSDLG_CANCEL 29 +#define SGFSDLG_HOMEDIR 7 +#define SGFSDLG_ROOTDIR 8 +#define SGFSDLG_ENTRY1 11 +#define SGFSDLG_ENTRY16 26 +#define SGFSDLG_UP 27 +#define SGFSDLG_DOWN 28 +#define SGFSDLG_SHOWHIDDEN 29 +#define SGFSDLG_OKAY 30 +#define SGFSDLG_CANCEL 31 #define DLGPATH_SIZE 62 @@ -38,7 +42,7 @@ static char dlgpath[DLGPATH_SIZE+1]; static char dlgfname[DLGFNAME_SIZE+1]; /* Name of the selected file in the dialog */ #define DLGFILENAMES_SIZE 59 -static char dlgfilenames[16][DLGFILENAMES_SIZE+1]; /* Visible file names in the dialog */ +static char dlgfilenames[SGFS_NUMENTRIES][DLGFILENAMES_SIZE+1]; /* Visible file names in the dialog */ /* The dialog data: */ static SGOBJ fsdlg[] = @@ -49,7 +53,8 @@ static SGOBJ fsdlg[] = { SGTEXT, 0, 0, 1,3, DLGPATH_SIZE,1, dlgpath }, { SGTEXT, 0, 0, 1,4, 6,1, "File:" }, { SGTEXT, 0, 0, 7,4, DLGFNAME_SIZE,1, dlgfname }, - { SGBUTTON, 0, 0, 55,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 51,1, 4,1, ".." }, + { SGBUTTON, 0, 0, 56,1, 3,1, "~" }, { SGBUTTON, 0, 0, 60,1, 3,1, "/" }, { SGBOX, 0, 0, 1,6, 62,16, NULL }, { SGBOX, 0, 0, 62,7, 1,14, NULL }, @@ -71,20 +76,24 @@ static SGOBJ fsdlg[] = { SGTEXT, SG_EXIT, 0, 2,21, DLGFILENAMES_SIZE,1, dlgfilenames[15] }, { SGBUTTON, SG_TOUCHEXIT, 0, 62,6, 1,1, "\x01" }, /* Arrow up */ { SGBUTTON, SG_TOUCHEXIT, 0, 62,21, 1,1, "\x02" }, /* Arrow down */ - { SGBUTTON, 0, 0, 14,23, 8,1, "Okay" }, - { SGBUTTON, 0, 0, 34,23, 8,1, "Cancel" }, + { SGCHECKBOX, SG_EXIT, 0, 2,23, 18,1, "Show hidden files" }, + { SGBUTTON, SG_DEFAULT, 0, 32,23, 8,1, "Okay" }, + { SGBUTTON, SG_CANCEL, 0, 50,23, 8,1, "Cancel" }, { -1, 0, 0, 0,0, 0,0, NULL } }; +static int ypos; /* First entry number to be displayed */ +static bool refreshentries; /* Do we have to update the file names in the dialog? */ +static int entries; /* How many files are in the actual directory? */ + /*-----------------------------------------------------------------------*/ /* Update the file name strings in the dialog. Returns FALSE if it failed, TRUE on success. */ -static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, - BOOL browsingzip, int entries, int ypos) +static int DlgFileSelect_RefreshEntries(struct dirent **files, char *path, bool browsingzip) { int i; char *tempstr = malloc(FILENAME_MAX); @@ -96,9 +105,9 @@ static int DlgFileSelect_RefreshEntries( } /* Copy entries to dialog: */ - for(i=0; i<16; i++) + for (i=0; id_name); - if( browsingzip ) + if (browsingzip) { - if( tempstr[strlen(tempstr)-1] == '/' ) + if (File_DoesFileNameEndWithSlash(tempstr)) dlgfilenames[i][0] = SGFOLDER; /* Mark folders */ } else @@ -133,38 +142,221 @@ static int DlgFileSelect_RefreshEntries( /*-----------------------------------------------------------------------*/ /* + Remove all hidden files (files with file names that begin with a dot) from + the list. +*/ +static void DlgFileSelect_RemoveHiddenFiles(struct dirent **files) +{ + int i; + int nActPos = -1; + int nOldEntries; + + nOldEntries = entries; + + /* Scan list for hidden files and remove them. */ + for (i = 0; i < nOldEntries; i++) + { + /* Does file name start with a dot? -> hidden file! */ + if (files[i]->d_name[0] == '.') + { + if (nActPos == -1) + nActPos = i; + /* Remove file from list: */ + free(files[i]); + files[i] = NULL; + entries -= 1; + } + } + + /* Now close the gaps in the list: */ + if (nActPos != -1) + { + for (i = nActPos; i < nOldEntries; i++) + { + if (files[i] != NULL) + { + /* Move entry to earlier position: */ + files[nActPos] = files[i]; + files[i] = NULL; + nActPos += 1; + } + } + } +} + + +/*-----------------------------------------------------------------------*/ +/* + Prepare to scroll up one entry. +*/ +static void DlgFileSelect_ScrollUp(void) +{ + if (ypos > 0) + { + --ypos; + refreshentries = TRUE; + } +} + + +/*-----------------------------------------------------------------------*/ +/* + Prepare to scroll down one entry. +*/ +static void DlgFileSelect_ScrollDown(void) +{ + if (ypos+SGFS_NUMENTRIES < entries) + { + ++ypos; + refreshentries = TRUE; + } +} + + +/*-----------------------------------------------------------------------*/ +/* + Handle SDL events. +*/ +static void DlgFileSelect_HandleSdlEvents(SDL_Event *pEvent) +{ + int oldypos = ypos; + switch (pEvent->type) + { + case SDL_MOUSEBUTTONDOWN: + if (pEvent->button.button == SDL_BUTTON_WHEELUP) + DlgFileSelect_ScrollUp(); + else if (pEvent->button.button == SDL_BUTTON_WHEELDOWN) + DlgFileSelect_ScrollDown(); + break; + case SDL_KEYDOWN: + switch (pEvent->key.keysym.sym) + { + case SDLK_UP: DlgFileSelect_ScrollUp(); break; + case SDLK_DOWN: DlgFileSelect_ScrollDown(); break; + case SDLK_HOME: ypos = 0; break; + case SDLK_END: ypos = entries-SGFS_NUMENTRIES; break; + case SDLK_PAGEUP: ypos -= SGFS_NUMENTRIES; break; + case SDLK_PAGEDOWN: + if (ypos+2*SGFS_NUMENTRIES < entries) + ypos += SGFS_NUMENTRIES; + else + ypos = entries-SGFS_NUMENTRIES; + break; + default: + break; + } + break; + default: + break; + } + if (ypos < 0) + ypos = 0; + if (ypos != oldypos) + refreshentries = TRUE; +} + + +/*-----------------------------------------------------------------------*/ +/* + Free file entries +*/ +static struct dirent **files_free(struct dirent **files) +{ + int i; + if (files != NULL) + { + for(i=0; i= FILENAME_MAX) - { - fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n"); - free(pStringMem); - return FALSE; - } - - /* Free old allocated memory: */ - if (files != NULL) - { - for(i=0; i