forked from bartvdbraak/blender
Various UI drawing and event tweaks to make markers feel more natural and avoid getting in the way. If there is a marker under the cursor, ESC will remove it and others in its group. Otherwise all temporary markers are removed. Tab finds/cycles/removes temp. markers, cycles non-temp. markers (under cursor) and behaves normally in all other cases.
This commit is contained in:
parent
799ba2c351
commit
6c0f4660ed
@ -48,9 +48,10 @@ def main():
|
||||
if not txt:
|
||||
return
|
||||
|
||||
line, c = current_line(txt)
|
||||
row, c = txt.getCursorPos()
|
||||
line = txt.asLines()[row]
|
||||
indent=0
|
||||
while indent<len(line) and (line[indent]==' ' or line[indent]=='\t'):
|
||||
while indent<c and (line[indent]==' ' or line[indent]=='\t'):
|
||||
indent += 1
|
||||
|
||||
# Check we are in a normal context
|
||||
|
@ -108,6 +108,8 @@ struct TextMarker *txt_find_marker (struct Text *text, struct TextLine *line, i
|
||||
struct TextMarker *txt_find_marker_region (struct Text *text, struct TextLine *line, int start, int end, int flags);
|
||||
struct TextMarker *txt_prev_marker (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_next_marker (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_prev_marker_color (struct Text *text, struct TextMarker *marker);
|
||||
struct TextMarker *txt_next_marker_color (struct Text *text, struct TextMarker *marker);
|
||||
|
||||
/* Undo opcodes */
|
||||
|
||||
|
@ -83,12 +83,19 @@ The st->top determines at what line the top of the text is displayed.
|
||||
If the user moves the cursor the st containing that cursor should
|
||||
be popped ... other st's retain their own top location.
|
||||
|
||||
*/ /***************/
|
||||
Markers
|
||||
--
|
||||
The mrk->flags define the behaviour and relationships between markers. The
|
||||
upper two bytes are used to hold a group ID, the lower two are normal flags. If
|
||||
TMARK_EDITALL is set the group ID defines which other markers should be edited.
|
||||
|
||||
The mrk->clr field is used to visually group markers where the flags may not
|
||||
match. A template system, for example, may allow editing of repeating tokens
|
||||
(in one group) but include other marked positions (in another group) all in the
|
||||
same template with the same colour.
|
||||
|
||||
/****************/ /*
|
||||
Undo
|
||||
|
||||
Undo
|
||||
--
|
||||
Undo/Redo works by storing
|
||||
events in a queue, and a pointer
|
||||
to the current position in the
|
||||
@ -2657,6 +2664,13 @@ int setcurr_tab (Text *text)
|
||||
/* Text marker utility functions */
|
||||
/*********************************/
|
||||
|
||||
static int color_match(TextMarker *a, TextMarker *b) {
|
||||
return (a->clr[0]==b->clr[0] &&
|
||||
a->clr[1]==b->clr[1] &&
|
||||
a->clr[2]==b->clr[2] &&
|
||||
a->clr[3]==b->clr[3]);
|
||||
}
|
||||
|
||||
/* Creates and adds a marker to the list maintaining sorted order */
|
||||
void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4], int flags) {
|
||||
TextMarker *tmp, *marker;
|
||||
@ -2681,8 +2695,9 @@ void txt_add_marker(Text *text, TextLine *line, int start, int end, char clr[4],
|
||||
else BLI_addhead(&text->markers, marker);
|
||||
}
|
||||
|
||||
/* Returns the first matching marker on the specified line between two points
|
||||
If flags is zero, all markers will be searched */
|
||||
/* Returns the first matching marker on the specified line between two points,
|
||||
with at least the specified flags set. If flags is zero, all markers will be
|
||||
searched */
|
||||
TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
@ -2690,7 +2705,7 @@ TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int en
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if (flags && marker->flags != flags) continue;
|
||||
if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
@ -2701,8 +2716,8 @@ TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int en
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Clears all matching markers on the specified line between two points
|
||||
If flags is zero, all markers will be cleared */
|
||||
/* Clears all markers on the specified line between two points with at least
|
||||
the specified flags set. If flags is zero, all markers will be cleared */
|
||||
void txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
@ -2710,7 +2725,7 @@ void txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if (flags && marker->flags != flags) continue;
|
||||
if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
@ -2720,26 +2735,27 @@ void txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int
|
||||
}
|
||||
}
|
||||
|
||||
/* Clears all markers with matching flags (useful for clearing temporary markers) */
|
||||
/* Clears all markers with at least the specified flags set (useful for
|
||||
clearing temporary markers) */
|
||||
void txt_clear_markers(Text *text, int flags) {
|
||||
TextMarker *marker, *next;
|
||||
|
||||
for (marker=text->markers.first; marker; marker=next) {
|
||||
next= marker->next;
|
||||
|
||||
if (marker->flags == flags)
|
||||
if ((marker->flags & flags) == flags)
|
||||
BLI_freelinkN(&text->markers, marker);
|
||||
}
|
||||
}
|
||||
|
||||
/* Finds the marker at the specified line and cursor position with matching flags.
|
||||
If flags is zero, all markers will be searched */
|
||||
/* Finds the marker at the specified line and cursor position with at least the
|
||||
specified flags set. If flags is zero, all markers will be searched */
|
||||
TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int flags) {
|
||||
TextMarker *marker;
|
||||
int lineno= txt_get_span(text->lines.first, line);
|
||||
|
||||
for (marker=text->markers.first; marker; marker=marker->next) {
|
||||
if (flags && marker->flags != flags) continue;
|
||||
if ((marker->flags & flags) != flags) continue;
|
||||
else if (marker->lineno < lineno) continue;
|
||||
else if (marker->lineno > lineno) break;
|
||||
|
||||
@ -2749,8 +2765,8 @@ TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int flags) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finds the previous marker with matching flags. If no other marker is found, the
|
||||
same one will be returned */
|
||||
/* Finds the previous marker with matching flags. If no other marker is found,
|
||||
the same one will be returned */
|
||||
TextMarker *txt_prev_marker(Text *text, TextMarker *marker) {
|
||||
TextMarker *tmp= marker;
|
||||
while (tmp) {
|
||||
@ -2774,3 +2790,29 @@ TextMarker *txt_next_marker(Text *text, TextMarker *marker) {
|
||||
}
|
||||
return NULL; /* Only if marker==NULL */
|
||||
}
|
||||
|
||||
/* Finds the previous marker with matching colour. If no other marker is found,
|
||||
the same one will be returned */
|
||||
TextMarker *txt_prev_marker_color(Text *text, TextMarker *marker) {
|
||||
TextMarker *tmp= marker;
|
||||
while (tmp) {
|
||||
if (tmp->prev) tmp= tmp->prev;
|
||||
else tmp= text->markers.last;
|
||||
if (color_match(tmp, marker))
|
||||
return tmp;
|
||||
}
|
||||
return NULL; /* Only if marker==NULL */
|
||||
}
|
||||
|
||||
/* Finds the next marker with matching colour. If no other marker is found, the
|
||||
same one will be returned */
|
||||
TextMarker *txt_next_marker_color(Text *text, TextMarker *marker) {
|
||||
TextMarker *tmp= marker;
|
||||
while (tmp) {
|
||||
if (tmp->next) tmp= tmp->next;
|
||||
else tmp= text->markers.first;
|
||||
if (color_match(tmp, marker))
|
||||
return tmp;
|
||||
}
|
||||
return NULL; /* Only if marker==NULL */
|
||||
}
|
||||
|
@ -878,9 +878,9 @@ static void draw_cursor(SpaceText *st) {
|
||||
if (vcurl==vsell) {
|
||||
y -= vcurl*st->lheight;
|
||||
if (vcurc < vselc)
|
||||
glRecti(x+vcurc*spacetext_get_fontwidth(st), y, x+vselc*spacetext_get_fontwidth(st), y-st->lheight);
|
||||
glRecti(x+vcurc*spacetext_get_fontwidth(st)-1, y, x+vselc*spacetext_get_fontwidth(st), y-st->lheight);
|
||||
else
|
||||
glRecti(x+vselc*spacetext_get_fontwidth(st), y, x+vcurc*spacetext_get_fontwidth(st), y-st->lheight);
|
||||
glRecti(x+vselc*spacetext_get_fontwidth(st)-1, y, x+vcurc*spacetext_get_fontwidth(st), y-st->lheight);
|
||||
} else {
|
||||
int froml, fromc, tol, toc;
|
||||
if (vcurl < vsell) {
|
||||
@ -891,7 +891,7 @@ static void draw_cursor(SpaceText *st) {
|
||||
fromc= vselc; toc= vcurc;
|
||||
}
|
||||
y -= froml*st->lheight;
|
||||
glRecti(x+fromc*spacetext_get_fontwidth(st), y, curarea->winx, y-st->lheight); y-=st->lheight;
|
||||
glRecti(x+fromc*spacetext_get_fontwidth(st)-1, y, curarea->winx, y-st->lheight); y-=st->lheight;
|
||||
for (i=froml+1; i<tol; i++)
|
||||
glRecti(x-4, y, curarea->winx, y-st->lheight), y-=st->lheight;
|
||||
glRecti(x-4, y, x+toc*spacetext_get_fontwidth(st), y-st->lheight); y-=st->lheight;
|
||||
@ -1446,6 +1446,7 @@ void drawtextspace(ScrArea *sa, void *spacedata)
|
||||
|
||||
tmp= text->lines.first;
|
||||
for (i= 0; i<st->top && tmp; i++) {
|
||||
if (st->showsyntax && !tmp->format) txt_format_line(st, tmp, 0);
|
||||
tmp= tmp->next;
|
||||
linecount++;
|
||||
}
|
||||
@ -1504,7 +1505,7 @@ void pop_space_text (SpaceText *st)
|
||||
if(!st->text) return;
|
||||
if(!st->text->curl) return;
|
||||
|
||||
i= txt_get_span(st->text->lines.first, st->text->curl);
|
||||
i= txt_get_span(st->text->lines.first, st->text->sell);
|
||||
if (st->top+st->viewlines <= i || st->top > i) {
|
||||
st->top= i - st->viewlines/2;
|
||||
}
|
||||
@ -1512,7 +1513,7 @@ void pop_space_text (SpaceText *st)
|
||||
if (st->wordwrap) {
|
||||
st->left= 0;
|
||||
} else {
|
||||
x= text_draw(st, st->text->curl->line, st->left, st->text->curc, 0, 0, 0, NULL);
|
||||
x= text_draw(st, st->text->sell->line, st->left, st->text->selc, 0, 0, 0, NULL);
|
||||
|
||||
if (x==0 || x>curarea->winx) {
|
||||
st->left= st->text->curc-0.5*(curarea->winx)/spacetext_get_fontwidth(st);
|
||||
@ -1962,7 +1963,7 @@ void txt_find_panel(SpaceText *st, int again, int flags)
|
||||
int first= 1;
|
||||
do {
|
||||
if (first && (flags & TXT_FIND_MARKALL))
|
||||
txt_clear_markers(text, TMARK_EDITALL | TMARK_GRP_FINDALL);
|
||||
txt_clear_markers(text, TMARK_GRP_FINDALL);
|
||||
first= 0;
|
||||
|
||||
/* Replace current */
|
||||
@ -1975,11 +1976,11 @@ void txt_find_panel(SpaceText *st, int again, int flags)
|
||||
} else {
|
||||
char clr[4];
|
||||
BIF_GetThemeColor4ubv(TH_SHADE2, clr);
|
||||
if (txt_find_marker(text, text->curl, text->selc, TMARK_EDITALL | TMARK_GRP_FINDALL)) {
|
||||
if (txt_find_marker(text, text->curl, text->selc, TMARK_GRP_FINDALL)) {
|
||||
if (tmp) MEM_freeN(tmp), tmp=NULL;
|
||||
break;
|
||||
}
|
||||
txt_add_marker(text, text->curl, text->curc, text->selc, clr, TMARK_EDITALL | TMARK_GRP_FINDALL);
|
||||
txt_add_marker(text, text->curl, text->curc, text->selc, clr, TMARK_GRP_FINDALL | TMARK_EDITALL);
|
||||
}
|
||||
}
|
||||
MEM_freeN(tmp);
|
||||
@ -2256,10 +2257,33 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va
|
||||
int c, s, draw=0, swallow=0;
|
||||
|
||||
text= st->text;
|
||||
if (!text || text->curl != text->sell) return 0;
|
||||
if (!text || text->id.lib || text->curl != text->sell) return 0;
|
||||
|
||||
marker= txt_find_marker(text, text->curl, text->curc, 0);
|
||||
if (!marker || text->id.lib) return 0;
|
||||
if (!marker) {
|
||||
/* Find the next temporary marker */
|
||||
if (evnt==TABKEY) {
|
||||
int lineno= txt_get_span(text->lines.first, text->curl);
|
||||
TextMarker *mrk= text->markers.first;
|
||||
while (mrk) {
|
||||
if (!marker && (mrk->flags & TMARK_TEMP)) marker= mrk;
|
||||
if ((mrk->flags & TMARK_TEMP) && (mrk->lineno > lineno || (mrk->lineno==lineno && mrk->end > text->curc))) {
|
||||
marker= mrk;
|
||||
break;
|
||||
}
|
||||
mrk= mrk->next;
|
||||
}
|
||||
if (marker) {
|
||||
txt_move_to(text, marker->lineno, marker->start, 0);
|
||||
txt_move_to(text, marker->lineno, marker->end, 1);
|
||||
pop_space_text(st);
|
||||
evnt= ascii= val= 0;
|
||||
draw= 1;
|
||||
swallow= 1;
|
||||
}
|
||||
}
|
||||
if (!swallow) return 0;
|
||||
}
|
||||
|
||||
if (ascii) {
|
||||
if (marker->flags & TMARK_EDITALL) {
|
||||
@ -2351,6 +2375,8 @@ static short do_markers(SpaceText *st, char ascii, unsigned short evnt, short va
|
||||
break;
|
||||
|
||||
/* Events that should clear markers */
|
||||
case UKEY: if (!(G.qual & LR_ALTKEY)) break;
|
||||
case ZKEY: if (evnt==ZKEY && !(G.qual & LR_CTRLKEY)) break;
|
||||
case RETKEY:
|
||||
case ESCKEY:
|
||||
if (marker->flags & (TMARK_EDITALL | TMARK_TEMP))
|
||||
@ -2808,17 +2834,11 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
indent(text);
|
||||
if (st->showsyntax) txt_format_text(st);
|
||||
}
|
||||
} else {
|
||||
TextMarker *mrk= txt_find_marker_region(text, text->curl, 0, text->curl->len, 0);
|
||||
if (mrk) {
|
||||
txt_move_to(text, mrk->lineno, mrk->start, 0);
|
||||
txt_move_to(text, mrk->lineno, mrk->end, 1);
|
||||
} else {
|
||||
txt_add_char(text, '\t');
|
||||
if (st->showsyntax) txt_format_line(st, text->curl, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
pop_space_text(st);
|
||||
do_draw= 1;
|
||||
st->currtab_set = setcurr_tab(text);
|
||||
@ -2848,6 +2868,9 @@ void winqreadtextspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
do_draw= 1;
|
||||
pop_space_text(st);
|
||||
break;
|
||||
case ESCKEY:
|
||||
txt_clear_markers(text, TMARK_TEMP);
|
||||
break;
|
||||
case BACKSPACEKEY:
|
||||
if (text && text->id.lib) {
|
||||
error_libdata();
|
||||
|
Loading…
Reference in New Issue
Block a user