⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 my_fl_file_chooser.cxx

📁 一个小的非常好用的电子书阅读器源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
//// "$Id: my_fl_file_chooser.cxx,v 1.1 2001/06/07 21:30:00 agenda Beta $"//// File chooser widget for the Fast Light Tool Kit (FLTK).//// Copyright 1998-2000 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@fltk.org".//#include "myconfig.h"#include "my_fl_file_chooser.H"#include <FL/Fl.H>#include <FL/Fl_Window.H>#include <FL/Fl_Box.H>#include <FL/Fl_Button.H>#include <FL/Fl_Return_Button.H>#include <FL/Fl_Browser_.H>#include <FL/Fl_Input.H>#include <FL/fl_draw.H>#include <FL/filename.H>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>/* Set the font type and size globally */#define FNTSZ 10#define FNTTP FL_HELVETICAstatic void default_callback(const char*) {}static void (*current_callback)(const char*) = default_callback;void fl_file_chooser_callback(void (*cb)(const char*)) {  current_callback = cb ? cb : default_callback;}// "File Chooser Browser" widget:class FCB : public Fl_Browser_ {  void* item_first() const ;  void* item_next(void*) const ;  void* item_prev(void*) const ;  int item_height(const dirent*, int) const ;  int item_height(void*) const ;  int item_width(const dirent*) const ;  int item_width(void*) const ;  int item_quick_height(void*) const ;  int incr_height() const ;  void item_draw(void*, int, int, int, int) const ;  int checkdir(const dirent*, char*) const ;  void draw();  void clear_prev();public:  char listed[FL_PATH_MAX];// current dir & starname  int dirend;		// points after last / before starname  int nameend;		// length to trailing '*' or '\0'  const char* pattern;	// default pattern  dirent** list;	// the file names  dirent** last;	// pointer after end of list  const char* message;	// message if no file names  char preved[FL_PATH_MAX];// directory listed in prev  dirent** prev;	// cached list of another directory  dirent** prev_last;	// end of that list  int prev_count;  FCB(int x, int y, int w, int h) : Fl_Browser_(x, y, w, h, 0) {    type(FL_HOLD_BROWSER);    listed[0] = 0;    dirend = nameend = 1;    pattern = 0;    list = prev = 0;    message = 0;  }  // ~FCB nyi  void clear();  void set(const char*);  int get(char*);};// "File Chooser Window" widget:class FCW : public Fl_Window {public:  int handle(int);  Fl_Input input;  Fl_Button* ok_button;  Fl_Button* cancel_button;  Fl_Button* normal_button;  FCB browser;  FCW();};/* Files are marked as being directories by replacing the trailing null   with a '/' if it is a directory, a '\001' if it is *not* a directory.   An item has height (and is thus selectable) if it is either a directory   or if it matches the pattern.  Quick-height assummes all unknown files   are directories, and thus saves the time needed to do a stat().*/// return pointer to last character:static const char* end_of_name(const dirent* d) {#if HAVE_DIRENT_H  const char* e;  for (e = d->d_name; ;e++) switch (*e) {  case 0: case 1: case '/': return e;  }#else  // warning: clobbers byte after end of name  return d->d_name + d->d_namelen;#endif}// return true if item is directory, when given pointer to last character:int FCB::checkdir(const dirent* d, char* e) const {  if (*e == 1) return 0;  if (*e == '/') return 1;  char buf[FL_PATH_MAX];  memcpy(buf, listed, dirend);  memcpy(buf+dirend, d->d_name, e-d->d_name);  *(buf+dirend+(e-d->d_name)) = 0;  if (filename_isdir(buf)) {    *e = '/'; return 1;  } else {    *e = 1; return 0;  }}void* FCB::item_first() const {return list;}void* FCB::item_next(void* p) const {  if ((dirent**)p+1 >= last) return 0;  return (dirent**)p+1;}void* FCB::item_prev(void* p) const {  if ((dirent**)p <= list) return 0;  return ((dirent**)p)-1;}#ifdef _MSC_VER#pragma optimize("a",off) // without this it does not change *e#endifstatic int ido_matching(const dirent* p, const char* e, const char* n) {  // replace / or 1 at end with 0 and do match, then put back.  yukko  int save = *e; *(char*)e = 0;  int r = filename_match(p->d_name, n);  *(char*)e = save;  return(r);}#ifdef _MSC_VER#pragma optimize("",on)#endifint FCB::incr_height() const {return FNTSZ+2;}int FCB::item_height(const dirent* p, int slow) const {  const char* e = end_of_name(p);  if (listed[dirend]) {//  if (p->d_name[0]=='.' && listed[dirend]!='.') return 0;    if (listed[nameend-1]=='/') {      if (slow ? !checkdir(p, (char*)e) : *e==1) return 0;      ((char*)listed)[nameend-1] = 0;      int r = ido_matching(p, e, listed+dirend);      ((char*)listed)[nameend-1] = '/';      if (!r) return 0;    } else {      if (!ido_matching(p, e, listed+dirend)) return 0;    }  } else {    if (p->d_name[0]=='.') return 0;    if (pattern && (slow ? !checkdir(p, (char*)e) : *e==1) &&	!ido_matching(p, e, pattern)) return 0;  }  return FNTSZ+2;}int FCB::item_height(void* x) const {  return item_height(*(const dirent**)x, 1);}int FCB::item_quick_height(void* x) const {  return item_height(*(const dirent**)x, 0);}void FCB::item_draw(void* v, int x, int y, int, int h) const {  const dirent* p = *(const dirent**)v;  const char* e = end_of_name(p);  if (checkdir(p, (char*)e)) e++;  if (v == selection()) fl_color(contrast(textcolor(), selection_color()));  else fl_color(textcolor());  fl_font(FNTTP, FNTSZ);  fl_draw(p->d_name, e-p->d_name, x+4, y+h-3);}int FCB::item_width(const dirent* p) const {  const char* e = end_of_name(p); if (*e == '/') e++;  fl_font(FNTTP, FNTSZ);  return (int)fl_width(p->d_name, e-p->d_name)+4;}int FCB::item_width(void* x) const {  return item_width(*(const dirent**)x);}// "get" the current value by copying the name of the selected file// or if none are selected, by copying as many common letters as// possible of the matched file list:int FCB::get(char* buf) {  dirent** q = (dirent**)selection(); // the file to copy from  int n = 0;	// number of letters  if (q) {	// a file is selected    const char* e = end_of_name(*q);    n = e - (*q)->d_name;    if (*e == '/') n++;  } else {	// do filename completion    for (q = list; q < last && !item_height(*q, 0); q++);    if (q < last) {      const char* e = end_of_name(*q);      n = e - (*q)->d_name;      if (*e == '/') n++;      for (dirent** r = q+1; n && r < last; r++) {	if (!item_height(*r, 0)) continue;	int i;#ifdef _WIN32	for (i=0; i<n && tolower((*q)->d_name[i])==tolower((*r)->d_name[i]); i++) {}#else	for (i=0; i<n && (*q)->d_name[i]==(*r)->d_name[i]; i++) {}#endif	n = i;      }    }  }  if (n) {    memcpy(buf, listed, dirend);    memcpy(buf+dirend, (*q)->d_name, n);    buf[dirend+n]=0;  }  return n;}// "set" the current value by changing the directory being listed and// changing the highlighted item, if possible:void FCB::set(const char* buf) {  int bufdirend;  int ispattern = 0;  const char* c = buf;  for (bufdirend=0; *c;) switch(*c++) {  case '?': case '[': case '*': case '{': ispattern = 1; goto BREAK;#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)  case '\\':#endif  case '/': bufdirend=c-buf; break;  }#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__)  if ((!bufdirend) && isalpha(buf[0]) && (buf[1]==':')) bufdirend = 2;#endif BREAK:  int bufend = strlen(buf);  if (bufend<=bufdirend) ispattern = 1;  // if directory is different, change list to xxx/ :  if (bufdirend != dirend || strncmp(buf, listed, bufdirend)) {    if (prev &&	preved[bufdirend]==0 && !strncmp(buf, preved, bufdirend)) {      strcpy(preved, listed); preved[dirend] = 0;      dirent** t;      t = prev; prev = list; list = t;      t = prev_last; prev_last = last; last = t;      strcpy(listed, buf);      dirend = nameend = bufdirend;      message = 0;    } else {      if (list) {	clear_prev();	strcpy(preved, listed); preved[dirend]=0;	prev = list;	prev_last = last;      }      list = last = 0;      message = "reading..."; redraw(); Fl::flush(); redraw();      strcpy(listed, buf);      dirend = nameend = bufdirend;      listed[dirend] = listed[dirend+1] = 0;      int n = filename_list(dirend ? listed : ".", &list);      if (n < 0) {	if (errno==ENOENT) message = "No such directory";	else message = strerror(errno);	n = 0; list = 0;      } else message = 0;      last = list+n;    }    if (list && last <= list+2) message = "Empty directory";    new_list();  }  dirent** q = 0; // will point to future selection  int any = 0; // true if any names shown  // do we match one item in the previous list?  if (!ispattern && bufend >= nameend) {    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;    }  }  // no, change the list pattern to the new text + a star:  if (!q) {    strcpy(listed+dirend, buf+bufdirend);    nameend = bufend;    if (!ispattern) {listed[nameend]='*'; listed[nameend+1]=0;}    any = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -