📄 my_fl_file_chooser.cxx
字号:
// search again for an exact match: for (q = list; ; q++) { if (q >= last) {q = 0; break;} if (item_height(*q, 0)==0) continue; any = 1; const char* a = (*q)->d_name; const char* b = buf+bufdirend;#if defined(WIN32) && !defined(__CYGWIN__) while (*b && tolower(*a)==tolower(*b)) {a++; b++;}#else while (*b && *a==*b) {a++; b++;}#endif if (!*b && (*a==0 || /* *a=='/' ||*/ *a==1)) break; } new_list(); } if (any) message = 0; else if (!message) message = "No matching files"; select_only(q); if (q) current_callback(buf);}void FCB::draw() { if (!message) { Fl_Browser_::draw(); if (full_height() > 0) return; message = "No matching files"; } Fl_Boxtype b = box(); if (!b) b = FL_DOWN_BOX; draw_box(b,color()); fl_color(FL_INACTIVE_COLOR); fl_font(FNTTP, FNTSZ); fl_draw(message, x()+7, y()+3, w(), h()-3, FL_ALIGN_TOP_LEFT); // insure scrollbars are redrawn if error message goes away: scrollbar.redraw(); hscrollbar.redraw();}void FCB::clear_prev() { if (prev) { for (dirent**p=prev_last-1; p>=prev; p--) free((void*)*p); free((void*)prev); prev = prev_last = 0; }}void FCB::clear() { if (list) { for (dirent**p=last-1; p>=list; p--) free((void*)*p); free((void*)list); list = last = 0; } clear_prev(); listed[0] = 0; dirend = 1;}////////////////////////////////////////////////////////////////static void fcb_cb(Fl_Widget*, void* v) { FCW* w = (FCW*)v; char buf[FL_PATH_MAX]; if (w->browser.get(buf)) { w->input.value(buf); w->input.position(10000);// w->input.position(10000, w->browser.dirend); if (Fl::event_button()==1) { if (Fl::event_clicks()) w->ok_button->do_callback(); else w->browser.set(buf); } else { current_callback(buf); } }}static void tab_cb(Fl_Widget*, void* v) { FCW* w = (FCW*)v; char buf[FL_PATH_MAX]; if (w->browser.get(buf)) { w->input.value(buf); w->input.position(10000); w->browser.set(buf); }}#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)// ':' needs very special handling!static inline int isdirsep(char c) {return c=='/' || c=='\\';}#else#define isdirsep(c) ((c)=='/')#endifstatic void input_cb(Fl_Widget*, void* v) { FCW* w = (FCW*)v; const char* buf = w->input.value(); char localbuf[FL_PATH_MAX]; if (buf[0] && isdirsep(buf[w->input.size()-1]) && filename_expand(localbuf, buf)) { buf = localbuf; w->input.value(localbuf); w->input.position(10000); } w->browser.set(buf);}static void up_cb(Fl_Widget*, void* v) { // the .. button FCW* w = (FCW*)v; char* p; char* newname; char buf[FL_PATH_MAX]; p = w->browser.listed+w->browser.dirend-1; // point right before last '/' if (p < w->browser.listed) newname = "../"; // go up from current directory else { for (; p>w->browser.listed; p--) if (isdirsep(*(p-1))) break; if (isdirsep(*p) || *p=='.' && (isdirsep(p[1]) || p[1]=='.' && isdirsep(p[2]))) { p = w->browser.listed+w->browser.dirend; memcpy(buf, w->browser.listed, p-w->browser.listed); strcpy(buf+(p-w->browser.listed), "../"); } else { memcpy(buf, w->browser.listed, p-w->browser.listed); buf[p-w->browser.listed] = 0; } newname = buf; } w->input.value(newname); w->input.position(10000); w->browser.set(newname);}static void dir_cb(Fl_Widget* obj, void* v) { // directory buttons FCW* w = (FCW*)v; const char* p = obj->label(); if (*p=='&') p++; char buf[FL_PATH_MAX]; char* q; for (q=buf; *p && *p!=' '; *q++ = *p++); *q = 0; filename_expand(buf, buf); w->input.value(buf); w->input.position(10000); w->browser.set(buf);}static void working_cb(Fl_Widget*, void* v) { // directory buttons FCW*w = (FCW*)v; char buf[FL_PATH_MAX]; filename_absolute(buf, ""); w->input.value(buf); w->input.position(10000); w->browser.set(buf);}static void files_cb(Fl_Widget* obj, void* v) { // file pattern buttons FCW* w = (FCW*)v; char buf[FL_PATH_MAX]; strcpy(buf, w->input.value()); char* q = buf+w->browser.dirend; if (obj != w->normal_button) { // tack on first word of label const char* p = obj->label(); if (*p=='&') p++; for (; *p && *p!=' '; *q++ = *p++); } *q = 0; w->input.value(buf); w->input.position(10000, w->browser.dirend); w->browser.set(buf);}/*----------------------- The Main Routine ----------------------*/#define HEIGHT_BOX (4*WIDTH_SPC+HEIGHT_BUT+HEIGHT_INPUT+HEIGHT_BROWSER)//#define HEIGHT_BUT 23#define HEIGHT_BUT 18#define HEIGHT_INPUT 23//#define HEIGHT_BROWSER (9*HEIGHT_BUT+2) // must be > buttons*HEIGHT_BUT#define HEIGHT_BROWSER (8*HEIGHT_BUT+2) // must be > buttons*HEIGHT_BUT#define WIDTH_BOX (3*WIDTH_SPC+WIDTH_BUT+WIDTH_BROWSER)//#define WIDTH_BROWSER 350#define WIDTH_BROWSER 90//#define WIDTH_BUT 125#define WIDTH_BUT 60//#define WIDTH_OK 60#define WIDTH_OK 40#define WIDTH_SPC 5int FCW::handle(int event) { if (Fl_Window::handle(event)) return 1; if (event==FL_KEYBOARD && Fl::event_key()==FL_Tab) { tab_cb(this, this); return 1; } return 0;}// set this to make extra directory-jumping button:const char* fl_file_chooser_button;extern const char* fl_ok;extern const char* fl_cancel;FCW::FCW() : Fl_Window(WIDTH_BOX, HEIGHT_BOX), input(WIDTH_SPC, HEIGHT_BOX-HEIGHT_BUT-2*WIDTH_SPC-HEIGHT_INPUT, WIDTH_BOX-2*WIDTH_SPC, HEIGHT_INPUT, 0), browser(2*WIDTH_SPC+WIDTH_BUT, WIDTH_SPC, WIDTH_BROWSER, HEIGHT_BROWSER){ int but_y = WIDTH_SPC; input.callback(input_cb, this); input.when(FL_WHEN_CHANGED); input.textfont(FNTTP); input.textsize(FNTSZ); // add(browser); browser.callback(fcb_cb, this); begin(); Fl_Widget* obj; obj = ok_button = new Fl_Return_Button( WIDTH_BOX-2*(WIDTH_SPC+WIDTH_OK), HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT, WIDTH_OK, HEIGHT_BUT, fl_ok); obj = cancel_button = new Fl_Button( WIDTH_BOX-WIDTH_SPC-WIDTH_OK, HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT, WIDTH_OK, HEIGHT_BUT, fl_cancel); cancel_button->shortcut("^["); obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "&Up 1 dir"); obj->callback(up_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&~/ Home"); obj->callback(dir_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&/ Root"); obj->callback(dir_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj=new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&Cur dir"); obj->callback(working_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); if (fl_file_chooser_button) { obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT,fl_file_chooser_button); obj->callback(dir_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); } normal_button = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, ""); normal_button->callback(files_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj = new Fl_Button(WIDTH_SPC,but_y, WIDTH_BUT, HEIGHT_BUT, "* &All fls"); obj->callback(files_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, ". &Hid fls"); obj->callback(files_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "*/ &Dirs"); obj->callback(files_cb, this); but_y += HEIGHT_BUT; obj->labelfont(FNTTP); obj->labelsize(FNTSZ); resizable(new Fl_Box(browser.x(), but_y, ok_button->x()-browser.x(), browser.y()+browser.h()-but_y)); // add(input); // put last for better draw() speed end(); set_modal();}char* my_fl_file_chooser(const char* message, const char* pat, const char* fname){ static FCW* f; if (!f) f = new FCW(); f->ok_button->label(fl_ok); f->cancel_button->label(fl_cancel); f->ok_button->labelfont(FNTTP); f->ok_button->labelsize(FNTSZ); f->cancel_button->labelfont(FNTTP); f->cancel_button->labelsize(FNTSZ); if (pat && !*pat) pat = 0; if (fname && *fname) { f->input.value(fname); } else if (f->browser.pattern != pat && (!pat || !f->browser.pattern || strcmp(pat,f->browser.pattern))) { // if pattern is different, remove name but leave old directory: const char* p = f->input.value(); const char* q = filename_name(p); f->input.value(p, q-p); } f->browser.pattern = pat; f->normal_button->label(pat ? pat : "visible files"); f->browser.set(f->input.value()); f->input.position(10000, f->browser.dirend); f->label(message); f->hotspot(f); f->show(); int ok = 0; for (;;) { Fl::wait(); Fl_Widget* o = Fl::readqueue(); if (o == f->ok_button) {ok = 1; break;} else if (o == f->cancel_button || o == f) break; } f->hide(); f->browser.clear(); if (!ok) return 0; const char* r = f->input.value(); const char* p; for (p=r+f->browser.dirend; *p; p++) if (*p=='*' || *p=='?' || *p=='[' || *p=='{') return 0; return (char*)r;}//// End of "$Id: my_fl_file_chooser.cxx,v 1.1 2001/06/07 21:30:00 agenda Beta $".//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -