Text space
========== Main changes: - lines could be partially shown when they starts somewhere behind the upper boundary of area but because of word-wrapping some part of line will be show - fixed caret navigatiog in area when tabs aren't replaced by spaces - highlight the whole current line not only it's wrapped segment with caret - when you're in replace mode cursor would be as long as the tab's width if it's under tab symbol This fixes: #22399: Text Editor: word-wrapped lines prevent navigating through text with up-arrow. #21163: Text editor scrollbar problem with word wrap
This commit is contained in:
@@ -4646,6 +4646,7 @@ static void lib_link_screen(FileData *fd, Main *main)
|
||||
SpaceText *st= (SpaceText *)sl;
|
||||
|
||||
st->text= newlibadr(fd, sc->id.lib, st->text);
|
||||
st->drawcache= NULL;
|
||||
|
||||
}
|
||||
else if(sl->spacetype==SPACE_SCRIPT) {
|
||||
@@ -4877,6 +4878,8 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
|
||||
|
||||
st->text= restore_pointer_by_name(newmain, (ID *)st->text, 1);
|
||||
if(st->text==NULL) st->text= newmain->text.first;
|
||||
|
||||
st->drawcache= NULL;
|
||||
}
|
||||
else if(sl->spacetype==SPACE_SCRIPT) {
|
||||
SpaceScript *scpt= (SpaceScript *)sl;
|
||||
|
||||
@@ -92,6 +92,7 @@ static void text_free(SpaceLink *sl)
|
||||
SpaceText *stext= (SpaceText*) sl;
|
||||
|
||||
stext->text= NULL;
|
||||
text_free_caches(stext);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,9 +105,11 @@ static void text_init(struct wmWindowManager *wm, ScrArea *sa)
|
||||
static SpaceLink *text_duplicate(SpaceLink *sl)
|
||||
{
|
||||
SpaceText *stextn= MEM_dupallocN(sl);
|
||||
|
||||
|
||||
/* clear or remove stuff from old */
|
||||
|
||||
|
||||
stextn->drawcache= NULL; /* space need it's own cache */
|
||||
|
||||
return (SpaceLink *)stextn;
|
||||
}
|
||||
|
||||
@@ -132,8 +135,11 @@ static void text_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
|
||||
switch(wmn->action) {
|
||||
case NA_EDITED:
|
||||
if(st->text)
|
||||
if(st->text) {
|
||||
text_drawcache_tag_update(st, 1);
|
||||
text_update_edited(st->text);
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(sa);
|
||||
/* no break -- fall down to tag redraw */
|
||||
case NA_ADDED:
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
@@ -521,9 +520,22 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
|
||||
linep= text->lines.first;
|
||||
i= st->top;
|
||||
while(i>0 && linep) {
|
||||
if(linep == linein) return; /* Line before top */
|
||||
linep= linep->next;
|
||||
i--;
|
||||
int lines= text_get_visible_lines(st, ar, linep->line);
|
||||
|
||||
/* Line before top */
|
||||
if(linep == linein) {
|
||||
if(lines <= i)
|
||||
/* no visible part of line */
|
||||
return;
|
||||
}
|
||||
|
||||
if (i-lines<0) {
|
||||
break;
|
||||
} else {
|
||||
linep= linep->next;
|
||||
(*offl)+= lines-1;
|
||||
i-= lines;
|
||||
}
|
||||
}
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
@@ -548,10 +560,18 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
|
||||
|
||||
while(chars--) {
|
||||
if(i-start>=max) {
|
||||
if(chop && linep==linein && i >= cursin)
|
||||
if(chop && linep==linein && i >= cursin) {
|
||||
if (i==cursin) {
|
||||
(*offl)++;
|
||||
*offc -= end-start;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
(*offl)++;
|
||||
*offc -= end-start;
|
||||
|
||||
start= end;
|
||||
end += max;
|
||||
chop= 1;
|
||||
@@ -570,7 +590,66 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
|
||||
}
|
||||
}
|
||||
|
||||
static int get_char_pos(SpaceText *st, char *line, int cur)
|
||||
void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *offl, int *offc)
|
||||
{
|
||||
int i, j, start, end, chars, max, chop;
|
||||
char ch;
|
||||
|
||||
*offl= *offc= 0;
|
||||
|
||||
if(!st->text) return;
|
||||
if(!st->wordwrap) return;
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
|
||||
start= 0;
|
||||
end= max;
|
||||
chop= 1;
|
||||
chars= 0;
|
||||
*offc= 0;
|
||||
|
||||
for(i=0, j=0; linein->line[j]!='\0'; j++) {
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
ch= linein->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
if(i<cursin) cursin += chars-1;
|
||||
ch= ' ';
|
||||
}
|
||||
else
|
||||
chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
if(i-start>=max) {
|
||||
if(chop && i >= cursin) {
|
||||
if (i==cursin) {
|
||||
(*offl)++;
|
||||
*offc -= end-start;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
(*offl)++;
|
||||
*offc -= end-start;
|
||||
|
||||
start= end;
|
||||
end += max;
|
||||
chop= 1;
|
||||
}
|
||||
else if(ch==' ' || ch=='-') {
|
||||
end = i+1;
|
||||
chop= 0;
|
||||
if(i >= cursin)
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int text_get_char_pos(SpaceText *st, char *line, int cur)
|
||||
{
|
||||
int a=0, i;
|
||||
|
||||
@@ -583,7 +662,7 @@ static int get_char_pos(SpaceText *st, char *line, int cur)
|
||||
return a;
|
||||
}
|
||||
|
||||
static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char *format)
|
||||
static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char *format, int skip)
|
||||
{
|
||||
FlattenString fs;
|
||||
int basex, i, a, len, start, end, max, lines;
|
||||
@@ -599,6 +678,14 @@ static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char
|
||||
end= max;
|
||||
for(i=0; i<len; i++) {
|
||||
if(i-start >= max) {
|
||||
/* skip hidden part of line */
|
||||
if(skip) {
|
||||
skip--;
|
||||
start= end;
|
||||
end += max;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Draw the visible portion of text on the overshot line */
|
||||
for(a=start; a<end; a++) {
|
||||
if(st->showsyntax && format) format_draw_color(format[a]);
|
||||
@@ -609,6 +696,8 @@ static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char
|
||||
lines++;
|
||||
start= end;
|
||||
end += max;
|
||||
|
||||
if(y<=0) break;
|
||||
}
|
||||
else if(str[i]==' ' || str[i]=='-') {
|
||||
end = i+1;
|
||||
@@ -616,7 +705,7 @@ static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char
|
||||
}
|
||||
|
||||
/* Draw the remaining text */
|
||||
for(a=start; a<len; a++) {
|
||||
for(a=start; a<len && y > 0; a++) {
|
||||
if(st->showsyntax && format)
|
||||
format_draw_color(format[a]);
|
||||
|
||||
@@ -631,7 +720,7 @@ static int text_draw_wrapped(SpaceText *st, char *str, int x, int y, int w, char
|
||||
static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, char *format)
|
||||
{
|
||||
FlattenString fs;
|
||||
int r=0, w= 0;
|
||||
int r=0, w= 0, amount;
|
||||
int *acc;
|
||||
char *in;
|
||||
|
||||
@@ -647,18 +736,26 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra
|
||||
|
||||
if(draw) {
|
||||
if(st->showsyntax && format) {
|
||||
int amount, a;
|
||||
int a;
|
||||
format = format+cshift;
|
||||
|
||||
amount = strlen(in);
|
||||
if(maxwidth)
|
||||
amount= MIN2(amount, maxwidth);
|
||||
|
||||
for(a = 0; a < amount; a++) {
|
||||
format_draw_color(format[a]);
|
||||
x += text_font_draw_character(st, x, y, in[a]);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
amount = strlen(in);
|
||||
if(maxwidth)
|
||||
amount= MIN2(amount, maxwidth);
|
||||
|
||||
in[amount]= 0;
|
||||
text_font_draw(st, x, y, in);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(w-- && *acc++ < maxwidth)
|
||||
@@ -675,18 +772,307 @@ static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int dra
|
||||
return r+TXT_OFFSET;
|
||||
}
|
||||
|
||||
/************************ cache utilities *****************************/
|
||||
|
||||
typedef struct DrawCache {
|
||||
int *line_height;
|
||||
int total_lines, nlines;
|
||||
|
||||
/* this is needed to check cache relevance */
|
||||
int winx, wordwrap, showlinenrs, tabnumber;
|
||||
short lheight;
|
||||
char cwidth;
|
||||
char text_id[MAX_ID_NAME];
|
||||
|
||||
/* for partial lines recalculation */
|
||||
short update_flag;
|
||||
int valid_head, valid_tail; /* amount of unchanged lines */
|
||||
} DrawCache;
|
||||
|
||||
static void text_drawcache_init(SpaceText *st)
|
||||
{
|
||||
DrawCache *drawcache= MEM_callocN(sizeof (DrawCache), "text draw cache");
|
||||
|
||||
drawcache->winx= -1;
|
||||
drawcache->nlines= BLI_countlist(&st->text->lines);
|
||||
drawcache->text_id[0]= '\0';
|
||||
|
||||
st->drawcache= drawcache;
|
||||
}
|
||||
|
||||
static void text_update_drawcache(SpaceText *st, ARegion *ar)
|
||||
{
|
||||
DrawCache *drawcache;
|
||||
int full_update= 0, nlines= 0;
|
||||
Text *txt= st->text;
|
||||
|
||||
if(!st->drawcache) text_drawcache_init(st);
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
drawcache= (DrawCache *)st->drawcache;
|
||||
nlines= drawcache->nlines;
|
||||
|
||||
/* check if full cache update is needed */
|
||||
full_update|= drawcache->winx != ar->winx; /* area was resized */
|
||||
full_update|= drawcache->wordwrap != st->wordwrap; /* word-wrapping option was toggled */
|
||||
full_update|= drawcache->showlinenrs != st->showlinenrs; /* word-wrapping option was toggled */
|
||||
full_update|= drawcache->tabnumber != st->tabnumber; /* word-wrapping option was toggled */
|
||||
full_update|= drawcache->lheight != st->lheight; /* word-wrapping option was toggled */
|
||||
full_update|= drawcache->cwidth != st->cwidth; /* word-wrapping option was toggled */
|
||||
full_update|= strncmp(drawcache->text_id, txt->id.name, MAX_ID_NAME); /* text datablock was changed */
|
||||
|
||||
if(st->wordwrap) {
|
||||
/* update line heights */
|
||||
if(full_update || !drawcache->line_height) {
|
||||
drawcache->valid_head = 0;
|
||||
drawcache->valid_tail = 0;
|
||||
drawcache->update_flag = 1;
|
||||
}
|
||||
|
||||
if(drawcache->update_flag) {
|
||||
TextLine *line= st->text->lines.first;
|
||||
int lineno= 0, size, lines_count;
|
||||
int *fp= drawcache->line_height, *new_tail, *old_tail;
|
||||
|
||||
nlines= BLI_countlist(&txt->lines);
|
||||
size= sizeof(int)*nlines;
|
||||
|
||||
if(fp) fp= MEM_reallocN(fp, size);
|
||||
else fp= MEM_callocN(size, "text drawcache line_height");
|
||||
|
||||
drawcache->valid_tail= drawcache->valid_head= 0;
|
||||
old_tail= fp + drawcache->nlines - drawcache->valid_tail;
|
||||
new_tail= fp + nlines - drawcache->valid_tail;
|
||||
memmove(new_tail, old_tail, drawcache->valid_tail);
|
||||
|
||||
drawcache->total_lines= 0;
|
||||
|
||||
if(st->showlinenrs)
|
||||
st->linenrs_tot= (int)floor(log10((float)nlines)) + 1;
|
||||
|
||||
while(line) {
|
||||
if(drawcache->valid_head) { /* we're inside valid head lines */
|
||||
lines_count= fp[lineno];
|
||||
drawcache->valid_head--;
|
||||
} else if (lineno > new_tail - fp) { /* we-re inside valid tail lines */
|
||||
lines_count= fp[lineno];
|
||||
} else {
|
||||
lines_count= text_get_visible_lines(st, ar, line->line);
|
||||
}
|
||||
|
||||
fp[lineno]= lines_count;
|
||||
|
||||
line= line->next;
|
||||
lineno++;
|
||||
drawcache->total_lines+= lines_count;
|
||||
}
|
||||
|
||||
drawcache->line_height= fp;
|
||||
}
|
||||
} else {
|
||||
if(drawcache->line_height) {
|
||||
MEM_freeN(drawcache->line_height);
|
||||
drawcache->line_height= NULL;
|
||||
}
|
||||
|
||||
if(full_update || drawcache->update_flag) {
|
||||
nlines= BLI_countlist(&txt->lines);
|
||||
|
||||
if(st->showlinenrs)
|
||||
st->linenrs_tot= (int)floor(log10((float)nlines)) + 1;
|
||||
}
|
||||
|
||||
drawcache->total_lines= nlines;
|
||||
}
|
||||
|
||||
drawcache->nlines= nlines;
|
||||
|
||||
/* store settings */
|
||||
drawcache->winx = ar->winx;
|
||||
drawcache->wordwrap = st->wordwrap;
|
||||
drawcache->lheight = st->lheight;
|
||||
drawcache->cwidth = st->cwidth;
|
||||
drawcache->showlinenrs = st->showlinenrs;
|
||||
drawcache->tabnumber = st->tabnumber;
|
||||
|
||||
strncpy(drawcache->text_id, txt->id.name, MAX_ID_NAME);
|
||||
|
||||
/* clear update flag */
|
||||
drawcache->update_flag = 0;
|
||||
drawcache->valid_head = 0;
|
||||
drawcache->valid_tail = 0;
|
||||
}
|
||||
|
||||
void text_drawcache_tag_update(SpaceText *st, int full)
|
||||
{
|
||||
DrawCache *drawcache= (DrawCache *)st->drawcache;
|
||||
|
||||
if(drawcache) {
|
||||
Text *txt= st->text;
|
||||
|
||||
if(drawcache->update_flag) {
|
||||
/* happens when tagging update from space listener */
|
||||
/* should do nothing to prevent locally tagged cache be fully recalculated */
|
||||
return;
|
||||
}
|
||||
|
||||
if(!full) {
|
||||
int sellno= BLI_findindex(&txt->lines, txt->sell);
|
||||
int curlno= BLI_findindex(&txt->lines, txt->curl);
|
||||
|
||||
if(curlno < sellno) {
|
||||
drawcache->valid_head= curlno;
|
||||
drawcache->valid_tail= drawcache->nlines - sellno - 1;
|
||||
} else {
|
||||
drawcache->valid_head= sellno;
|
||||
drawcache->valid_tail= drawcache->nlines - curlno - 1;
|
||||
}
|
||||
|
||||
/* quick cache recalculation is also used in delete operator,
|
||||
which could merge lines which are adjusent to current selection lines
|
||||
expand recalculate area to this lines */
|
||||
if(drawcache->valid_head>0) drawcache->valid_head--;
|
||||
if(drawcache->valid_tail>0) drawcache->valid_tail--;
|
||||
} else {
|
||||
drawcache->valid_head= 0;
|
||||
drawcache->valid_tail= 0;
|
||||
}
|
||||
|
||||
drawcache->update_flag= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void text_free_caches(SpaceText *st)
|
||||
{
|
||||
DrawCache *drawcache= (DrawCache *)st->drawcache;
|
||||
|
||||
if(drawcache) {
|
||||
if(drawcache->line_height)
|
||||
MEM_freeN(drawcache->line_height);
|
||||
|
||||
MEM_freeN(drawcache);
|
||||
}
|
||||
}
|
||||
|
||||
/************************ word-wrap utilities *****************************/
|
||||
|
||||
/* cache should be updated in caller */
|
||||
int text_get_visible_lines_no(SpaceText *st, int lineno)
|
||||
{
|
||||
DrawCache *drawcache= (DrawCache *)st->drawcache;
|
||||
|
||||
return drawcache->line_height[lineno];
|
||||
}
|
||||
|
||||
int text_get_visible_lines(SpaceText *st, ARegion *ar, char *str)
|
||||
{
|
||||
int i, j, start, end, max, lines, chars;
|
||||
char ch;
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
lines= 1;
|
||||
start= 0;
|
||||
end= max;
|
||||
for(i= 0, j= 0; str[j] != '\0'; j++) {
|
||||
/* Mimic replacement of tabs */
|
||||
ch= str[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
ch= ' ';
|
||||
}
|
||||
else chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
if(i-start >= max) {
|
||||
lines++;
|
||||
start= end;
|
||||
end += max;
|
||||
}
|
||||
else if(ch==' ' || ch=='-') {
|
||||
end= i+1;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
int text_get_span_wrap(SpaceText *st, ARegion *ar, TextLine *from, TextLine *to)
|
||||
{
|
||||
if(st->wordwrap) {
|
||||
int ret=0;
|
||||
TextLine *tmp= from;
|
||||
|
||||
/* Look forwards */
|
||||
while (tmp) {
|
||||
if (tmp == to) return ret;
|
||||
ret+= text_get_visible_lines(st, ar, tmp->line);
|
||||
tmp= tmp->next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else return txt_get_span(from, to);
|
||||
}
|
||||
|
||||
int text_get_total_lines(SpaceText *st, ARegion *ar)
|
||||
{
|
||||
DrawCache *drawcache;
|
||||
|
||||
text_update_drawcache(st, ar);
|
||||
drawcache= (DrawCache *)st->drawcache;
|
||||
|
||||
return drawcache->total_lines;
|
||||
}
|
||||
|
||||
/* Move pointer to first visible line (top) */
|
||||
static TextLine *first_visible_line(SpaceText *st, ARegion *ar, int *wrap_top)
|
||||
{
|
||||
Text *text= st->text;
|
||||
TextLine* pline= text->lines.first;
|
||||
int i= st->top, lineno= 0;
|
||||
DrawCache *drawcache;
|
||||
|
||||
text_update_drawcache(st, ar);
|
||||
drawcache= (DrawCache *)st->drawcache;
|
||||
|
||||
if(wrap_top) *wrap_top= 0;
|
||||
|
||||
if(st->wordwrap) {
|
||||
while(i>0 && pline) {
|
||||
int lines= text_get_visible_lines_no(st, lineno);
|
||||
|
||||
if (i-lines<0) {
|
||||
if(wrap_top) *wrap_top= i;
|
||||
break;
|
||||
} else {
|
||||
pline= pline->next;
|
||||
i-= lines;
|
||||
lineno++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(i=st->top, pline= text->lines.first; pline->next && i>0; i--)
|
||||
pline= pline->next;
|
||||
}
|
||||
|
||||
return pline;
|
||||
}
|
||||
|
||||
/************************ draw scrollbar *****************************/
|
||||
|
||||
static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll)
|
||||
{
|
||||
int lhlstart, lhlend, ltexth;
|
||||
int lhlstart, lhlend, ltexth, sell_off, curl_off;
|
||||
short barheight, barstart, hlstart, hlend, blank_lines;
|
||||
short pix_available, pix_top_margin, pix_bottom_margin, pix_bardiff;
|
||||
|
||||
pix_top_margin = 8;
|
||||
pix_bottom_margin = 4;
|
||||
pix_available = ar->winy - pix_top_margin - pix_bottom_margin;
|
||||
ltexth= txt_get_span(st->text->lines.first, st->text->lines.last);
|
||||
ltexth= text_get_total_lines(st, ar);
|
||||
blank_lines = st->viewlines / 2;
|
||||
|
||||
/* nicer code: use scroll rect for entire bar */
|
||||
@@ -722,10 +1108,10 @@ static void calc_text_rcts(SpaceText *st, ARegion *ar, rcti *scroll)
|
||||
st->pix_per_line= (pix_available > 0)? (float) ltexth/pix_available: 0;
|
||||
if(st->pix_per_line<.1) st->pix_per_line=.1f;
|
||||
|
||||
lhlstart = MIN2(txt_get_span(st->text->lines.first, st->text->curl),
|
||||
txt_get_span(st->text->lines.first, st->text->sell));
|
||||
lhlend = MAX2(txt_get_span(st->text->lines.first, st->text->curl),
|
||||
txt_get_span(st->text->lines.first, st->text->sell));
|
||||
curl_off= text_get_span_wrap(st, ar, st->text->lines.first, st->text->curl);
|
||||
sell_off= text_get_span_wrap(st, ar, st->text->lines.first, st->text->sell);
|
||||
lhlstart = MIN2(curl_off, sell_off);
|
||||
lhlend = MAX2(curl_off, sell_off);
|
||||
|
||||
if(ltexth > 0) {
|
||||
hlstart = (lhlstart * pix_available)/ltexth;
|
||||
@@ -811,78 +1197,80 @@ static void draw_markers(SpaceText *st, ARegion *ar)
|
||||
{
|
||||
Text *text= st->text;
|
||||
TextMarker *marker, *next;
|
||||
TextLine *top, *bottom, *line;
|
||||
int offl, offc, i, cy, x1, x2, y1, y2, x, y;
|
||||
TextLine *top, *line;
|
||||
int offl, offc, i, x1, x2, y1, y2, x, y;
|
||||
int topi, topy;
|
||||
|
||||
for(i=st->top, top= text->lines.first; top->next && i>0; i--)
|
||||
top= top->next;
|
||||
/* Move pointer to first visible line (top) */
|
||||
top= first_visible_line(st, ar, NULL);
|
||||
topi= BLI_findindex(&text->lines, top);
|
||||
|
||||
topy= txt_get_span(text->lines.first, top);
|
||||
|
||||
for(i=st->viewlines-1, bottom=top; bottom->next && i>0; i--)
|
||||
bottom= bottom->next;
|
||||
|
||||
for(marker= text->markers.first; marker; marker= next) {
|
||||
next= marker->next;
|
||||
|
||||
for(cy= 0, line= top; line; cy++, line= line->next) {
|
||||
if(cy+st->top==marker->lineno) {
|
||||
/* Remove broken markers */
|
||||
if(marker->end>line->len || marker->start>marker->end) {
|
||||
BLI_freelinkN(&text->markers, marker);
|
||||
break;
|
||||
}
|
||||
/* invisible line (before top) */
|
||||
if(marker->lineno<topi) continue;
|
||||
|
||||
wrap_offset(st, ar, line, marker->start, &offl, &offc);
|
||||
x1= get_char_pos(st, line->line, marker->start) - st->left + offc;
|
||||
y1= cy + offl;
|
||||
wrap_offset(st, ar, line, marker->end, &offl, &offc);
|
||||
x2= get_char_pos(st, line->line, marker->end) - st->left + offc;
|
||||
y2= cy + offl;
|
||||
line= BLI_findlink(&text->lines, marker->lineno);
|
||||
|
||||
glColor3ub(marker->color[0], marker->color[1], marker->color[2]);
|
||||
x= st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
|
||||
y= ar->winy-3;
|
||||
/* Remove broken markers */
|
||||
if(marker->end>line->len || marker->start>marker->end) {
|
||||
BLI_freelinkN(&text->markers, marker);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(y1==y2) {
|
||||
y -= y1*st->lheight;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(x+x2*st->cwidth+1, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y-st->lheight);
|
||||
glVertex2i(x+x2*st->cwidth+1, y-st->lheight);
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
y -= y1*st->lheight;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(ar->winx, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y-st->lheight);
|
||||
glVertex2i(ar->winx, y-st->lheight);
|
||||
glEnd();
|
||||
y-=st->lheight;
|
||||
wrap_offset(st, ar, line, marker->start, &offl, &offc);
|
||||
y1 = txt_get_span(top, line) - st->top + offl + topy;
|
||||
x1 = text_get_char_pos(st, line->line, marker->start) - st->left + offc;
|
||||
|
||||
for(i=y1+1; i<y2; i++) {
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(ar->winx, y);
|
||||
glVertex2i(x, y-st->lheight);
|
||||
glVertex2i(ar->winx, y-st->lheight);
|
||||
glEnd();
|
||||
y-=st->lheight;
|
||||
}
|
||||
wrap_offset(st, ar, line, marker->end, &offl, &offc);
|
||||
y2 = txt_get_span(top, line) - st->top + offl + topy;
|
||||
x2 = text_get_char_pos(st, line->line, marker->end) - st->left + offc;
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x+x2*st->cwidth+1, y);
|
||||
glVertex2i(x+x2*st->cwidth+1, y-st->lheight);
|
||||
glVertex2i(x, y-st->lheight);
|
||||
glEnd();
|
||||
}
|
||||
/* invisible part of line (before top, after last visible line) */
|
||||
if(y2 < 0 || y1 > st->top+st->viewlines) continue;
|
||||
|
||||
break;
|
||||
glColor3ub(marker->color[0], marker->color[1], marker->color[2]);
|
||||
x= st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
|
||||
y= ar->winy-3;
|
||||
|
||||
if(y1==y2) {
|
||||
y -= y1*st->lheight;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(x+x2*st->cwidth+1, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y-st->lheight);
|
||||
glVertex2i(x+x2*st->cwidth+1, y-st->lheight);
|
||||
glEnd();
|
||||
}
|
||||
else {
|
||||
y -= y1*st->lheight;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(ar->winx, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y);
|
||||
glVertex2i(x+x1*st->cwidth-2, y-st->lheight);
|
||||
glVertex2i(ar->winx, y-st->lheight);
|
||||
glEnd();
|
||||
y-=st->lheight;
|
||||
|
||||
for(i=y1+1; i<y2; i++) {
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(ar->winx, y);
|
||||
glVertex2i(x, y-st->lheight);
|
||||
glVertex2i(ar->winx, y-st->lheight);
|
||||
glEnd();
|
||||
y-=st->lheight;
|
||||
}
|
||||
|
||||
if(line==bottom) break;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(x, y);
|
||||
glVertex2i(x+x2*st->cwidth+1, y);
|
||||
glVertex2i(x+x2*st->cwidth+1, y-st->lheight);
|
||||
glVertex2i(x, y-st->lheight);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1058,16 +1446,16 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
|
||||
Text *text= st->text;
|
||||
int vcurl, vcurc, vsell, vselc, hidden=0;
|
||||
int offl, offc, x, y, w, i;
|
||||
|
||||
|
||||
/* Draw the selection */
|
||||
if(text->curl!=text->sell || text->curc!=text->selc) {
|
||||
/* Convert all to view space character coordinates */
|
||||
wrap_offset(st, ar, text->curl, text->curc, &offl, &offc);
|
||||
vcurl = txt_get_span(text->lines.first, text->curl) - st->top + offl;
|
||||
vcurc = get_char_pos(st, text->curl->line, text->curc) - st->left + offc;
|
||||
vcurc = text_get_char_pos(st, text->curl->line, text->curc) - st->left + offc;
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
|
||||
vselc = get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
|
||||
vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
|
||||
|
||||
if(vcurc<0) vcurc=0;
|
||||
if(vselc<0) vselc=0, hidden=1;
|
||||
@@ -1106,7 +1494,7 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
|
||||
else {
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
vsell = txt_get_span(text->lines.first, text->sell) - st->top + offl;
|
||||
vselc = get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
|
||||
vselc = text_get_char_pos(st, text->sell->line, text->selc) - st->left + offc;
|
||||
|
||||
if(vselc<0) {
|
||||
vselc= 0;
|
||||
@@ -1115,17 +1503,30 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
|
||||
}
|
||||
|
||||
if(st->line_hlight) {
|
||||
y= ar->winy-2 - vsell*st->lheight;
|
||||
if(!(y<0 || y > ar->winy)) { /* check we need to draw */
|
||||
int x1= st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
|
||||
int x2= x1 + ar->winx;
|
||||
y= ar->winy-2 - vsell*st->lheight;
|
||||
|
||||
int x1, x2, y1, y2;
|
||||
|
||||
if(st->wordwrap) {
|
||||
int visible_lines = text_get_visible_lines(st, ar, text->sell->line);
|
||||
int offl, offc;
|
||||
|
||||
wrap_offset_in_line(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
|
||||
y1= ar->winy-2 - (vsell-offl)*st->lheight;
|
||||
y2= y1-st->lheight*visible_lines+1;
|
||||
} else {
|
||||
y1= ar->winy-2 - vsell*st->lheight;
|
||||
y2= y1-st->lheight+1;
|
||||
}
|
||||
|
||||
if(!(y1<0 || y2 > ar->winy)) { /* check we need to draw */
|
||||
x1= st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
|
||||
x2= x1 + ar->winx;
|
||||
|
||||
glColor4ub(255, 255, 255, 32);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_BLEND);
|
||||
glRecti(x1-4, y, x2, y-st->lheight+1);
|
||||
glRecti(x1-4, y1, x2, y2);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
@@ -1138,8 +1539,10 @@ static void draw_cursor(SpaceText *st, ARegion *ar)
|
||||
|
||||
if(st->overwrite) {
|
||||
char ch= text->sell->line[text->selc];
|
||||
if(!ch) ch= ' ';
|
||||
|
||||
w= st->cwidth;
|
||||
if(ch=='\t') w*= st->tabnumber-(vselc+st->left)%st->tabnumber;
|
||||
|
||||
UI_ThemeColor(TH_HILITE);
|
||||
glRecti(x, y-st->lheight-1, x+w, y-st->lheight+1);
|
||||
}
|
||||
@@ -1243,7 +1646,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
/* draw opening bracket */
|
||||
ch= startl->line[startc];
|
||||
wrap_offset(st, ar, startl, startc, &offl, &offc);
|
||||
viewc= get_char_pos(st, startl->line, startc) - st->left + offc;
|
||||
viewc= text_get_char_pos(st, startl->line, startc) - st->left + offc;
|
||||
|
||||
if(viewc >= 0){
|
||||
viewl= txt_get_span(text->lines.first, startl) - st->top + offl;
|
||||
@@ -1255,7 +1658,7 @@ static void draw_brackets(SpaceText *st, ARegion *ar)
|
||||
/* draw closing bracket */
|
||||
ch= endl->line[endc];
|
||||
wrap_offset(st, ar, endl, endc, &offl, &offc);
|
||||
viewc= get_char_pos(st, endl->line, endc) - st->left + offc;
|
||||
viewc= text_get_char_pos(st, endl->line, endc) - st->left + offc;
|
||||
|
||||
if(viewc >= 0) {
|
||||
viewl= txt_get_span(text->lines.first, endl) - st->top + offl;
|
||||
@@ -1273,12 +1676,15 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
||||
TextLine *tmp;
|
||||
rcti scroll;
|
||||
char linenr[12];
|
||||
int i, x, y, winx, linecount= 0;
|
||||
int i, x, y, winx, linecount= 0, lineno= 0;
|
||||
int wraplinecount= 0, wrap_skip= 0;
|
||||
|
||||
/* if no text, nothing to do */
|
||||
if(!text)
|
||||
return;
|
||||
|
||||
text_update_drawcache(st, ar);
|
||||
|
||||
/* make sure all the positional pointers exist */
|
||||
if(!text->curl || !text->sell || !text->lines.first || !text->lines.last)
|
||||
txt_clean_text(text);
|
||||
@@ -1291,12 +1697,28 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
||||
|
||||
/* update syntax formatting if needed */
|
||||
tmp= text->lines.first;
|
||||
lineno= 0;
|
||||
for(i= 0; i<st->top && tmp; i++) {
|
||||
if(st->showsyntax && !tmp->format)
|
||||
txt_format_line(st, tmp, 0);
|
||||
|
||||
tmp= tmp->next;
|
||||
linecount++;
|
||||
if(st->wordwrap) {
|
||||
int lines= text_get_visible_lines_no(st, lineno);
|
||||
|
||||
if (wraplinecount+lines>st->top) {
|
||||
wrap_skip= st->top-wraplinecount;
|
||||
break;
|
||||
} else {
|
||||
wraplinecount+= lines;
|
||||
tmp= tmp->next;
|
||||
linecount++;
|
||||
}
|
||||
} else {
|
||||
tmp= tmp->next;
|
||||
linecount++;
|
||||
}
|
||||
|
||||
lineno++;
|
||||
}
|
||||
|
||||
text_font_begin(st);
|
||||
@@ -1305,7 +1727,6 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
||||
|
||||
/* draw line numbers background */
|
||||
if(st->showlinenrs) {
|
||||
st->linenrs_tot = (int)floor(log10((float)(linecount + st->viewlines))) + 1;
|
||||
x= TXT_OFFSET + TEXTXLOC;
|
||||
|
||||
UI_ThemeColor(TH_GRID);
|
||||
@@ -1328,7 +1749,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
||||
if(st->showsyntax && !tmp->format)
|
||||
txt_format_line(st, tmp, 0);
|
||||
|
||||
if(st->showlinenrs) {
|
||||
if(st->showlinenrs && !wrap_skip) {
|
||||
/* draw line number */
|
||||
if(tmp == text->curl)
|
||||
UI_ThemeColor(TH_HILITE);
|
||||
@@ -1344,14 +1765,16 @@ void draw_text_main(SpaceText *st, ARegion *ar)
|
||||
|
||||
if(st->wordwrap) {
|
||||
/* draw word wrapped text */
|
||||
int lines = text_draw_wrapped(st, tmp->line, x, y, winx-x, tmp->format);
|
||||
int lines = text_draw_wrapped(st, tmp->line, x, y, winx-x, tmp->format, wrap_skip);
|
||||
y -= lines*st->lheight;
|
||||
}
|
||||
else {
|
||||
/* draw unwrapped text */
|
||||
text_draw(st, tmp->line, st->left, 0, 1, x, y, tmp->format);
|
||||
text_draw(st, tmp->line, st->left, ar->winx/st->cwidth, 1, x, y, tmp->format);
|
||||
y -= st->lheight;
|
||||
}
|
||||
|
||||
wrap_skip= 0;
|
||||
}
|
||||
|
||||
/* draw other stuff */
|
||||
@@ -1398,6 +1821,12 @@ void text_update_cursor_moved(bContext *C)
|
||||
text_update_character_width(st);
|
||||
|
||||
i= txt_get_span(text->lines.first, text->sell);
|
||||
if(st->wordwrap) {
|
||||
int offl, offc;
|
||||
wrap_offset(st, CTX_wm_region(C), text->sell, text->selc, &offl, &offc);
|
||||
i+= offl;
|
||||
}
|
||||
|
||||
if(st->top+st->viewlines <= i || st->top > i)
|
||||
st->top= i - st->viewlines/2;
|
||||
|
||||
|
||||
@@ -90,12 +90,20 @@ void flatten_string_free(FlattenString *fs);
|
||||
|
||||
int wrap_width(struct SpaceText *st, struct ARegion *ar);
|
||||
void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc);
|
||||
void wrap_offset_in_line(struct SpaceText *st, struct ARegion *ar, struct TextLine *linep, int cursin, int *offl, int *offc);
|
||||
int text_get_char_pos(struct SpaceText *st, char *line, int cur);
|
||||
|
||||
void text_drawcache_tag_update(struct SpaceText *st, int full);
|
||||
void text_free_caches(struct SpaceText *st);
|
||||
|
||||
int text_file_modified(struct Text *text);
|
||||
|
||||
int text_do_suggest_select(struct SpaceText *st, struct ARegion *ar);
|
||||
void text_pop_suggest_list();
|
||||
|
||||
int text_get_visible_lines(struct SpaceText *st, struct ARegion *ar, char *str);
|
||||
int text_get_span_wrap(struct SpaceText *st, struct ARegion *ar, struct TextLine *from, struct TextLine *to);
|
||||
int text_get_total_lines(struct SpaceText *st, struct ARegion *ar);
|
||||
|
||||
/* text_ops.c */
|
||||
enum { LINE_BEGIN, LINE_END, FILE_TOP, FILE_BOTTOM, PREV_CHAR, NEXT_CHAR,
|
||||
|
||||
@@ -173,6 +173,7 @@ static int new_exec(bContext *C, wmOperator *op)
|
||||
st->top= 0;
|
||||
}
|
||||
|
||||
text_drawcache_tag_update(st, 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -254,6 +255,7 @@ static int open_exec(bContext *C, wmOperator *op)
|
||||
text->name = NULL;
|
||||
}
|
||||
|
||||
text_drawcache_tag_update(st, 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_ADDED, text);
|
||||
|
||||
MEM_freeN(op->customdata);
|
||||
@@ -315,6 +317,7 @@ static int reload_exec(bContext *C, wmOperator *op)
|
||||
|
||||
text_update_edited(text);
|
||||
text_update_cursor_moved(C);
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -357,6 +360,8 @@ static int unlink_exec(bContext *C, wmOperator *op)
|
||||
|
||||
unlink_text(bmain, text);
|
||||
free_libblock(&bmain->text, text);
|
||||
|
||||
text_drawcache_tag_update(st, 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_REMOVED, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -738,6 +743,8 @@ static int paste_exec(bContext *C, wmOperator *op)
|
||||
if(!buf)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
txt_insert_buf(text, buf);
|
||||
text_update_edited(text);
|
||||
|
||||
@@ -809,6 +816,8 @@ static int cut_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
txt_copy_clipboard(text);
|
||||
txt_delete_selected(text);
|
||||
|
||||
@@ -840,6 +849,8 @@ static int indent_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
if(txt_has_sel(text)) {
|
||||
txt_order_cursors(text);
|
||||
indent(text);
|
||||
@@ -874,6 +885,8 @@ static int unindent_exec(bContext *C, wmOperator *op)
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
if(txt_has_sel(text)) {
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
txt_order_cursors(text);
|
||||
unindent(text);
|
||||
|
||||
@@ -909,6 +922,8 @@ static int line_break_exec(bContext *C, wmOperator *op)
|
||||
int a, curts;
|
||||
int space = (text->flags & TXT_TABSTOSPACES) ? st->tabnumber : 1;
|
||||
|
||||
text_drawcache_tag_update(st, 0);
|
||||
|
||||
// double check tabs/spaces before splitting the line
|
||||
curts= setcurr_tab_spaces(text, space);
|
||||
txt_split_curline(text);
|
||||
@@ -952,6 +967,8 @@ static int comment_exec(bContext *C, wmOperator *op)
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
if(txt_has_sel(text)) {
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
txt_order_cursors(text);
|
||||
comment(text);
|
||||
text_update_edited(text);
|
||||
@@ -983,6 +1000,8 @@ static int uncomment_exec(bContext *C, wmOperator *op)
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
if(txt_has_sel(text)) {
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
txt_order_cursors(text);
|
||||
uncomment(text);
|
||||
text_update_edited(text);
|
||||
@@ -1130,6 +1149,7 @@ static int convert_whitespace_exec(bContext *C, wmOperator *op)
|
||||
|
||||
text_update_edited(text);
|
||||
text_update_cursor_moved(C);
|
||||
text_drawcache_tag_update(st, 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -1317,146 +1337,360 @@ static EnumPropertyItem move_type_items[]= {
|
||||
{NEXT_PAGE, "NEXT_PAGE", 0, "Next Page", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* get cursor position in line by relative wrapped line and column positions */
|
||||
static int text_get_cursor_rel(SpaceText* st, ARegion *ar, TextLine *linein, int rell, int relc)
|
||||
{
|
||||
int i, j, start, end, chars, max, chop, curs, loop, endj, found, selc;
|
||||
char ch;
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
|
||||
selc= start= chars= endj= curs= found= 0;
|
||||
end= max;
|
||||
chop= loop= 1;
|
||||
|
||||
for(i=0, j=0; loop; j++) {
|
||||
/* Mimic replacement of tabs */
|
||||
ch= linein->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
ch= ' ';
|
||||
}
|
||||
else chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
if(rell==0 && i-start==relc) {
|
||||
/* current position could be wrapped to next line */
|
||||
/* this should be checked when end of current line would be reached */
|
||||
selc= j;
|
||||
found= 1;
|
||||
}
|
||||
else if(i-end==relc) {
|
||||
curs= j;
|
||||
}
|
||||
if(i-start>=max) {
|
||||
if(found) {
|
||||
/* exact cursor position was found, check if it's */
|
||||
/* still on needed line (hasn't been wrapped) */
|
||||
if(selc>endj && !chop) selc= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj= j;
|
||||
|
||||
start= end;
|
||||
end += max;
|
||||
chop= 1;
|
||||
rell--;
|
||||
|
||||
if(rell==0 && i-start>=relc) {
|
||||
selc= curs;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ch=='\0') {
|
||||
if(!found) selc= linein->len;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
else if(ch==' ' || ch=='-') {
|
||||
if(found) {
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(rell==0 && i-start>=relc) {
|
||||
selc= curs;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
end= i+1;
|
||||
endj= j;
|
||||
chop= 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return selc;
|
||||
}
|
||||
|
||||
static int cursor_skip_find_line(SpaceText* st, ARegion *ar, Text *text,
|
||||
int lines, TextLine **linep, int *charp, int *rell, int *relc)
|
||||
{
|
||||
int offl, offc, visible_lines;
|
||||
|
||||
wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc);
|
||||
*relc= text_get_char_pos(st, (*linep)->line, *charp) + offc;
|
||||
*rell= lines;
|
||||
|
||||
/* handle current line */
|
||||
if(lines>0) {
|
||||
visible_lines= text_get_visible_lines(st, ar, (*linep)->line);
|
||||
|
||||
if(*rell-visible_lines+offl>=0) {
|
||||
if(!(*linep)->next) {
|
||||
if(offl < visible_lines-1) {
|
||||
*rell= visible_lines-1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*charp= (*linep)->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*rell-= visible_lines-offl;
|
||||
*linep=(*linep)->next;
|
||||
} else {
|
||||
*rell+= offl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if(*rell+offl<=0) {
|
||||
if(!(*linep)->prev) {
|
||||
if(offl) {
|
||||
*rell= 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*charp= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*rell+= offl;
|
||||
*linep=(*linep)->prev;
|
||||
} else {
|
||||
*rell+= offl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip lines and find destination line and offsets */
|
||||
while(*linep) {
|
||||
visible_lines= text_get_visible_lines(st, ar, (*linep)->line);
|
||||
|
||||
if(lines<0) { /* moving top */
|
||||
if(*rell+visible_lines >= 0) {
|
||||
*rell+= visible_lines;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(*linep)->prev) {
|
||||
*rell= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*rell+= visible_lines;
|
||||
*linep=(*linep)->prev;
|
||||
} else { /* moving bottom */
|
||||
if(*rell-visible_lines < 0) break;
|
||||
|
||||
if(!(*linep)->next) {
|
||||
*rell= visible_lines-1;
|
||||
break;
|
||||
}
|
||||
|
||||
*rell-= visible_lines;
|
||||
*linep=(*linep)->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
|
||||
{
|
||||
Text *text= st->text;
|
||||
int offl, offc, lin;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int oldl, oldc, i, j, max, start, end, chars, endj, chop, loop;
|
||||
char ch;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
lin= txt_get_span(text->lines.first, text->sell);
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
if (sel) linep= &text->sell, charp= &text->selc;
|
||||
else linep= &text->curl, charp= &text->curc;
|
||||
|
||||
if (sel) {
|
||||
txt_undo_add_toop(text, UNDO_STO, lin, text->selc, lin, -offc);
|
||||
text->selc= -offc;
|
||||
} else {
|
||||
txt_undo_add_toop(text, UNDO_CTO, lin, text->curc, lin, -offc);
|
||||
text->curc= -offc;
|
||||
txt_pop_sel(text);
|
||||
oldc= *charp;
|
||||
oldl= txt_get_span(text->lines.first, *linep);
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
|
||||
start= chars= endj= 0;
|
||||
end= max;
|
||||
chop= loop= 1;
|
||||
*charp= 0;
|
||||
|
||||
for(i=0, j=0; loop; j++) {
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
ch= ' ';
|
||||
}
|
||||
else chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
if(i-start>=max) {
|
||||
*charp= endj;
|
||||
|
||||
if(j>=oldc) {
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj= j;
|
||||
|
||||
start= end;
|
||||
end += max;
|
||||
chop= 0;
|
||||
}
|
||||
else if(ch==' ' || ch=='-' || ch=='\0') {
|
||||
if(j>=oldc) {
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
end= i+1;
|
||||
endj= j+1;
|
||||
chop= 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sel) txt_pop_sel(text);
|
||||
txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, oldl, *charp);
|
||||
}
|
||||
|
||||
static void wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
|
||||
{
|
||||
Text *text= st->text;
|
||||
int offl, offc, lin, startl, c;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int oldl, oldc, i, j, max, start, end, chars, endj, chop, loop;
|
||||
char ch;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
lin= txt_get_span(text->lines.first, text->sell);
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
startl= offl;
|
||||
c= text->selc;
|
||||
while (offl==startl && text->sell->line[c]!='\0') {
|
||||
c++;
|
||||
wrap_offset(st, ar, text->sell, c, &offl, &offc);
|
||||
} if (offl!=startl) c--;
|
||||
if (sel) linep= &text->sell, charp= &text->selc;
|
||||
else linep= &text->curl, charp= &text->curc;
|
||||
|
||||
if (sel) {
|
||||
txt_undo_add_toop(text, UNDO_STO, lin, text->selc, lin, c);
|
||||
text->selc= c;
|
||||
} else {
|
||||
txt_undo_add_toop(text, UNDO_CTO, lin, text->curc, lin, c);
|
||||
text->curc= c;
|
||||
txt_pop_sel(text);
|
||||
oldc= *charp;
|
||||
oldl= txt_get_span(text->lines.first, *linep);
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
|
||||
start= chars= endj= 0;
|
||||
end= max;
|
||||
chop= loop= 1;
|
||||
*charp= 0;
|
||||
|
||||
for(i=0, j=0; loop; j++) {
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
ch= ' ';
|
||||
}
|
||||
else chars= 1;
|
||||
|
||||
while(chars--) {
|
||||
if(i-start>=max) {
|
||||
if(endj>=oldc) {
|
||||
*charp= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj= j;
|
||||
|
||||
start= end;
|
||||
end += max;
|
||||
chop= 0;
|
||||
} else if(ch=='\0') {
|
||||
*charp= (*linep)->len;
|
||||
loop= 0;
|
||||
break;
|
||||
} else if(ch==' ' || ch=='-') {
|
||||
end= i+1;
|
||||
endj= j;
|
||||
chop= 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sel) txt_pop_sel(text);
|
||||
txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, oldl, *charp);
|
||||
}
|
||||
|
||||
static void wrap_move_up(SpaceText *st, ARegion *ar, short sel)
|
||||
{
|
||||
Text *text= st->text;
|
||||
int offl, offl_1, offc, fromline, toline, c, target;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int oldl, oldc, offl, offc, col, newl;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
wrap_offset(st, ar, text->sell, 0, &offl_1, &offc);
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
fromline= toline= txt_get_span(text->lines.first, text->sell);
|
||||
target= text->selc + offc;
|
||||
if (sel) linep= &text->sell, charp= &text->selc;
|
||||
else linep= &text->curl, charp= &text->curc;
|
||||
|
||||
if (offl==offl_1) {
|
||||
if (!text->sell->prev) {
|
||||
txt_move_bol(text, sel);
|
||||
return;
|
||||
}
|
||||
toline--;
|
||||
c= text->sell->prev->len; /* End of prev. line */
|
||||
wrap_offset(st, ar, text->sell->prev, c, &offl, &offc);
|
||||
c= -offc+target;
|
||||
/* store previous position */
|
||||
oldc= *charp;
|
||||
newl= oldl= txt_get_span(text->lines.first, *linep);
|
||||
|
||||
wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc);
|
||||
col= text_get_char_pos(st, (*linep)->line, *charp) + offc;
|
||||
if(offl) {
|
||||
*charp= text_get_cursor_rel(st, ar, *linep, offl-1, col);
|
||||
} else {
|
||||
c= -offc-1; /* End of prev. line */
|
||||
wrap_offset(st, ar, text->sell, c, &offl, &offc);
|
||||
c= -offc+target;
|
||||
}
|
||||
if (c<0) c=0;
|
||||
if((*linep)->prev) {
|
||||
int visible_lines;
|
||||
|
||||
if (sel) {
|
||||
txt_undo_add_toop(text, UNDO_STO, fromline, text->selc, toline, c);
|
||||
if (toline<fromline) text->sell= text->sell->prev;
|
||||
if(text->sell) {
|
||||
if (c>text->sell->len) c= text->sell->len;
|
||||
text->selc= c;
|
||||
}
|
||||
}
|
||||
else if(text->curl) {
|
||||
txt_undo_add_toop(text, UNDO_CTO, fromline, text->curc, toline, c);
|
||||
if (toline<fromline) text->curl= text->curl->prev;
|
||||
if(text->curl) {
|
||||
if (c>text->curl->len) c= text->curl->len;
|
||||
text->curc= c;
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
*linep= (*linep)->prev;
|
||||
visible_lines= text_get_visible_lines(st, ar, (*linep)->line);
|
||||
*charp= text_get_cursor_rel(st, ar, *linep, visible_lines-1, col);
|
||||
} else *charp= 0;
|
||||
}
|
||||
|
||||
if (!sel) txt_pop_sel(text);
|
||||
txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, newl, *charp);
|
||||
}
|
||||
|
||||
static void wrap_move_down(SpaceText *st, ARegion *ar, short sel)
|
||||
{
|
||||
Text *text= st->text;
|
||||
int offl, startoff, offc, fromline, toline, c, target;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int oldl, oldc, offl, offc, col, newl, visible_lines;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
wrap_offset(st, ar, text->sell, text->selc, &offl, &offc);
|
||||
fromline= toline= txt_get_span(text->lines.first, text->sell);
|
||||
target= text->selc + offc;
|
||||
startoff= offl;
|
||||
c= text->selc;
|
||||
while (offl==startoff && text->sell->line[c]!='\0') {
|
||||
c++;
|
||||
wrap_offset(st, ar, text->sell, c, &offl, &offc);
|
||||
}
|
||||
if (sel) linep= &text->sell, charp= &text->selc;
|
||||
else linep= &text->curl, charp= &text->curc;
|
||||
|
||||
if (text->sell->line[c]=='\0') {
|
||||
if (!text->sell->next) {
|
||||
txt_move_eol(text, sel);
|
||||
return;
|
||||
}
|
||||
toline++;
|
||||
c= target;
|
||||
/* store previous position */
|
||||
oldc= *charp;
|
||||
newl= oldl= txt_get_span(text->lines.first, *linep);
|
||||
|
||||
wrap_offset_in_line(st, ar, *linep, *charp, &offl, &offc);
|
||||
col= text_get_char_pos(st, (*linep)->line, *charp) + offc;
|
||||
visible_lines= text_get_visible_lines(st, ar, (*linep)->line);
|
||||
if(offl<visible_lines-1) {
|
||||
*charp= text_get_cursor_rel(st, ar, *linep, offl+1, col);
|
||||
} else {
|
||||
c += target;
|
||||
if (c > text->sell->len) c= text->sell->len;
|
||||
if((*linep)->next) {
|
||||
*linep= (*linep)->next;
|
||||
*charp= text_get_cursor_rel(st, ar, *linep, 0, col);
|
||||
} else *charp= (*linep)->len;
|
||||
}
|
||||
if (c<0) c=0;
|
||||
|
||||
if (sel) {
|
||||
txt_undo_add_toop(text, UNDO_STO, fromline, text->selc, toline, c);
|
||||
if (toline>fromline) text->sell= text->sell->next;
|
||||
if(text->sell) {
|
||||
if (c>text->sell->len) c= text->sell->len;
|
||||
text->selc= c;
|
||||
}
|
||||
}
|
||||
else if(text->curl) {
|
||||
txt_undo_add_toop(text, UNDO_CTO, fromline, text->curc, toline, c);
|
||||
if (toline>fromline) text->curl= text->curl->next;
|
||||
if(text->curl) {
|
||||
if (c > text->curl->len) c= text->curl->len;
|
||||
text->curc= c;
|
||||
txt_pop_sel(text);
|
||||
}
|
||||
}
|
||||
if (!sel) txt_pop_sel(text);
|
||||
txt_undo_add_toop(text, sel?UNDO_STO:UNDO_CTO, oldl, oldc, newl, *charp);
|
||||
}
|
||||
|
||||
/* Moves the cursor vertically by the specified number of lines.
|
||||
@@ -1465,7 +1699,7 @@ static void wrap_move_down(SpaceText *st, ARegion *ar, short sel)
|
||||
|
||||
This is to replace screen_skip for PageUp/Down operations.
|
||||
*/
|
||||
static void cursor_skip(Text *text, int lines, int sel)
|
||||
static void cursor_skip(SpaceText* st, ARegion *ar, Text *text, int lines, int sel)
|
||||
{
|
||||
TextLine **linep;
|
||||
int oldl, oldc, *charp;
|
||||
@@ -1475,13 +1709,21 @@ static void cursor_skip(Text *text, int lines, int sel)
|
||||
oldl= txt_get_span(text->lines.first, *linep);
|
||||
oldc= *charp;
|
||||
|
||||
while (lines>0 && (*linep)->next) {
|
||||
*linep= (*linep)->next;
|
||||
lines--;
|
||||
}
|
||||
while (lines<0 && (*linep)->prev) {
|
||||
*linep= (*linep)->prev;
|
||||
lines++;
|
||||
if(st && ar && st->wordwrap) {
|
||||
int rell, relc;
|
||||
|
||||
/* find line and offsets inside it needed to set cursor position */
|
||||
if(cursor_skip_find_line(st, ar, text, lines, linep, charp, &rell, &relc))
|
||||
*charp= text_get_cursor_rel (st, ar, *linep, rell, relc);
|
||||
} else {
|
||||
while (lines>0 && (*linep)->next) {
|
||||
*linep= (*linep)->next;
|
||||
lines--;
|
||||
}
|
||||
while (lines<0 && (*linep)->prev) {
|
||||
*linep= (*linep)->prev;
|
||||
lines++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*charp > (*linep)->len) *charp= (*linep)->len;
|
||||
@@ -1546,18 +1788,18 @@ static int move_cursor(bContext *C, int type, int select)
|
||||
break;
|
||||
|
||||
case PREV_PAGE:
|
||||
if(st) cursor_skip(text, -st->viewlines, select);
|
||||
else cursor_skip(text, -10, select);
|
||||
if(st) cursor_skip(st, ar, st->text, -st->viewlines, select);
|
||||
else cursor_skip(NULL, NULL, text, -10, select);
|
||||
break;
|
||||
|
||||
case NEXT_PAGE:
|
||||
if(st) cursor_skip(text, st->viewlines, select);
|
||||
else cursor_skip(text, 10, select);
|
||||
if(st) cursor_skip(st, ar, st->text, st->viewlines, select);
|
||||
else cursor_skip(NULL, NULL, text, 10, select);
|
||||
break;
|
||||
}
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
|
||||
WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1665,6 +1907,8 @@ static int delete_exec(bContext *C, wmOperator *op)
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
int type= RNA_enum_get(op->ptr, "type");
|
||||
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 0);
|
||||
|
||||
if(type == DEL_PREV_WORD)
|
||||
txt_backspace_word(text);
|
||||
else if(type == DEL_PREV_CHAR)
|
||||
@@ -1729,13 +1973,13 @@ void TEXT_OT_overwrite_toggle(wmOperatorType *ot)
|
||||
/******************* scroll operator **********************/
|
||||
|
||||
/* Moves the view vertically by the specified number of lines */
|
||||
static void screen_skip(SpaceText *st, int lines)
|
||||
static void screen_skip(SpaceText *st, ARegion *ar, int lines)
|
||||
{
|
||||
int last;
|
||||
|
||||
st->top += lines;
|
||||
st->top += lines;
|
||||
|
||||
last= txt_get_span(st->text->lines.first, st->text->lines.last);
|
||||
last= text_get_total_lines(st, ar);
|
||||
last= last - (st->viewlines/2);
|
||||
|
||||
if(st->top>last) st->top= last;
|
||||
@@ -1756,12 +2000,14 @@ typedef struct TextScroll {
|
||||
static int scroll_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
SpaceText *st= CTX_wm_space_text(C);
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
|
||||
int lines= RNA_int_get(op->ptr, "lines");
|
||||
|
||||
if(lines == 0)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
screen_skip(st, lines*U.wheellinescroll);
|
||||
screen_skip(st, ar, lines*U.wheellinescroll);
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
|
||||
@@ -1771,6 +2017,7 @@ static int scroll_exec(bContext *C, wmOperator *op)
|
||||
static void scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
SpaceText *st= CTX_wm_space_text(C);
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
TextScroll *tsc= op->customdata;
|
||||
short *mval= event->mval;
|
||||
|
||||
@@ -1792,7 +2039,7 @@ static void scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
|
||||
tsc->delta[1]= (tsc->hold[1]-mval[1])*st->pix_per_line;
|
||||
|
||||
if(tsc->delta[0] || tsc->delta[1]) {
|
||||
screen_skip(st, tsc->delta[1]);
|
||||
screen_skip(st, ar, tsc->delta[1]);
|
||||
|
||||
tsc->lines += tsc->delta[1];
|
||||
|
||||
@@ -1969,7 +2216,7 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
Text *text= st->text;
|
||||
TextLine **linep;
|
||||
int *charp;
|
||||
int w;
|
||||
int w, tabs;
|
||||
|
||||
text_update_character_width(st);
|
||||
|
||||
@@ -1987,16 +2234,28 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
x = (x/st->cwidth) + st->left;
|
||||
|
||||
if(st->wordwrap) {
|
||||
int i, j, endj, curs, max, chop, start, end, chars, loop;
|
||||
int i, j, endj, curs, max, chop, start, end, chars, loop, found;
|
||||
char ch;
|
||||
|
||||
/* Point to first visible line */
|
||||
*linep= text->lines.first;
|
||||
for(i=0; i<st->top && (*linep)->next; i++) *linep= (*linep)->next;
|
||||
i= st->top;
|
||||
while(i>0 && *linep) {
|
||||
int lines= text_get_visible_lines(st, ar, (*linep)->line);
|
||||
|
||||
if (i-lines<0) {
|
||||
y+= i;
|
||||
break;
|
||||
} else {
|
||||
*linep= (*linep)->next;
|
||||
i-= lines;
|
||||
}
|
||||
}
|
||||
|
||||
max= wrap_width(st, ar);
|
||||
|
||||
loop= 1;
|
||||
found= 0;
|
||||
while(loop && *linep) {
|
||||
start= 0;
|
||||
end= max;
|
||||
@@ -2004,12 +2263,14 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
chars= 0;
|
||||
curs= 0;
|
||||
endj= 0;
|
||||
tabs= 0;
|
||||
for(i=0, j=0; loop; j++) {
|
||||
|
||||
/* Mimic replacement of tabs */
|
||||
ch= (*linep)->line[j];
|
||||
if(ch=='\t') {
|
||||
chars= st->tabnumber-i%st->tabnumber;
|
||||
tabs+= chars-1;
|
||||
ch= ' ';
|
||||
}
|
||||
else
|
||||
@@ -2021,22 +2282,34 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
*charp= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
/* Exactly at the cursor, done */
|
||||
/* Exactly at the cursor */
|
||||
}
|
||||
else if(y==0 && i-start==x) {
|
||||
/* current position could be wrapped to next line */
|
||||
/* this should be checked when end of current line would be reached */
|
||||
*charp= curs= j;
|
||||
loop= 0;
|
||||
break;
|
||||
found= 1;
|
||||
/* Prepare curs for next wrap */
|
||||
}
|
||||
else if(i-end==x) {
|
||||
curs= j;
|
||||
}
|
||||
if(i-start>=max) {
|
||||
if(found) {
|
||||
/* exact cursor position was found, check if it's */
|
||||
/* still on needed line (hasn't been wrapped) */
|
||||
if(*charp>endj && !chop) (*charp)= endj;
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(chop) endj= j;
|
||||
y--;
|
||||
start= end;
|
||||
end += max;
|
||||
|
||||
if(start-tabs<(*linep)->len)
|
||||
y--;
|
||||
|
||||
chop= 1;
|
||||
if(y==0 && i-start>=x) {
|
||||
*charp= curs;
|
||||
@@ -2045,6 +2318,11 @@ static void set_cursor_to_pos(SpaceText *st, ARegion *ar, int x, int y, int sel)
|
||||
}
|
||||
}
|
||||
else if(ch==' ' || ch=='-' || ch=='\0') {
|
||||
if(found) {
|
||||
loop= 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(y==0 && i-start>=x) {
|
||||
*charp= curs;
|
||||
loop= 0;
|
||||
@@ -2102,7 +2380,7 @@ static void set_cursor_apply(bContext *C, wmOperator *op, wmEvent *event)
|
||||
|
||||
if(event->mval[1]<0 || event->mval[1]>ar->winy) {
|
||||
int d= (scu->old[1]-event->mval[1])*st->pix_per_line;
|
||||
if(d) screen_skip(st, d);
|
||||
if(d) screen_skip(st, ar, d);
|
||||
|
||||
set_cursor_to_pos(st, ar, event->mval[0], event->mval[1]<0?0:ar->winy, 1);
|
||||
|
||||
@@ -2290,6 +2568,8 @@ static int insert_exec(bContext *C, wmOperator *op)
|
||||
char *str;
|
||||
int done = 0, i;
|
||||
|
||||
text_drawcache_tag_update(st, 0);
|
||||
|
||||
str= RNA_string_get_alloc(op->ptr, "text", NULL, 0);
|
||||
|
||||
if(st && st->overwrite) {
|
||||
@@ -2396,6 +2676,7 @@ static int find_and_replace(bContext *C, wmOperator *op, short mode)
|
||||
}
|
||||
text_update_cursor_moved(C);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 1);
|
||||
}
|
||||
else if(mode==TEXT_MARK_ALL) {
|
||||
char color[4];
|
||||
@@ -2741,6 +3022,7 @@ void ED_text_undo_step(bContext *C, int step)
|
||||
text_update_edited(text);
|
||||
|
||||
text_update_cursor_moved(C);
|
||||
text_drawcache_tag_update(CTX_wm_space_text(C), 1);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_EDITED, text);
|
||||
}
|
||||
|
||||
|
||||
@@ -318,6 +318,8 @@ typedef struct SpaceText {
|
||||
|
||||
char findstr[256]; /* ST_MAX_FIND_STR */
|
||||
char replacestr[256]; /* ST_MAX_FIND_STR */
|
||||
|
||||
void *drawcache; /* cache for faster drawing */
|
||||
} SpaceText;
|
||||
|
||||
typedef struct Script {
|
||||
|
||||
Reference in New Issue
Block a user