📄 rfsel.c
字号:
/* fs_flist_putter: * Callback routine for for_each_file() to fill the file selector listbox. */static void fs_flist_putter(AL_CONST char *str, int attrib, int param){ char ext_tokens[32]; char *s, *ext, *tok, *name; char tmp[512], tmp2[32]; int c, c2, i, k, sign; /* attribute flags (rhsda order) * 0 = not required, 1 = must be set, -1 = must be unset */ int attr_flag[5+5] = { 0, -1, -1, 0, 0, FA_RDONLY, FA_HIDDEN, FA_SYSTEM, FA_DIREC, FA_ARCH }; c = usetc(ext_tokens, ' '); c += usetc(ext_tokens+c, ','); c += usetc(ext_tokens+c, ';'); usetc(ext_tokens+c, 0); s = get_filename(str); fix_filename_case(s); if (fext) { ustrcpy(tmp, fext); ustrtok(tmp, ext_tokens); c = (ustrtok(NULL, ext_tokens) ? 1 : 0); if (!c) { if (!ustrchr(fext, '/')) c = 1; } if (c && (!(attrib & FA_DIREC))) { ustrcpy(tmp, fext); ext = get_extension(s); tok = ustrtok(tmp, ext_tokens); while (tok) { if (ustricmp(ext, tok) == 0) break; tok = ustrtok(NULL, ext_tokens); } if (!tok) return; } c = usetc(ext_tokens, ' '); c += usetc(ext_tokens+c, ','); c += usetc(ext_tokens+c, ';'); c += usetc(ext_tokens+c, '/'); usetc(ext_tokens+c, 0); ustrcpy(tmp, fext); tok = ustrchr(tmp, '/'); if (tok) tok = ustrtok(tok, ext_tokens); if (tok) { sign = 1; c = usetc(tmp2, 'r'); c += usetc(tmp2+c, 'h'); c += usetc(tmp2+c, 's'); c += usetc(tmp2+c, 'd'); c += usetc(tmp2+c, 'a'); c += usetc(tmp2+c, '+'); c += usetc(tmp2+c, '-'); usetc(tmp2+c, 0); /* scan the string */ i = 0; while ((c = utolower(ugetat(tok, i)))) { k = 0; while ((c2 = ugetat(tmp2, k))!=0) { if (c == c2) { if (k<5) { attr_flag[k] = sign; break; } else sign = (k==5) ? 1 : -1; } k++; } i++; } } } /* check if file attributes match */ if (!(attr_flag[3+5] & attrib)) { /* if not a directory, we check all attributes except FA_DIREC */ for (c=0; c<5; c++) { if (c == 3) continue; if ((attr_flag[c] == 1) && (!(attrib & attr_flag[c+5]))) return; if ((attr_flag[c] == -1) && (attrib & attr_flag[c+5])) return; } } else { /* if a directory, we check only FA_DIREC */ if (attr_flag[3] == -1) return; } if ((flist->size < FLIST_SIZE) && ((ugetc(s) != '.') || (ugetat(s, 1)))) { name = malloc(ustrsizez(s) + ((attrib & FA_DIREC) ? ucwidth(OTHER_PATH_SEPARATOR) : 0)); if (!name) return; for (c=0; c<flist->size; c++) { if (ugetat(flist->name[c], -1) == OTHER_PATH_SEPARATOR) { if (attrib & FA_DIREC) if (ustrfilecmp(s, flist->name[c]) < 0) break; } else { if (attrib & FA_DIREC) break; if (ustrfilecmp(s, flist->name[c]) < 0) break; } } for (c2=flist->size; c2>c; c2--) flist->name[c2] = flist->name[c2-1]; flist->name[c] = name; ustrcpy(flist->name[c], s); if (attrib & FA_DIREC) put_backslash(flist->name[c]); flist->size++; }}/* fs_flist_getter: * Listbox data getter routine for the file selector list. */static char *fs_flist_getter(int index, int *list_size){ if (index < 0) { if (list_size) *list_size = flist->size; return NULL; } return flist->name[index];}/* fs_flist_proc: * Dialog procedure for the file selector list. */static int fs_flist_proc(int msg, DIALOG *d, int c){ static int recurse_flag = 0; char *s = file_selector[FS_EDIT].dp; char tmp[32]; int sel = d->d1; int i, ret; int ch, count; if (msg == MSG_START) { if (!flist) { flist = malloc(sizeof(FLIST)); if (!flist) { *allegro_errno = ENOMEM; return D_CLOSE; } } else { for (i=0; i<flist->size; i++) if (flist->name[i]) free(flist->name[i]); } flist->size = 0; replace_filename(flist->dir, s, uconvert_ascii("*.*", tmp), sizeof(flist->dir)); for_each_file(flist->dir, FA_RDONLY | FA_DIREC | FA_ARCH | FA_HIDDEN | FA_SYSTEM, fs_flist_putter, 0); if (*allegro_errno) raine_alert("", "Disk error", NULL, NULL, "OK", NULL, 13, 0); usetc(get_filename(flist->dir), 0); d->d1 = d->d2 = 0; sel = 0; } if (msg == MSG_END) { if (flist) { for (i=0; i<flist->size; i++) if (flist->name[i]) free(flist->name[i]); free(flist); flist = NULL; } } recurse_flag++; ret = d_text_list_proc(msg, d, c); /* call the parent procedure */ recurse_flag--; if (((sel != d->d1) || (ret == D_CLOSE)) && (recurse_flag == 0)) { replace_filename(s, flist->dir, flist->name[d->d1], 512); /* check if we want to `cd ..' */ if ((!ustrncmp(flist->name[d->d1], "..", 2)) && (ret == D_CLOSE)) { /* let's remember the previous directory */ ustrcpy(updir, empty_string); i = ustrlen(flist->dir); count = 0; while (i>0) { ch = ugetat(flist->dir, i); if ((ch == '/') || (ch == OTHER_PATH_SEPARATOR)) { if (++count == 2) break; } uinsert(updir, 0, ch); i--; } /* ok, we have the dirname in updir */ } else { ustrcpy(updir, empty_string); } scare_mouse(); SEND_MESSAGE(file_selector+FS_EDIT, MSG_START, 0); SEND_MESSAGE(file_selector+FS_EDIT, MSG_DRAW, 0); unscare_mouse(); if (ret == D_CLOSE) return SEND_MESSAGE(file_selector+FS_EDIT, MSG_KEY, 0); } return ret;}/* stretch_dialog: * Stretch the dialog horizontally and vertically to the specified * size and the font in use. * (all the magic numbers come from the "historical" file selector) */static void stretch_dialog(DIALOG *d, int width, int height){ int font_w, font_h, hpad, vpad; #ifdef HAVE_DIR_LIST /* horizontal settings */ font_w = text_length(font, "a"); if (width == 0) width = 0.95*SCREEN_W + 1; hpad = 0.05*width + 1; d[FS_FRAME].w = width; d[FS_FRAME].x = 0; d[FS_MESSAGE].w = 1; d[FS_MESSAGE].x = width/2; d[FS_EDIT].w = d[FS_FRAME].w - 2*hpad - 1; d[FS_EDIT].x = hpad; d[FS_CANCEL].w = 10*font_w + 1; d[FS_CANCEL].x = d[FS_FRAME].w - hpad - d[FS_CANCEL].w; d[FS_OK].w = d[FS_CANCEL].w; d[FS_OK].x = d[FS_CANCEL].x; d[FS_DISKS].w = d[FS_OK].w; d[FS_DISKS].x = d[FS_OK].x; d[FS_FILES].x = hpad; d[FS_FILES].w = d[FS_CANCEL].x - d[FS_FILES].x - hpad + 1; d[FS_YIELD].x = 0; /* vertical settings */ font_h = text_height(font); if (height == 0) height = 0.80*SCREEN_H + 1; vpad = 0.05*height; d[FS_FRAME].h = height; d[FS_FRAME].y = 0; d[FS_MESSAGE].h = font_h; d[FS_MESSAGE].y = 2; d[FS_EDIT].h = font_h; d[FS_EDIT].y = 2*vpad + d[FS_MESSAGE].h + 4; d[FS_CANCEL].h = font_h + 9; d[FS_CANCEL].y = d[FS_FRAME].h - 2*vpad - d[FS_CANCEL].h + 1; d[FS_OK].h = d[FS_CANCEL].h; d[FS_OK].y = d[FS_CANCEL].y - vpad/2 - d[FS_OK].h - 1; d[FS_DISKS].y = d[FS_EDIT].y + d[FS_EDIT].h + vpad + 2; d[FS_DISKS].h = d[FS_OK].y - d[FS_DISKS].y - vpad - 1; d[FS_FILES].y = d[FS_DISKS].y; d[FS_FILES].h = d[FS_FRAME].h - d[FS_FILES].y - 2*vpad + 1; d[FS_YIELD].y = 0; #else /* horizontal settings */ font_w = text_length(font, "a"); if (width == 0) width = 0.95*SCREEN_W + 1; hpad = 0.05*width + 1; d[FS_FRAME].w = width; d[FS_FRAME].x = 0; d[FS_MESSAGE].w = 1; d[FS_MESSAGE].x = width/2; d[FS_EDIT].w = d[FS_FRAME].w - 2*hpad - 1; d[FS_EDIT].x = hpad; d[FS_FILES].w = d[FS_FRAME].w - 2*hpad; d[FS_FILES].x = hpad; d[FS_OK].w = 10*font_w + 1; d[FS_OK].x = (d[FS_FRAME].w - 2*d[FS_OK].w - hpad + 1)/2; d[FS_CANCEL].w = d[FS_OK].w; d[FS_CANCEL].x = d[FS_FRAME].w - d[FS_OK].x - d[FS_CANCEL].w; d[FS_YIELD].x = 0; /* vertical settings */ font_h = text_height(font); if (height == 0) height = 0.95*SCREEN_H - 1; vpad = 0.04*height + 1; d[FS_FRAME].h = height; d[FS_FRAME].y = 0; d[FS_MESSAGE].h = font_h; d[FS_MESSAGE].y = 2; d[FS_EDIT].h = font_h; d[FS_EDIT].y = 2*vpad + d[FS_MESSAGE].h + 4; d[FS_OK].h = font_h + 9; d[FS_OK].y = d[FS_FRAME].h - 1.5*vpad - d[FS_OK].h; d[FS_CANCEL].h = d[FS_OK].h; d[FS_CANCEL].y = d[FS_OK].y; d[FS_FILES].y = d[FS_EDIT].y + d[FS_EDIT].h + vpad + 2; d[FS_FILES].h = d[FS_OK].y - d[FS_FILES].y - vpad - 6; d[FS_YIELD].y = 0; #endif}int raine_file_select_ex( char *message, char *path, char *ext, int size,int width, int height){ char buf[512]; int ret; char *p; if (width == -1) width = 305; #ifdef HAVE_DIR_LIST if (height == -1) height = 161; #else if (height == -1) height = 189; #endif /* for fs_dlist_proc() */ ASSERT(size >= 4 * uwidth_max(U_CURRENT)); ustrcpy(updir, empty_string); file_selector[FS_MESSAGE].dp = (char *)message; file_selector[FS_EDIT].d1 = size/uwidth_max(U_CURRENT) - 1; file_selector[FS_EDIT].dp = path; file_selector[FS_OK].dp = (void*)raine_get_config_text("OK"); file_selector[FS_CANCEL].dp = (void*)raine_get_config_text("Cancel"); fext = ext; if (!ugetc(path)) { if (!getcwd(buf, sizeof(buf))) buf[0]=0; do_uconvert(buf, U_ASCII, path, U_CURRENT, size); fix_filename_case(path); fix_filename_slashes(path); put_backslash(path); } clear_keybuf(); do { } while (gui_mouse_b()); stretch_dialog(file_selector, width, height); centre_dialog(file_selector); // Stupid correction of the allegro colors... file_selector[FS_FILES].fg = CGUI_COL_TEXT_1; file_selector[FS_FILES].bg = CGUI_BOX_COL_MIDDLE; ret = do_dialog(file_selector, FS_EDIT); if (ret == FS_CANCEL) return FALSE; p = get_extension(path); if ((!ugetc(p)) && (ext) && (!ustrpbrk(ext, uconvert_ascii(" ,;", NULL)))) { p += usetc(p, '.'); ustrcpy(p, ext); } return TRUE; }/* file_select: * Displays the Allegro file selector, with the message as caption. * Allows the user to select a file, and stores the selection in path * (which should have room for at least 80 characters). The files are * filtered according to the file extensions in ext. Passing NULL * includes all files, "PCX;BMP" includes only files with .PCX or .BMP * extensions. Returns zero if it was closed with the Cancel button, * non-zero if it was OK'd. */int raine_file_select(char *message, char *path, char *ext){ #ifdef HAVE_DIR_LIST return raine_file_select_ex(message, path, ext, 512, 305, 161); #else return raine_file_select_ex(message, path, ext, 512, 305, 189); #endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -