requesters: file requester switch directory

a double click on the initial drive list now switches to list the
contents of the selected drive, also removed some unused variables
This commit is contained in:
Wei-ju Wu
2016-01-24 00:26:41 -08:00
parent e6f479fe7e
commit 6abaf6b7ae
2 changed files with 81 additions and 60 deletions
+44 -20
View File
@@ -11,6 +11,7 @@
extern struct Library *DOSBase;
/*
accessing the list of logical volumes is hairy under AmigaOS 1.x - it is
"hidden" in the DosBase structure, and shared among all tasks.
@@ -26,7 +27,7 @@ extern struct Library *DOSBase;
For now, we will omit device typed entries, because writing/reading to them
usually doesn't make too much sense.
*/
struct FileListEntry *scan_dir(const char *dirpath, int *num_entries)
static struct FileListEntry *all_volumes(int *num_entries)
{
struct DosLibrary *dosbase = (struct DosLibrary *) DOSBase;
Forbid();
@@ -57,37 +58,60 @@ struct FileListEntry *scan_dir(const char *dirpath, int *num_entries)
current = BADDR(current->dvi_Next);
}
Permit();
/* scan current directory */
/*
on AmigaOS versions before 36 (essentially all 1.x versions), the
function GetCurrentDirName() does not exist, but it's obtainable
by calling Cli() and querying the returned CommandLineInterface
structure
*/
/*
puts("scanning directory...");
// on AmigaOS 1.x, this function does not exist !!!
GetCurrentDirName(dirname, PATHBUFFER_SIZE);
printf("current dir: '%s'\n", dirname);
flock = Lock(dirname, SHARED_LOCK);
*num_entries = n;
/* The result is an unsorted list, which is usually not what we want.
TODO: sort the list
*/
return result;
}
static struct FileListEntry *dir_contents(const char *dirpath, int *num_entries)
{
struct FileInfoBlock fileinfo;
struct FileListEntry *cur_entry = NULL, *result = NULL, *tmp;
int n = 0;
BPTR flock = Lock(dirpath, SHARED_LOCK);
if (Examine(flock, &fileinfo)) {
while (ExNext(flock, &fileinfo)) {
print_fileinfo(&fileinfo);
tmp = calloc(1, sizeof(struct FileListEntry));
if (fileinfo.fib_DirEntryType < 0) tmp->file_type = FILETYPE_FILE;
else if (fileinfo.fib_DirEntryType > 0) tmp->file_type = FILETYPE_DIR;
else tmp->file_type = FILETYPE_VOLUME;
tmp->index = n;
strncpy(tmp->name, fileinfo.fib_FileName, MAX_FILENAME_LEN);
if (!cur_entry) result = cur_entry = tmp;
else {
cur_entry->next = tmp;
tmp->prev = cur_entry;
cur_entry = tmp;
}
n++;
}
error = IoErr();
LONG error = IoErr();
if (error != ERROR_NO_MORE_ENTRIES) {
puts("unknown I/O error, TODO handle");
}
}
UnLock(flock);
*/
/* The result is an unsorted list, which is usually not what we want.
TODO: sort the list
*/
*num_entries = n;
return result;
}
/*
scan current directory
on AmigaOS versions before 36 (essentially all 1.x versions), the
function GetCurrentDirName() does not exist, but it's obtainable
by calling Cli() and querying the returned CommandLineInterface
structure
*/
struct FileListEntry *scan_dir(const char *dirpath, int *num_entries)
{
if (!dirpath) return all_volumes(num_entries);
return dir_contents(dirpath, num_entries);
}
void free_file_list(struct FileListEntry *entries)
{
struct FileListEntry *cur = entries, *next;
+37 -40
View File
@@ -41,7 +41,6 @@ static int filelist_bm_width;
static int filelist_bm_height;
static struct FileListEntry *current_files;
static int num_current_files;
static int select_index = 1;
static int slider_increment;
/*
@@ -225,23 +224,8 @@ static int filelist_bm_depth = 1;
static struct BitMap filelist_bitmap;
static struct RastPort filelist_rastport;
#define PATHBUFFER_SIZE 200
static char dirname[PATHBUFFER_SIZE + 1];
static BPTR flock;
static LONG error;
static struct FileInfoBlock fileinfo;
static UWORD font_baseline, font_height;
static void print_fileinfo(struct FileInfoBlock *fileinfo)
{
if (fileinfo->fib_DirEntryType > 0) {
printf("dir: '%s'\n", fileinfo->fib_FileName);
} else {
printf("file: '%s'\n", fileinfo->fib_FileName);
}
}
static void close_requester()
{
if (req_opened) {
@@ -350,8 +334,6 @@ static void draw_list()
cur = cur->next;
count++;
}
// Done drawing, offscreen bitmap is rendered, copy to the requester's layer
render_list_backbuffer();
}
@@ -379,6 +361,38 @@ static void update_string_gadgets(struct FileListEntry *entry)
RefreshGList(&dir_text, req_window, &requester, 1);
}
static void reload_file_list(const char *dirpath)
{
int num_files;
struct FileListEntry *dir_entries = scan_dir(dirpath, &num_files);
if (current_files) free_file_list(current_files);
current_files = dir_entries;
num_current_files = num_files;
first_visible_entry = current_files;
clear_list();
draw_list();
// set the length of the slider thumb according to the current file list
int vertbody = MAXBODY;
int vertpot = MAXBODY;
if (num_current_files > NUM_FILE_ENTRIES) {
// because we can only use integer division, so we have to determine
// the body size by solving the equation
// MAXBODY / vertbody = num_current_files / NUM_FILE_ENTRIES
vertbody = (MAXBODY * NUM_FILE_ENTRIES) / num_current_files;
// this is surprisingly different that I thought:
// we need to compute the increment over the drag space not over
// the vslider space, so we can ignore the VertBody setting (in short
// VertPot and VertBody are independent)
slider_increment = MAXBODY / (num_current_files - NUM_FILE_ENTRIES);
vertpot = first_visible_entry->index * slider_increment;
printf("vpot: %d, vbody: %d inc: %d\n", vertpot, vertbody, slider_increment);
}
NewModifyProp(&list_vslider, req_window, &requester, AUTOKNOB | FREEVERT,
0, vertpot, MAXBODY, vertbody, 1);
}
static void handle_events()
{
BOOL done = FALSE;
@@ -442,6 +456,9 @@ static void handle_events()
update_string_gadgets(entry);
} else if (entry != NULL && is_doubleclick) {
printf("double click on: %s\n", entry->name);
if (entry->file_type == FILETYPE_VOLUME || entry->file_type == FILETYPE_DIR) {
reload_file_list(entry->name);
}
}
}
ReplyMsg((struct Message *) msg);
@@ -591,30 +608,10 @@ void open_file(struct Window *window)
filelist_rastport.BitMap = &filelist_bitmap;
if (req_opened = Request(&requester, req_window)) {
current_files = scan_dir(NULL, &num_current_files);
first_visible_entry = current_files;
// set the length of the slider thumb according to the current file list
int vertbody = MAXBODY;
int vertpot = MAXBODY;
if (num_current_files > NUM_FILE_ENTRIES) {
// because we can only use integer division, so we have to determine
// the body size by solving the equation
// MAXBODY / vertbody = num_current_files / NUM_FILE_ENTRIES
vertbody = (MAXBODY * NUM_FILE_ENTRIES) / num_current_files;
// this is surprisingly different that I thought:
// we need to compute the increment over the drag space not over
// the vslider space, so we can ignore the VertBody setting (in short
// VertPot and VertBody are independent)
slider_increment = MAXBODY / (num_current_files - NUM_FILE_ENTRIES);
vertpot = first_visible_entry->index * slider_increment;
printf("vpot: %d, vbody: %d inc: %d\n", vertpot, vertbody, slider_increment);
}
NewModifyProp(&list_vslider, req_window, &requester, AUTOKNOB | FREEVERT,
0, vertpot, MAXBODY, vertbody, 1);
draw_list();
reload_file_list(NULL);
handle_events();
free_file_list(current_files);
current_files = first_visible_entry = NULL;
CloseWindow(req_window);
req_window = NULL;
} else {