diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-04-09 20:29:54 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-04-09 20:29:54 (GMT) |
commit | f38d8af1713a2a46a8c2d4499081bd0d123af163 (patch) | |
tree | 16c1439de2a396cbb8dc8231b8d1c5beabca49b1 /src/glibext/gbufferline.c | |
parent | 944225261e872785366d1df5377f59ea917a2195 (diff) |
Fixed all known bugs with the keyboard-based navigation in buffer views.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@507 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/glibext/gbufferline.c')
-rw-r--r-- | src/glibext/gbufferline.c | 257 |
1 files changed, 147 insertions, 110 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 0422af5..e34f86f 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -62,6 +62,9 @@ static gint get_column_width(const buffer_line_column *); /* Ajoute un fragment de texte à une colonne de ligne. */ static void add_segment_to_column(buffer_line_column *, GBufferSegment *); +/* Valide ou non la présence d'un segment dans une colonne. */ +static bool column_has_segment(const buffer_line_column *, const GBufferSegment *, size_t *); + #define get_first_segment(col) ((col)->count > 0 ? (col)->segments[0] : NULL) #define get_last_segment(col) ((col)->count > 0 ? (col)->segments[(col)->count - 1] : NULL) @@ -69,7 +72,7 @@ static void add_segment_to_column(buffer_line_column *, GBufferSegment *); static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScrollDirection); /* Fournit le segment voisin d'un autre segment identifié. */ -static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection, bool *); +static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection); /* Met en surbrillance des segments similaires. */ static GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *); @@ -202,6 +205,36 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se /****************************************************************************** * * +* Paramètres : column = colonne de ligne à venir consulter. * +* segment = fragment de texte à trouver dans la colonne. * +* index = indice du segment retrouvé ou NULL. [OUT] * +* * +* Description : Valide ou non la présence d'un segment dans une colonne. * +* * +* Retour : Statut de présence du segment indiqué. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool column_has_segment(const buffer_line_column *column, const GBufferSegment *segment, size_t *index) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < column->count; i++) + if (column->segments[i] == segment) + { + if (index != NULL) *index = i; + break; + } + + return (i < column->count); + +} + + +/****************************************************************************** +* * * Paramètres : column = colonne de ligne de texte à consulter. * * x = position de recherche à ajuster. [OUT] * * dir = direction d'un éventuel déplacement en cours. * @@ -264,7 +297,6 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, * Paramètres : column = colonne de ligne de texte à consulter. * * target = segment dont un voisin est à retourner. * * dir = orientation des recherches. * -* out = renvoie vers une bordure extérieur au besoin. [OUT] * * * * Description : Fournit le segment voisin d'un autre segment identifié. * * * @@ -274,29 +306,25 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, * * ******************************************************************************/ -static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir, bool *out) +static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir) { GBufferSegment *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ result = NULL; - *out = false; - for (i = 0; i < column->count; i++) - if (column->segments[i] == target) break; + column_has_segment(column, target, &i); if (i < column->count) switch (dir) { case GDK_SCROLL_LEFT: - *out = (i == 0); - if (!*out) + if (i > 0) result = column->segments[i - 1]; break; case GDK_SCROLL_RIGHT: - *out = ((i + 1) == column->count); - if (!*out) + if ((i + 1) < column->count) result = column->segments[i + 1]; break; @@ -743,6 +771,7 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint gint old; /* Valeur d'origine de position*/ BufferLineColumn last; /* Dernière colonne remplie */ gint last_x; /* Dernière abscisse associée */ + gint sum; /* Somme de toutes les largeurs*/ BufferLineColumn i; /* Boucle de parcours */ gint width; /* Largeur d'une colonne donnée*/ @@ -752,10 +781,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint last = BLC_COUNT; last_x = *x; /* Pour GCC */ - printf(" {{ ADDR }} 0x%08x\n", line->range.addr.physical); - + sum = 0; + printf("---------------\n"); + /* On cible déjà la colonne idéale */ for (i = 0; i < BLC_COUNT; i++) { @@ -769,7 +799,7 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint if (get_column_width(&line->columns[i]) > 0) { last = i; - last_x = *x; + last_x = sum; } if (i < line->merge_start) @@ -777,7 +807,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint width = max_widths[i]; if (*x <= width) break; - else *x -= (max_widths[i] + COL_MARGIN); + else + { + *x -= (max_widths[i] + COL_MARGIN); + sum += width + COL_MARGIN; + } } else @@ -785,7 +819,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint width = get_column_width(&line->columns[i]); if (*x <= width) break; - else *x -= width; + else + { + *x -= width; + sum += width; + } } @@ -799,59 +837,57 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint - if (force) + + + if (i < BLC_COUNT) { - if (i == BLC_COUNT) - { - /* Re-calcul des largeurs cumulées */ + printf(" -- width @ %u : %d\n", i, get_column_width(&line->columns[i])); - if (last == BLC_COUNT) i = BLC_COUNT; - else + if (get_column_width(&line->columns[i]) > 0) + result = get_segment_at(&line->columns[i], x, dir); + + /* La position fournie tombe dans une colonne vide ! */ + else + { + if (force || get_column_width(&line->columns[i]) == 0) { - *x = old; + result = NULL; + *x = sum; - for (i = 0; i < last; i++) + for (i++; i < BLC_COUNT && result == NULL; i++) { - if (i < line->merge_start) - *x -= (max_widths[i] + COL_MARGIN); - else - *x -= get_column_width(&line->columns[i]); - } + printf(" -- update to col %u -- x = %d\n", i, *x); - } + if ((i - 1) < line->merge_start) + *x += (max_widths[i - 1] + COL_MARGIN); + else + *x += get_column_width(&line->columns[i - 1]); + result = get_first_segment(&line->columns[i]); - printf(" -- get segment at -- last index %u (max=%u) -->> x = %d\n", i, BLC_COUNT, *x); + } + printf(" -- final x = %d (result=%p)\n", *x, result); + } } - /* Si on s'est arrêté sur un champ vide... */ - else if (i != last) + } + + else /* if (i == BLC_COUNT) */ + { + if (force && last != BLC_COUNT) { - i = last; - *x = last_x; + result = get_last_segment(&line->columns[last]); + *x = last_x + get_column_width(&line->columns[last]); } + else + result = NULL; } - - - - - if (i < BLC_COUNT) - result = get_segment_at(&line->columns[i], x, dir); - - - if (result == NULL) - printf(" -- get segment at -- found nothing...\n"); - else - printf(" -- get segment at -- found %p '%s'...\n", result, g_buffer_segment_get_text(result, false)); - - - return result; } @@ -861,10 +897,10 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint * * * Paramètres : line = ligne à venir consulter. * * target = segment dont un voisin est à retourner. * -* max_widths = largeurs de colonne à respecter. XXXXXXXXXXXXXXX * +* max_widths = largeurs de colonne à respecter. * * display = règles d'affichage des colonnes modulables. * * dir = orientation des recherches. * -* offset = décalage pour amener à l'extrémité voisine. [OUT] * +* offset = décalage pour amener à l'extrémité nouvelle. [OUT] * * * * Description : Fournit le segment voisin d'un autre segment identifié. * * * @@ -877,93 +913,94 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBufferSegment *target, const gint max_widths[BLC_COUNT], const bool *display, GdkScrollDirection dir, gint *offset) { GBufferSegment *result; /* Trouvaille à retourner */ - BufferLineColumn i; /* Boucle de parcours */ - bool out; /* Présence de cible en bordure*/ + BufferLineColumn i; /* Boucle de parcours #1 */ + bool displayed; /* Confort de lecture */ + BufferLineColumn k; /* Boucle de parcours #2 */ result = NULL; - *offset = 0; - for (i = 0; i < BLC_COUNT && result == NULL; i++) - { - if (i < BLC_DISPLAY && !display[i]) continue; + /* Recherche dans la colonne de départ */ + + for (i = 0; i < BLC_COUNT; i++) + if (column_has_segment(&line->columns[i], target, NULL)) + break; - result = find_near_segment(&line->columns[i], target, dir, &out); + if (i == BLC_COUNT) return NULL; - printf(" [%d] near seg = %p (out ? %d)\n", i, result, out); + result = find_near_segment(&line->columns[i], target, dir); + if (result != NULL) return result; - if (result != NULL) break; + /* Recherche dans la direction des colonnes voisines */ - if (out) + if (result == NULL) + switch (dir) { - switch (dir) - { - case GDK_SCROLL_LEFT: + case GDK_SCROLL_LEFT: + + /* Si on a atteint la première colonne sans trouver... */ + if (i == 0) break; - gblfns_loop_left: + /* On s'assure que la colonne précédente est visible et peuplée */ + for (; i > BLC_FIRST && result == NULL; i--) + { + displayed = (i <= BLC_DISPLAY ? display[i - 1] : true); - /* On s'assure que la colonne précédente est visible */ - if (i <= BLC_DISPLAY) - for (; i > BLC_FIRST; i--) - if (display[i - 1]) break; + if (displayed) + result = get_last_segment(&line->columns[i - 1]); - if (i > BLC_FIRST) result = get_last_segment(&line->columns[i - 1]); + } - printf(" [near] (%d) %p\n", i, result); + break; - if (result == NULL && i > BLC_FIRST) - { - printf(" [loop] %u -> %u\n", i, i - 1); - i--; - *offset -= (max_widths[i] + COL_MARGIN); - goto gblfns_loop_left; - } + case GDK_SCROLL_RIGHT: - if (result != NULL) - *offset += g_buffer_segment_get_width(result) - max_widths[i - 1] - COL_MARGIN; + /* Si on a atteint la dernière colonne sans trouver... */ + /*if (i == BLC_COUNT) break;*/ - break; + /* On s'assure que la colonne suivante est visible et peuplée */ + for (; (i + 1) < BLC_COUNT && result == NULL; i++) + { + displayed = ((i + 1) < BLC_DISPLAY ? display[i + 1] : true); - case GDK_SCROLL_RIGHT: + if (displayed) + result = get_first_segment(&line->columns[i + 1]); - gblfns_loop_right: + } - /* On s'assure que la colonne suivante est visible */ - for (; (i + 1) < BLC_DISPLAY; i++) - if (display[i + 1]) break; + break; - if ((i + 1) < BLC_COUNT) result = get_first_segment(&line->columns[i + 1]); + default: + break; + } - printf(" [near] (%d) %p\n", i, result); + /* Calcul de la position finale */ - if (result == NULL && (i + 1) < BLC_COUNT) - { - printf(" [loop] %u -> %u\n", i, i + 1); - *offset += (max_widths[i] + COL_MARGIN); - printf(" -- add %d ~> %d\n", max_widths[i], *offset); - i++; - goto gblfns_loop_right; - } + if (result != NULL) + { + *offset = 0; - if (result != NULL) - { - *offset -= g_buffer_segment_get_width(target); - *offset += max_widths[i] + COL_MARGIN; - printf(" -- add %d ~> %d\n", max_widths[i], *offset); - } + for (k = 0; k < i; k++) + { + displayed = (k < BLC_DISPLAY ? display[k] : true); + if (displayed) + *offset += max_widths[k] + COL_MARGIN; - /* - if (result != NULL) - *offset += max_widths[i + 1] - g_buffer_segment_get_width(result) + COL_MARGIN; - */ + } - break; + switch (dir) + { + case GDK_SCROLL_LEFT: + *offset += get_column_width(&line->columns[i]); + break; - default: - break; + case GDK_SCROLL_RIGHT: + /**offset += 0;*/ + break; - } + default: + break; } |