Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-10-01 16:27:11 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-10-01 16:34:24 +0300
commit066df84f730d213c3e6ea875c202aa46cf1a6642 (patch)
tree877e5db3d9abaf7a93b59d612870eaf908862ff4 /source/blender/editors/space_text
parent29c2a6469427b7c43d815188af7e7ed3f79f486c (diff)
Fix T46340: Auto scrolling in text editor with upward selection not work.
Cleanup and rework a bit text_cursor_set_to_pos_wrapped(), it did not handle correctly negative y valuesi, because it was only checking lines starting from first visible one. Mostly, we now directly get line matching given y position (be it an invisible one) from the helper (renamed `get_line_pos_wrapped()`), instead of first visible one, which allows us to get rid of additional complexity of looping over next lines until we find correct one. This code remains rather complex to follow, added some asserts to ensure everything works as expected, and tested it rather seriously, but DO NOT backport this to 2.76!
Diffstat (limited to 'source/blender/editors/space_text')
-rw-r--r--source/blender/editors/space_text/text_ops.c108
1 files changed, 56 insertions, 52 deletions
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 543fa0a0f72..060bf241bcf 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -2367,21 +2367,23 @@ static int flatten_column_to_offset(SpaceText *st, const char *str, int index)
return j;
}
-static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y)
+static TextLine *get_line_pos_wrapped(SpaceText *st, ARegion *ar, int *y)
{
TextLine *linep = st->text->lines.first;
- int i;
- for (i = st->top; i > 0 && linep; ) {
- int lines = text_get_visible_lines(st, ar, linep->line);
-
- if (i - lines < 0) {
- *y += i;
+ int i, lines;
+
+ if (*y < -st->top) {
+ return NULL; /* We are beyond the first line... */
+ }
+
+ for (i = -st->top; i <= *y && linep; linep = linep->next, i += lines) {
+ lines = text_get_visible_lines(st, ar, linep->line);
+
+ if (i + lines > *y) {
+ /* We found the line matching given vertical 'coordinate', now set y relative to this line's start. */
+ *y -= i;
break;
}
- else {
- linep = linep->next;
- i -= lines;
- }
}
return linep;
}
@@ -2391,23 +2393,22 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
Text *text = st->text;
int max = wrap_width(st, ar); /* column */
int charp = -1; /* mem */
- int loop = 1, found = 0; /* flags */
- char ch;
-
- /* Point to first visible line */
- TextLine *linep = get_first_visible_line(st, ar, &y);
+ bool found = false; /* flags */
- while (loop && linep) {
+ /* Point to line matching given y position, if any. */
+ TextLine *linep = get_line_pos_wrapped(st, ar, &y);
+
+ if (linep) {
int i = 0, start = 0, end = max; /* column */
- int j = 0, curs = 0, endj = 0; /* mem */
- int chop = 1; /* flags */
-
- for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) {
+ int j, curs = 0, endj = 0; /* mem */
+ bool chop = true; /* flags */
+ char ch;
+
+ for (j = 0 ; !found && ((ch = linep->line[j]) != '\0'); j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
- ch = linep->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
@@ -2420,7 +2421,8 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
/* Gone too far, go back to last wrap point */
if (y < 0) {
charp = endj;
- loop = 0;
+ y = 0;
+ found = true;
break;
/* Exactly at the cursor */
}
@@ -2428,7 +2430,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
charp = curs = j;
- found = 1;
+ found = true;
/* Prepare curs for next wrap */
}
else if (i - end <= x && i + columns - end > x) {
@@ -2438,68 +2440,70 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
end = MIN2(end, i);
if (found) {
- /* exact cursor position was found, check if it's */
- /* still on needed line (hasn't been wrapped) */
- if (charp > endj && !chop && ch != '\0') charp = endj;
- loop = 0;
+ /* exact cursor position was found, check if it's still on needed line (hasn't been wrapped) */
+ if (charp > endj && !chop && ch != '\0')
+ charp = endj;
break;
}
- if (chop) endj = j;
+ if (chop)
+ endj = j;
start = end;
end += max;
if (j < linep->len)
y--;
- chop = 1;
+ chop = true;
if (y == 0 && i + columns - start > x) {
charp = curs;
- loop = 0;
+ found = true;
break;
}
}
else if (ch == ' ' || ch == '-' || ch == '\0') {
if (found) {
- loop = 0;
break;
}
if (y == 0 && i + columns - start > x) {
charp = curs;
- loop = 0;
+ found = true;
break;
}
end = i + 1;
endj = j;
- chop = 0;
+ chop = false;
}
i += columns;
}
-
- if (ch == '\0') break;
- }
-
- if (!loop || found) break;
-
- if (!linep->next) {
- charp = linep->len;
- break;
}
+
+ BLI_assert(y == 0);
- /* On correct line but didn't meet cursor, must be at end */
- if (y == 0) {
+ if (!found) {
+ /* On correct line but didn't meet cursor, must be at end */
charp = linep->len;
- break;
}
- linep = linep->next;
-
- y--;
+ }
+ else if (y < 0) { /* Before start of text. */
+ linep = st->text->lines.first;
+ charp = 0;
+ }
+ else { /* Beyond end of text */
+ linep = st->text->lines.last;
+ charp = linep->len;
}
- if (linep && charp != -1) {
- if (sel) { text->sell = linep; text->selc = charp; }
- else { text->curl = linep; text->curc = charp; }
+ BLI_assert(linep && charp != -1);
+
+ if (sel) {
+ text->sell = linep;
+ text->selc = charp;
+ }
+ else {
+ text->curl = linep;
+ text->curc = charp;
}
}