mirror of
https://github.com/weiju/amiga-stuff
synced 2026-09-11 19:26:01 +00:00
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:
+44
-20
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user