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

📄 editor.c

📁 SEAL是DOS 下的32位保护模式的GUI程序
💻 C
📖 第 1 页 / 共 4 页
字号:
{

  l_rect sizey = size;
  l_long lines = 0;

  l_long tsize = o->line_num;

  while ( sizey > 0 && line >= 0 && line < tsize ) {

      sizey -= o->ysize_of_line(o, line, 1, NULL);

      line += plus;

      lines++;

  };

  if ( sizey < 0 ) lines--;

  return lmax(0, lines);

};


t_rect  editor_get_cursor_rect ( p_editor o, l_long line, l_long pos )
{
  p_view  vo = VIEW(o);

  t_rect  r = o->line_rect(o, line);
  t_rect  safe;

  l_long  len;
  l_text  text  = o->lntxtlen(o, line, &len); /* get text from line "line"
                                                 and pos "pos" + len will
                                                 contains length of this
                                                 line */
  l_rect rcpos = FONT_GETSTRWIDTH(vo->font, text, lmax(0, lmin(len, pos)));
  l_rect ecpos = FONT_GETSTRWIDTH(vo->font, text, lmax(0, lmin(len, pos+1)));

  if ( ecpos == rcpos ) ecpos = rcpos+FONT_GETWIDTH(vo->font, ' ');

  r = rect_assign(lmax(r.a.x, r.a.x+rcpos), r.a.y, lmin(r.b.x, r.a.x+ecpos), r.b.y);

  return r;

};


/*

  draw cursor to current line and current pos and redraw all cursor

  at line (oldline) and pos (oldpos)

*/
void  editor_draw_cursor ( p_editor o, l_long oldline, l_long oldpos )
{

  l_long  len;
  l_text  text     = o->lntxtlen(o, o->line, &len); /* get text from line "line"
                                                       and pos "pos" + len will
                                                       contains length of this
                                                       line */

  l_long  oldlen;
  l_text  oldtext  = o->lntxtlen(o, oldline, &oldlen); /* get text from line "line"
                                                          and pos "pos" + len will
                                                          contains length of this
                                                          line */

  if ( !ed_is_wable(o) ) /* is not-rewrite able */

     return;

  if ( oldpos >= 0 && oldpos <= oldlen )

    o->draw_cursor_ex ( o, oldline, oldpos, 0);


  if ( o->cursor_visible )

    o->draw_cursor_ex ( o, o->line, o->line_pos, 1);

};


void  editor_show_cursor ( p_editor o, l_bool show )
{
  o->cursor_visible = show;

  o->draw_cursor(o, o->line, o->line_pos);
};


/*
  - return num of lines that may be visible in page that start from

    line (line)
*/

l_int  editor_lines_inpage ( p_editor o )
{
  l_int  ln = 0;
  t_rect r = o->line_rect(o, o->line_from);

  while ( !rect_check_empty(r) )

    r = o->line_rect(o, o->line_from+(ln++));


  return ln;
};


/*
  draw only selected lines

  dst - new selected lines
  src - old selected lines
*/

void   editor_draw_select ( p_editor o, t_rect dst, t_rect src )
{
  l_long start = o->line_from;
  l_int  ln    = o->lines_inpage(o);
  l_int  i = 0;

  while ( i < ln ) {

    l_long p = -1;

      if ( src.a.y < o->line_from+i && src.b.y > o->line_from+i &&
           dst.a.y < o->line_from+i && dst.b.y > o->line_from+i )

           ;

      else {

            if ( o->line_from+i >= src.a.y && o->line_from+i <= src.b.y )

                  o->draw_line(o, o->line_from+i);
            else
                  if ( o->line_from+i >= dst.a.y && o->line_from+i <= dst.b.y )

                       o->draw_line(o, o->line_from+i);
      };

      i++;
  };

};


/*
 - return rect of line (line)
*/

t_rect  editor_line_rect ( p_editor o, l_long line )
{
  t_rect t = rect_empty;
  p_scroller sc = SCROLLER(o);
  t_rect s = VIEW(o)->size_limits(VIEW(o));

  if ( line <= o->line_num && line >= o->line_from ) {

    l_long  f = 0;
    l_long  h = o->ysize_of_line(o, line, 1, &f);

    if ( f || h ) t = rect_assign(s.a.x, s.a.y+f-sc->scrolly, s.b.x, s.a.y+h+f-sc->scrolly-1);


  };

  return rect_cliped(t, s);

};



/*
 - set new text to editor and release memory of old one,
 - redraw editor box and scrollbars
*/

l_bool  editor_set_text ( p_editor o, l_text txt )
{

  ed_sel_clear(o);

  _free(o->text); /* release memory of old text */

  if ( txt )

     o->text = strdup(txt);

  else {

     o->text = strdup("");

  };

  o->line_num = o->lnmax(o, &(o->line_longest)); /* get number of lines */
  o->line_from = o->line = o->line_pos_from = o->line_pos = 0;
  o->line_ptr = o->text;

  reset_scroller(o);

  o->draw_box(o);

  set_notedited(o);

  draw_scroller_bars(SCROLLER(o)); /* redraw scroll bars */

  return true;

};


/*
  set line to real (line) and pos to real (pos)

  it means it bounds line and pos
*/

void  editor_realpos ( p_editor o, l_long *line, l_long *pos )
{
  l_long len;
  l_text text;

  if ( !line || !pos ) return;

  text = o->lntxtlen(o, (*line), &len);

  if ( !text || (*line) > o->line_num ) { /* this line is out of range */

     if ( *line > 0 ) {

         (*line) = o->line_num;

         o->lntxtlen(o, (*line), pos);

     } else {

         (*line) = 0;
         (*pos) = 0;

     };

     return;

  };

  if ( (*pos) < 0 && (*line) > 0 ) {

    (*line)--;

    text = o->lntxtlen(o, (*line), &len);

    (*pos) = len;

  } else {

    if ( (*line) < o->line_num && (*pos) > len ) /* posx > than this line */
    {  /* and this line is not > than LINEmax */
      if ( (*line) == o->line ) { /* line is still same, only pos is moved */

        (*line)++;
        (*pos) = 0;

      };

    };

  };

  (*line) = lmax(0, lmin(o->line_num, (*line)));
  (*pos)  = lmax(0, lmin(len, (*pos)));

};


/*
  main function for text manipulating

  - newline is position of newline that must be current now
  - newpos  is position of new char-pos in newline
  - keycode is keyboard code that contains info about type of manipulating

*/

void  editor_redraw_text ( p_editor o, l_long newline, l_long newpos, l_int keycode )
{

  p_scroller sc = SCROLLER(o);
  l_long oldpos = o->line_pos;
  l_long oldline = o->line;
  l_long len = 0;

  l_long l = newline;
  l_long p = newpos;
  l_long drawpfrom = 0;
  l_bool drawp = true;

  l_text text;

  l_bool can_draw_cursor;
  l_bool can_del;
  l_bool must_write;

  l_int  redraw_text = 0;
  t_rect sel = o->sel_from;

  can_draw_cursor = false;
  can_del = true;
  must_write = true;

  redraw_text = 0;

  if ( keycode && !ed_is_wable(o) ) return;

  if ( keycode && ed_is_sel(o) && !(sel.a.y == sel.b.y && sel.b.x == sel.a.x) )  {
    l_text pp = o->posptr(o,sel.a.y,sel.a.x);
    l_text t = o->posptr(o,sel.b.y,sel.b.x);

    o->delstr(o,(pp-o->text),(t-pp));
    if ( sel.a.y < sel.b.y ) {
      newline = sel.a.y;
      newpos  = sel.a.x;
    } else {
      newline = sel.a.y;
      newpos  = sel.a.x;
    };
    l = newline;
    p = newpos;
    o->line = newline;
    o->line_pos = newpos;
    o->show_cursor(o, true);
    VIEW(o)->draw_view(VIEW(o));
  };

  text = o->lntxtlen(o, newline, &len);

  if ( !o->sel_ok && ed_is_sel(o) ) {

        ed_sel_clear(o);

        o->draw_box_ex(o, o->line_from);

  };

  #define coddrawpage(ln)         \
    if ( !ed_is_sel(o) ) {        \
      o->draw_box_ex(o, ln);      \
      drawpfrom = ln;             \
      drawp = false;              \
    } else drawp = true

  if ( keycode ) {

    switch ( KEY_TO(keycode) ) {

      case KB_ENTER     : {  /* insert ENTER to current position */

        if ( !o->inschr(o, '\n', o->line, o->line_pos) )

             return;

        text = o->lntxtlen(o, newline, &len);

        redraw_text = 1;

        coddrawpage(o->line);

      }; break;

      case KB_TAB     : { /* insert TAB to current position */

        l_text tab = (l_text)_malloc(EDITOR_TAB_SIZE+1);
        l_text ps  = o->posptr(o, o->line, o->line_pos);

        if ( tab && ps ) {

            memset(tab, 0x20, EDITOR_TAB_SIZE);

            tab[EDITOR_TAB_SIZE] = '\0';

            if ( o->insstr(o, strsize(o->text, ps), tab) ) {

                  o->draw_line(o, o->line);

            } else {

                  _free(tab);

                  return;
            };
        };

        _free(tab);

      }; break;

      case KB_DEL     : { /* delete char from current position */

        if ( o->line >= o->line_num && o->line_pos >= len ) return; /* if I'm going to delete last text char */

        text = o->lntxtlen(o, newline, &len);

        if ( o->delchr(o, o->line, o->line_pos) == '\n' )
          coddrawpage(o->line);

        /* show cursor */
        o->show_cursor(o, true);

        return;

      }; break;

      case KB_BACKSPACE  : { /* delete char from previous position */

        if ( newline <= 0 && newpos < 0 ) return; /* if pos is lower as first text char */

        text = o->lntxtlen(o, newline, &len);

        /* set cursor to true values */
        o->realpos(o, &newline, &newpos);

        if ( !o->delchr(o, newline, newpos) ) return;

        if ( newline != l )

            coddrawpage(newline); /* if deleted first char of line */

      }; break;

      default: /* insert char to current position */

        if ( (l_byte)TO_CHAR(keycode) >= 32 && (l_byte)TO_CHAR(keycode) <= 255 ) {

           if ( !o->inschr(o, (l_char)TO_CHAR(keycode), o->line, o->line_pos) ) return;

           text = o->lntxtlen(o, newline, &len);

        }; break;
    };
  };


  if ( keycode != TO_KEY(KB_BACKSPACE) ) /* backspace set values before */

       o->realpos(o, &newline, &newpos); /* set cursor to true values */

  o->line_pos = newpos;
  o->line = newline;

  can_draw_cursor = true;


  if ( o->line_pos == oldpos && o->line == oldline ) can_draw_cursor = false;


  if ( o->line_pos != oldpos ||
       o->line != oldline    || redraw_text ) {

      /* X SCROLLING */
      if ( o->line_pos < o->line_pos_from ) { /* scroll left */

            o->draw_cursor_ex(o, oldline, oldpos, 0);

            redraw_text = 0x03;
            can_draw_cursor = false;

            sc->scroll_place(sc, o->line_pos*sc->deltax-sc->scrollx, 0, 0);

      } else /* scroll right */
      if ( o->line_pos - o->line_pos_from > o->charsin(o, o->line, o->line_pos_from, 1) ) {

            o->draw_cursor_ex(o, oldline, oldpos, 0);

            redraw_text = 0x03;
            can_draw_cursor = false;

            sc->scroll_place(sc, (o->line_pos-o->charsin(o, o->line, o->line_pos, -1))*sc->deltax-sc->scrollx, 0, 0);
      };

      /* Y SCROLLING */
      if ( o->line < o->line_from ) { /* scroll up */

            o->draw_cursor_ex(o, oldline, oldpos, 0);

            redraw_text = 0x03;
            can_draw_cursor = false;

            sc->scroll_place(sc, 0, o->line*sc->deltay-sc->scrolly, 0);

      } else /* scroll down */
      if ( o->line - o->line_from > o->linesin(o, o->line_from, 1) ) {

            o->draw_cursor_ex(o, oldline, oldpos, 0);

            redraw_text = 0x03;
            can_draw_cursor = false;

            sc->scroll_place(sc, 0, (o->line-o->linesin(o, o->line_from, 1))*sc->deltay-sc->scrolly, 0);
      };

  };


  if ( keycode ) { /* if something is write I can't shift it */

    o->sel_ok = 0;

    if ( ed_is_sel(o) ) {

        t_rect s = o->sel_from;

        ed_sel_clear(o);

        o->show_cursor(o, false); /* hide cursor */

        if ( drawp ) /* must redraw page */

           o->draw_box_ex(o, drawpfrom);

        else

⌨️ 快捷键说明

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