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

📄 fl_input_.cxx

📁 SRI international 发布的OAA框架软件
💻 CXX
📖 第 1 页 / 共 2 页
字号:
	newmark = line_end(newmark);
      } else {
	newpos = word_start(newpos);
	newmark = word_end(newmark);
      }
    }
    // if the multiple click does not increase the selection, revert
    // to single-click behavior:
    if (!drag && (mark() > position() ?
                  (newmark >= position() && newpos <= mark()) :
                  (newmark >= mark() && newpos <= position()))) {
      Fl::event_clicks(0);
      newmark = newpos = l-value();
    }
  }
  position(newpos, newmark);
}

int Fl_Input_::position(int p, int m) {
  was_up_down = 0;
  if (p<0) p = 0;
  if (p>size()) p = size();
  if (m<0) m = 0;
  if (m>size()) m = size();
  if (p == position_ && m == mark_) return 0;
  //if (Fl::selection_owner() == this) Fl::selection_owner(0);
  if (p != m) {
    if (p != position_) minimal_update(position_, p);
    if (m != mark_) minimal_update(mark_, m);
  } else {
    // new position is a cursor
    if (position_ == mark_) {
      // old position was just a cursor
      if (Fl::focus() == this && !(damage()&FL_DAMAGE_EXPOSE)) {
	minimal_update(position_); erase_cursor_only = 1;
      }
    } else { // old position was a selection
      minimal_update(position_, mark_);
    }
  }
  position_ = p;
  mark_ = m;
  return 1;
}

int Fl_Input_::up_down_position(int i, int keepmark) {
  // unlike before, i must be at the start of the line already!

  setfont();
  char buf[MAXBUF];
  const char* p = value()+i;
  const char* e = expand(p, buf);
  const char *l, *r, *t;
  for (l = p, r = e; l<r; ) {
    t = l+(r-l+1)/2;
    int f = (int)expandpos(p, t, buf, 0);
    if (f <= up_down_pos) l = t; else r = t-1;
  }
  int j = l-value();
  j = position(j, keepmark ? mark_ : j);
  was_up_down = 1;
  return j;
}

int Fl_Input_::copy(int clipboard) {
  int b = position();
  int e = mark();
  if (b != e) {
    if (b > e) {b = mark(); e = position();}
    if (input_type() == FL_SECRET_INPUT) e = b;
    Fl::copy(value()+b, e-b, clipboard);
    return 1;
  }
  return 0;
}

#define MAXFLOATSIZE 40

static char* undobuffer;
static int undobufferlength;
static Fl_Input_* undowidget;
static int undoat;	// points after insertion
static int undocut;	// number of characters deleted there
static int undoinsert;	// number of characters inserted
static int yankcut;	// length of valid contents of buffer, even if undocut=0

static void undobuffersize(int n) {
  if (n > undobufferlength) {
    if (undobuffer) {
      do {undobufferlength *= 2;} while (undobufferlength < n);
      undobuffer = (char*)realloc(undobuffer, undobufferlength);
    } else {
      undobufferlength = n+9;
      undobuffer = (char*)malloc(undobufferlength);
    }
  }
}

// all changes go through here, delete characters b-e and insert text:
int Fl_Input_::replace(int b, int e, const char* text, int ilen) {

  was_up_down = 0;

  if (b<0) b = 0;
  if (e<0) e = 0;
  if (b>size_) b = size_;
  if (e>size_) e = size_;
  if (e<b) {int t=b; b=e; e=t;}
  if (text && !ilen) ilen = strlen(text);
  if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
  if (size_+ilen-(e-b) > maximum_size_) {
    ilen = maximum_size_-size_+(e-b);
    if (ilen < 0) ilen = 0;
  }

  put_in_buffer(size_+ilen);

  if (e>b) {
    if (undowidget == this && b == undoat) {
      undobuffersize(undocut+(e-b));
      memcpy(undobuffer+undocut, value_+b, e-b);
      undocut += e-b;
    } else if (undowidget == this && e == undoat && !undoinsert) {
      undobuffersize(undocut+(e-b));
      memmove(undobuffer+(e-b), undobuffer, undocut);
      memcpy(undobuffer, value_+b, e-b);
      undocut += e-b;
    } else if (undowidget == this && e == undoat && (e-b)<undoinsert) {
      undoinsert -= e-b;
    } else {
      undobuffersize(e-b);
      memcpy(undobuffer, value_+b, e-b);
      undocut = e-b;
      undoinsert = 0;
    }
    memmove(buffer+b, buffer+e, size_-e+1);
    size_ -= e-b;
    undowidget = this;
    undoat = b;
    if (input_type() == FL_SECRET_INPUT) yankcut = 0; else yankcut = undocut;
  }

  if (ilen) {
    if (undowidget == this && b == undoat)
      undoinsert += ilen;
    else {
      undocut = 0;
      undoinsert = ilen;
    }
    memmove(buffer+b+ilen, buffer+b, size_-b+1);
    memcpy(buffer+b, text, ilen);
    size_ += ilen;
  }
  undowidget = this;
  undoat = b+ilen;

  // Insertions into the word at the end of the line will cause it to
  // wrap to the next line, so we must indicate that the changes may start
  // right after the whitespace before the current word.  This will
  // result in sub-optimal update when such wrapping does not happen
  // but it is too hard to figure out for now...
  if (wrap())
    while (b > 0 && !isspace(index(b))) b--;

  // make sure we redraw the old selection or cursor:
  if (mark_ < b) b = mark_;
  if (position_ < b) b = position_;

  minimal_update(b);

  mark_ = position_ = undoat;

  if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
  return 1;
}

int Fl_Input_::undo() {
  was_up_down = 0;
  if (undowidget != this || !undocut && !undoinsert) return 0;

  int ilen = undocut;
  int xlen = undoinsert;
  int b = undoat-xlen;
  int b1 = b;

  put_in_buffer(size_+ilen);

  if (ilen) {
    memmove(buffer+b+ilen, buffer+b, size_-b+1);
    memcpy(buffer+b, undobuffer, ilen);
    size_ += ilen;
    b += ilen;
  }

  if (xlen) {
    undobuffersize(xlen);
    memcpy(undobuffer, buffer+b, xlen);
    memmove(buffer+b, buffer+b+xlen, size_-xlen-b+1);
    size_ -= xlen;
  }

  undocut = xlen;
  if (xlen) yankcut = xlen;
  undoinsert = ilen;
  undoat = b;
  mark_ = b /* -ilen */;
  position_ = b;

  minimal_update(b1);
  if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
  return 1;
}

int Fl_Input_::copy_cuts() {
  // put the yank buffer into the X clipboard
  if (!yankcut || input_type()==FL_SECRET_INPUT) return 0;
  Fl::copy(undobuffer, yankcut, 1);
  return 1;
}

void Fl_Input_::maybe_do_callback() {
  if (changed() || (when()&FL_WHEN_NOT_CHANGED)) {
    clear_changed(); do_callback();}
}

int Fl_Input_::handletext(int event, int X, int Y, int W, int H) {
  switch (event) {

  case FL_ENTER:
    if (active_r()) window()->cursor(FL_CURSOR_INSERT);
    return 1;

  case FL_LEAVE:
    if (active_r()) window()->cursor(FL_CURSOR_DEFAULT);
    return 1;

  case FL_FOCUS:
    if (mark_ == position_) {
      minimal_update(size()+1);
    } else //if (Fl::selection_owner() != this)
      minimal_update(mark_, position_);
    return 1;

  case FL_UNFOCUS:
    if (mark_ == position_) {
      if (!(damage()&FL_DAMAGE_EXPOSE)) {minimal_update(position_); erase_cursor_only = 1;}
    } else //if (Fl::selection_owner() != this)
      minimal_update(mark_, position_);
  case FL_HIDE:
    if (when() & FL_WHEN_RELEASE) maybe_do_callback();
    return 1;

  case FL_PUSH:
    handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT));

    if (Fl::focus() != this) {
      Fl::focus(this);
      handle(FL_FOCUS);
    }
    return 1;

  case FL_DRAG:
    handle_mouse(X, Y, W, H, 1);
    return 1;

  case FL_RELEASE:
    copy(0);
    return 1;

  case FL_PASTE: {
    // Don't allow pastes into readonly widgets...
    if (readonly()) {
      fl_beep(FL_BEEP_ERROR);
      return 1;
    }

    // See if we have anything to paste...
    if (!Fl::event_text() || !Fl::event_length()) return 1;

    // strip trailing control characters and spaces before pasting:
    const char* t = Fl::event_text();
    const char* e = t+Fl::event_length();
    if (input_type() != FL_MULTILINE_INPUT) while (e > t && isspace(*(e-1))) e--;
    if (!t || e <= t) return 1; // Int/float stuff will crash without this test
    if (input_type() == FL_INT_INPUT) {
      while (isspace(*t) && t < e) t ++;
      const char *p = t;
      if (*p == '+' || *p == '-') p ++;
      if (strncmp(p, "0x", 2) == 0) {
        p += 2;
        while (isxdigit(*p) && p < e) p ++;
      } else {
        while (isdigit(*p) && p < e) p ++;
      }
      if (p < e) {
        fl_beep(FL_BEEP_ERROR);
        return 1;
      } else return replace(0, size(), t, e - t);
    } else if (input_type() == FL_FLOAT_INPUT) {
      while (isspace(*t) && t < e) t ++;
      const char *p = t;
      if (*p == '+' || *p == '-') p ++;
      while (isdigit(*p) && p < e) p ++;
      if (*p == '.') {
        p ++;
        while (isdigit(*p) && p < e) p ++;
	if (*p == 'e' || *p == 'E') {
	  p ++;
	  if (*p == '+' || *p == '-') p ++;
	  while (isdigit(*p) && p < e) p ++;
	}
      }
      if (p < e) {
        fl_beep(FL_BEEP_ERROR);
        return 1;
      } else return replace(0, size(), t, e - t);
    }
    return replace(position(), mark(), t, e-t);}

  default:
    return 0;
  }
}

/*------------------------------*/

Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l)
: Fl_Widget(X, Y, W, H, l) {
  box(FL_DOWN_BOX);
  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
  align(FL_ALIGN_LEFT);
  textsize_ = (uchar)FL_NORMAL_SIZE;
  textfont_ = FL_HELVETICA;
  textcolor_ = FL_FOREGROUND_COLOR;
  cursor_color_ = FL_FOREGROUND_COLOR; // was FL_BLUE
  mark_ = position_ = size_ = 0;
  bufsize = 0;
  buffer  = 0;
  value_ = "";
  xscroll_ = yscroll_ = 0;
  maximum_size_ = 32767;
}

void Fl_Input_::put_in_buffer(int len) {
  if (value_ == buffer && bufsize > len) {
    buffer[size_] = 0;
    return;
  }
  if (!bufsize) {
    if (len > size_) len += 9; // let a few characters insert before realloc
    bufsize = len+1; 
    buffer = (char*)malloc(bufsize);
  } else if (bufsize <= len) {
    // we may need to move old value in case it points into buffer:
    int moveit = (value_ >= buffer && value_ < buffer+bufsize);
    // enlarge current buffer
    if (len > size_) {
      do {bufsize *= 2;} while (bufsize <= len);
    } else {
      bufsize = len+1;
    }
    char* nbuffer = (char*)realloc(buffer, bufsize);
    if (moveit) value_ += (nbuffer-buffer);
    buffer = nbuffer;
  }
  memmove(buffer, value_, size_); buffer[size_] = 0;
  value_ = buffer;
}

int Fl_Input_::static_value(const char* str, int len) {
  clear_changed();
  if (undowidget == this) undowidget = 0;
  if (str == value_ && len == size_) return 0;
  if (len) { // non-empty new value:
    if (xscroll_ || yscroll_) {
      xscroll_ = yscroll_ = 0;
      minimal_update(0);
    } else {
      int i = 0;
      // find first different character:
      if (value_) {
	for (; i<size_ && i<len && str[i]==value_[i]; i++);
	if (i==size_ && i==len) return 0;
      }
      minimal_update(i);
    }
    value_ = str;
    size_ = len;
  } else { // empty new value:
    if (!size_) return 0; // both old and new are empty.
    size_ = 0;
    value_ = "";
    xscroll_ = yscroll_ = 0;
    minimal_update(0);
  }
  position(0, readonly() ? 0 : size());
  return 1;
}

int Fl_Input_::static_value(const char* str) {
  return static_value(str, str ? strlen(str) : 0);
}

int Fl_Input_::value(const char* str, int len) {
  int r = static_value(str, len);
  if (len) put_in_buffer(len);
  return r;
}

int Fl_Input_::value(const char* str) {
  return value(str, str ? strlen(str) : 0);
}

void Fl_Input_::resize(int X, int Y, int W, int H) {
  if (W != w()) xscroll_ = 0;
  if (H != h()) yscroll_ = 0;
  Fl_Widget::resize(X, Y, W, H);
}

Fl_Input_::~Fl_Input_() {
  if (undowidget == this) undowidget = 0;
  if (bufsize) free((void*)buffer);
}

//
// End of "$Id: Fl_Input_.cxx,v 1.1.1.1 2003/06/03 22:25:42 agno Exp $".
//

⌨️ 快捷键说明

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