📄 editor.c
字号:
{
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 + -