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

📄 fl_browser.cxx

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 CXX
字号:
//// "$Id: Fl_Browser.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $"//// Browser widget for the Fast Light Tool Kit (FLTK).//// Copyright 1998-1999 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@easysw.com".//#include <FL/Fl.H>#include <FL/Fl_Browser.H>#include <FL/fl_draw.H>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <math.h>// I modified this from the original Forms data to use a linked list// so that the number of items in the browser and size of those items// is unlimited.  The only problem is that the old browser used an// index number to identify a line, and it is slow to convert from/to// a pointer.  I use a cache of the last match to try to speed this// up.// Also added the ability to "hide" a line.  This set's it's height to// zero, so the Fl_Browser_ cannot pick it.#define SELECTED 1#define NOTDISPLAYED 2struct FL_BLINE {	// data is in a linked list of these  FL_BLINE* prev;  FL_BLINE* next;  void* data;  short length;		// sizeof(txt)-1, may be longer than string  char flags;		// selected, displayed  char txt[1];		// start of allocated array};void* Fl_Browser::item_first() const {return first;}void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}int Fl_Browser::item_selected(void* l) const {  return ((FL_BLINE*)l)->flags&SELECTED;}void Fl_Browser::item_select(void* l, int v) {  if (v) ((FL_BLINE*)l)->flags |= SELECTED;  else ((FL_BLINE*)l)->flags &= ~SELECTED;}FL_BLINE* Fl_Browser::find_line(int line) const {  int n; FL_BLINE* l;  if (line == cacheline) return cache;  if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) {    n = cacheline; l = cache;  } else if (line <= (lines/2)) {    n = 1; l = first;  } else {    n = lines; l = last;  }  for (; n < line && l; n++) l = l->next;  for (; n > line && l; n--) l = l->prev;  ((Fl_Browser*)this)->cacheline = line;  ((Fl_Browser*)this)->cache = l;  return l;}int Fl_Browser::lineno(void* v) const {  FL_BLINE* l = (FL_BLINE*)v;  if (!l) return 0;  if (l == cache) return cacheline;  if (l == first) return 1;  if (l == last) return lines;  if (!cache) {    ((Fl_Browser*)this)->cache = first;    ((Fl_Browser*)this)->cacheline = 1;  }  // assumme it is near cache, search both directions:  FL_BLINE* b = cache->prev;  int bnum = cacheline-1;  FL_BLINE* f = cache->next;  int fnum = cacheline+1;  int n = 0;  for (;;) {    if (b == l) {n = bnum; break;}    if (f == l) {n = fnum; break;}    if (b) {b = b->prev; bnum--;}    if (f) {f = f->next; fnum++;}  }  ((Fl_Browser*)this)->cache = l;  ((Fl_Browser*)this)->cacheline = n;  return n;}FL_BLINE* Fl_Browser::_remove(int line) {  FL_BLINE* ttt = find_line(line);  deleting(ttt);  cacheline = line-1;  cache = ttt->prev;  if (ttt->prev) ttt->prev->next = ttt->next;  else first = ttt->next;  if (ttt->next) ttt->next->prev = ttt->prev;  else last = ttt->prev;  lines--;  full_height_ -= item_height(ttt);  return(ttt);}void Fl_Browser::remove(int line) {  if (line < 1 || line > lines) return;  free(_remove(line));}void Fl_Browser::insert(int line, FL_BLINE* t) {  if (!first) {    t->prev = t->next = 0;    first = last = t;  } else if (line <= 1) {    inserting(first, t);    t->prev = 0;    t->next = first;    t->next->prev = t;    first = t;  } else if (line > lines) {    t->prev = last;    t->prev->next = t;    t->next = 0;    last = t;  } else {    FL_BLINE* n = find_line(line);    inserting(n, t);    t->next = n;    t->prev = n->prev;    t->prev->next = t;    n->prev = t;  }  cacheline = line;  cache = t;  lines++;  full_height_ += item_height(t);  redraw_line(t);}void Fl_Browser::insert(int line, const char* newtext, void* data) {  int l = strlen(newtext);  FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);  t->length = l;  t->flags = 0;  strcpy(t->txt, newtext);  t->data = data;  insert(line, t);}void Fl_Browser::move(int to, int from) {  if (from < 1 || from > lines) return;  insert(to, _remove(from));}void Fl_Browser::text(int line, const char* newtext) {  if (line < 1 || line > lines) return;  FL_BLINE* t = find_line(line);  int l = strlen(newtext);  if (l > t->length) {    FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);    replacing(t, n);    cache = n;    n->data = t->data;    n->length = l;    n->flags = t->flags;    n->prev = t->prev;    if (n->prev) n->prev->next = n; else first = n;    n->next = t->next;    if (n->next) n->next->prev = n; else last = n;    free(t);    t = n;  }  strcpy(t->txt, newtext);  redraw_line(t);}void Fl_Browser::data(int line, void* data) {  if (line < 1 || line > lines) return;  find_line(line)->data = data;}int Fl_Browser::item_height(void* lv) const {  FL_BLINE* l = (FL_BLINE*)lv;  if (l->flags & NOTDISPLAYED) return 0;  int hmax = 2; // use 2 to insure we don't return a zero!  if (!l->txt[0]) {    // For blank lines set the height to exactly 1 line!    fl_font(textfont(), textsize());    int h = fl_height();    if (h > hmax) hmax = h;  }  else {    // do each column separately as they may all set different fonts:    for (char* str = l->txt; *str; str++) {      Fl_Font font = textfont(); // default font      int size = textsize(); // default size      while (*str==format_char()) {	str++;	switch (*str++) {	case 'l': case 'L': size = 24; break;	case 'm': case 'M': size = 18; break;	case 's': size = 11; break;	case 'b': font = (Fl_Font)(font|FL_BOLD); break;	case 'i': font = (Fl_Font)(font|FL_ITALIC); break;	case 'f': case 't': font = FL_COURIER; break;	case 'B':	case 'C': strtol(str, &str, 10); break;// skip a color number	case 'F': font = (Fl_Font)strtol(str,&str,10); break;	case 'S': size = strtol(str,&str,10); break;	case 0: case '@': str--;	case '.': goto END_FORMAT;	}      }      END_FORMAT:      char* ptr = str;      for(;*str && (*str!=column_char()); str++) ;      if (ptr < str) {	fl_font(font, size); int h = fl_height();	if (h > hmax) hmax = h;      }      if (!*str) str --;    }  }  return hmax; // previous version returned hmax+2!}int Fl_Browser::item_width(void* v) const {  char* str = ((FL_BLINE*)v)->txt;  const int* i = column_widths();  int w = 0;  while (*i) { // add up all tab-seperated fields    w += *i++;    char* e;    for (e = str; *e && *e != column_char(); e++);    if (!*e) return 0; // last one occupied by text    str = e+1;  }  // OK, we gotta parse the string and find the string width...  int size = textsize();  Fl_Font font = textfont();  int done = 0;  // MRS - might this cause problems on some platforms - order of operations?  while (*str == format_char_ && *++str && *str != format_char_) {    switch (*str++) {    case 'l': case 'L': size = 24; break;    case 'm': case 'M': size = 18; break;    case 's': size = 11; break;    case 'b': font = (Fl_Font)(font|FL_BOLD); break;    case 'i': font = (Fl_Font)(font|FL_ITALIC); break;    case 'f': case 't': font = FL_COURIER; break;    case 'B':    case 'C': strtol(str, &str, 10); break;// skip a color number    case 'F': font = (Fl_Font)strtol(str, &str, 10); break;    case 'S': size = strtol(str, &str, 10); break;    case '.':      done = 1;    case '@':      str--;      done = 1;    }    if (done)      break;  }  fl_font(font, size);  return w + int(fl_width(str)) + 6;}int Fl_Browser::full_height() const {  return full_height_;}int Fl_Browser::incr_height() const {  return textsize()+2;}void Fl_Browser::item_draw(void* v, int x, int y, int w, int h) const {  char* str = ((FL_BLINE*)v)->txt;  const int* i = column_widths();  while (w > 6) {	// do each tab-seperated field    int w1 = w;	// width for this field    char* e = 0; // pointer to end of field or null if none    if (*i) { // find end of field and temporarily replace with 0      for (e = str; *e && *e != column_char(); e++);      if (*e) {*e = 0; w1 = *i++;} else e = 0;    }    int size = textsize();    Fl_Font font = textfont();    Fl_Color lcol = textcolor();    Fl_Align align = FL_ALIGN_LEFT;    // check for all the @-lines recognized by XForms:    while (*str == format_char() && *++str && *str != format_char()) {      switch (*str++) {      case 'l': case 'L': size = 24; break;      case 'm': case 'M': size = 18; break;      case 's': size = 11; break;      case 'b': font = (Fl_Font)(font|FL_BOLD); break;      case 'i': font = (Fl_Font)(font|FL_ITALIC); break;      case 'f': case 't': font = FL_COURIER; break;      case 'c': align = FL_ALIGN_CENTER; break;      case 'r': align = FL_ALIGN_RIGHT; break;      case 'B': 	fl_color((Fl_Color)strtol(str, &str, 10));	fl_rectf(x, y, w1, h);        break;      case 'C':	lcol = (Fl_Color)strtol(str, &str, 10);	break;      case 'F':	font = (Fl_Font)strtol(str, &str, 10);	break;      case 'N':	lcol = FL_INACTIVE_COLOR;	break;      case 'S':	size = strtol(str, &str, 10);	break;      case '-':	fl_color(FL_DARK3);	fl_line(x+3, y+h/2, x+w1-3, y+h/2);	fl_color(FL_LIGHT3);	fl_line(x+3, y+h/2+1, x+w1-3, y+h/2+1);	break;      case 'u':      case '_':	fl_color(lcol);	fl_line(x+3, y+h-1, x+w1-3, y+h-1);	break;      case '.':	goto BREAK;      case '@':	str--; goto BREAK;      }    }  BREAK:    fl_font(font, size);    if (!active_r()) lcol = inactive(lcol);    if (((FL_BLINE*)v)->flags & SELECTED)      lcol = contrast(lcol, selection_color());    fl_color(lcol);    fl_draw(str, x+3, y, w1-6, h, e ? Fl_Align(align|FL_ALIGN_CLIP) : align);    if (!e) break; // no more fields...    *e = column_char(); // put the seperator back    x += w1;    w -= w1;    str = e+1;  }}static const int no_columns[1] = {0};Fl_Browser::Fl_Browser(int x, int y, int w, int h, const char*l)  : Fl_Browser_(x, y, w, h, l) {  column_widths_ = no_columns;  lines = 0;  full_height_ = 0;  cacheline = 0;  format_char_ = '@';  column_char_ = '\t';  first = last = cache = 0;}void Fl_Browser::lineposition(int line, Fl_Line_Position pos) {  if (line<1) line = 1;  if (line>lines) line = lines;  int p = 0;  FL_BLINE* l;  for (l=first; l && line>1; l = l->next) {    line--; p += item_height(l);  }  if (l && (pos == BOTTOM)) p += item_height (l);  int final = p, X, Y, W, H;  bbox(X, Y, W, H);  switch(pos) {    case TOP: break;    case BOTTOM: final -= H; break;    case MIDDLE: final -= H/2; break;  }    if (final > (full_height() - H)) final = full_height() -H;  position(final);}int Fl_Browser::topline() const {  return lineno(top());}void Fl_Browser::clear() {  for (FL_BLINE* l = first; l;) {    FL_BLINE* h = l->next;    free(l);    l = h;  }  full_height_ = 0;  first = 0;  lines = 0;  new_list();}void Fl_Browser::add(const char* newtext, void* data) {  insert(lines+1, newtext, data);  //Fl_Browser_::display(last);}const char* Fl_Browser::text(int line) const {  if (line < 1 || line > lines) return 0;  return find_line(line)->txt;}void* Fl_Browser::data(int line) const {  if (line < 1 || line > lines) return 0;  return find_line(line)->data;}int Fl_Browser::select(int line, int value) {  if (line < 1 || line > lines) return 0;  return Fl_Browser_::select(find_line(line), value);}int Fl_Browser::selected(int line) const {  if (line < 1 || line > lines) return 0;  return find_line(line)->flags & SELECTED;}void Fl_Browser::show(int line) {  FL_BLINE* t = find_line(line);  if (t->flags & NOTDISPLAYED) {    t->flags &= ~NOTDISPLAYED;    full_height_ += item_height(t);    if (Fl_Browser_::displayed(t)) redraw_lines();  }}void Fl_Browser::hide(int line) {  FL_BLINE* t = find_line(line);  if (!(t->flags & NOTDISPLAYED)) {    full_height_ -= item_height(t);    t->flags |= NOTDISPLAYED;    if (Fl_Browser_::displayed(t)) redraw_lines();  }}void Fl_Browser::display(int line, int value) {  if (line < 1 || line > lines) return;  if (value) show(line); else hide(line);}int Fl_Browser::visible(int line) const {  if (line < 1 || line > lines) return 0;  return !(find_line(line)->flags&NOTDISPLAYED);}int Fl_Browser::value() const {  return lineno(selection());}//// End of "$Id: Fl_Browser.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $".//

⌨️ 快捷键说明

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