summaryrefslogtreecommitdiff
path: root/src/glibext/gbufferline.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-04-09 20:29:54 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-04-09 20:29:54 (GMT)
commitf38d8af1713a2a46a8c2d4499081bd0d123af163 (patch)
tree16c1439de2a396cbb8dc8231b8d1c5beabca49b1 /src/glibext/gbufferline.c
parent944225261e872785366d1df5377f59ea917a2195 (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.c257
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;
}