--- hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:11:38 1.1 +++ hatari/src/gui-sdl/dlgFileSelect.c 2019/04/01 07:12:22 1.1.1.2 @@ -6,7 +6,7 @@ A file selection dialog for the graphical user interface for Hatari. */ -char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1 2019/04/01 07:11:38 root Exp $"; +char DlgFileSelect_rcsid[] = "Hatari $Id: dlgFileSelect.c,v 1.1.1.2 2019/04/01 07:12:22 root Exp $"; #include #include @@ -14,12 +14,14 @@ char DlgFileSelect_rcsid[] = "Hatari $Id #include #include "main.h" -#include "screen.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 @@ -38,7 +40,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[] = @@ -77,14 +79,17 @@ static SGOBJ fsdlg[] = }; +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,7 +101,7 @@ static int DlgFileSelect_RefreshEntries( } /* Copy entries to dialog: */ - for(i=0; i<16; i++) + for(i=0; i 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) +{ + 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; refreshentries = TRUE; break; + case SDLK_END: ypos = entries-SGFS_NUMENTRIES; refreshentries = TRUE; break; + case SDLK_PAGEUP: + if (ypos > SGFS_NUMENTRIES) + ypos -= SGFS_NUMENTRIES; + else + ypos = 0; + refreshentries = TRUE; + break; + case SDLK_PAGEDOWN: + if (ypos+2*SGFS_NUMENTRIES < entries) + ypos += SGFS_NUMENTRIES; + else + ypos = entries-SGFS_NUMENTRIES; + refreshentries = TRUE; + break; + default: break; + } + break; + } +} + + +/*-----------------------------------------------------------------------*/ +/* Show and process a file selection dialog. Returns TRUE if the use selected "okay", FALSE if "cancel". input: zip_path = pointer to buffer to contain file path within a selected @@ -142,13 +217,10 @@ static int DlgFileSelect_RefreshEntries( int SDLGui_FileSelect(char *path_and_name, char *zip_path, BOOL bAllowNew) { int i,n; - int entries = 0; /* How many files are in the actual directory? */ - int ypos = 0; struct dirent **files = NULL; char *pStringMem; char *path, *fname; /* The actual file and path names */ BOOL reloaddir = TRUE; /* Do we have to reload the directory file list? */ - BOOL refreshentries = TRUE; /* Do we have to update the file names in the dialog? */ int retbut; int oldcursorstate; int selection = -1; /* The actual selection, -1 if none selected */ @@ -156,6 +228,12 @@ int SDLGui_FileSelect(char *path_and_nam char *zipdir; BOOL browsingzip = FALSE; /* Are we browsing an archive? */ zip_dir *zipfiles = NULL; + SDL_Event sdlEvent; + struct stat filestat; + + ypos = 0; + refreshentries = TRUE; + entries = 0; /* Allocate memory for the file and path name strings: */ pStringMem = malloc(4 * FILENAME_MAX); @@ -179,7 +257,14 @@ int SDLGui_FileSelect(char *path_and_nam } /* Prepare the path and filename variables */ + if (stat(path_and_name, &filestat) == 0 && S_ISDIR(filestat.st_mode)) + { + /* assure that a directory name ends with a '/' */ + File_AddSlashToEndFileName(path_and_name); + } File_splitpath(path_and_name, path, fname, NULL); + File_MakeAbsoluteName(path); + File_MakeValidPathName(path); File_ShrinkName(dlgpath, path, DLGPATH_SIZE); File_ShrinkName(dlgfname, fname, DLGFNAME_SIZE); @@ -234,7 +319,7 @@ int SDLGui_FileSelect(char *path_and_nam /* Update the file name strings in the dialog? */ if (refreshentries) { - if (!DlgFileSelect_RefreshEntries(files, path, browsingzip, entries, ypos)) + if (!DlgFileSelect_RefreshEntries(files, path, browsingzip)) { free(pStringMem); return FALSE; @@ -243,13 +328,12 @@ int SDLGui_FileSelect(char *path_and_nam } /* Show dialog: */ - retbut = SDLGui_DoDialog(fsdlg); + retbut = SDLGui_DoDialog(fsdlg, &sdlEvent); /* Has the user clicked on a file or folder? */ if( retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos0 ) - { - --ypos; - refreshentries = TRUE; - } - SDL_Delay(20); + DlgFileSelect_ScrollUp(); + SDL_Delay(10); break; case SGFSDLG_DOWN: /* Scroll down */ - if( ypos+17<=entries ) - { - ++ypos; - refreshentries = TRUE; - } - SDL_Delay(20); + DlgFileSelect_ScrollDown(); + SDL_Delay(10); break; case SGFSDLG_FILENAME: /* User entered new filename */ strcpy(fname, dlgfname); break; + case SDLGUI_UNKNOWNEVENT: + DlgFileSelect_HandleSdlEvents(&sdlEvent); + break; } /* switch */ } /* other button code */ } /* do */ - - - while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL && !bQuitProgram); + while (retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL && retbut!=SDLGUI_QUIT && !bQuitProgram); if (oldcursorstate == SDL_DISABLE) SDL_ShowCursor(SDL_DISABLE);