summaryrefslogtreecommitdiff
path: root/src/glibext/gbufferline.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-04-11 20:01:03 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-04-11 20:01:03 (GMT)
commit7bd707cb43ed8830add9d9eec3a670c9a0ce4d68 (patch)
tree0ae304fd09046f67dfe41760e254cc3ebd6d8b94 /src/glibext/gbufferline.c
parentb66aa52128ad47d7130f087509535989d507d15b (diff)
Fixed the remaining bugs in all kinds of navigation in buffer views.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@509 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/glibext/gbufferline.c')
-rw-r--r--src/glibext/gbufferline.c204
1 files changed, 193 insertions, 11 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index e34f86f..d763e9d 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -69,7 +69,7 @@ static bool column_has_segment(const buffer_line_column *, const GBufferSegment
#define get_last_segment(col) ((col)->count > 0 ? (col)->segments[(col)->count - 1] : NULL)
/* Donne le segment d'une colonne présent à une abscisse donnée. */
-static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScrollDirection);
+static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScrollDirection, gint *);
/* Fournit le segment voisin d'un autre segment identifié. */
static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection);
@@ -235,9 +235,10 @@ static bool column_has_segment(const buffer_line_column *column, const GBufferSe
/******************************************************************************
* *
-* Paramètres : column = colonne de ligne de texte à consulter. *
-* x = position de recherche à ajuster. [OUT] *
-* dir = direction d'un éventuel déplacement en cours. *
+* Paramètres : column = colonne de ligne de texte à consulter. *
+* x = position de recherche, puis position locale. [OUT]*
+* dir = direction d'un éventuel déplacement en cours. *
+* consumed = distance pour arriver à la base du segment. [OUT] *
* *
* Description : Donne le segment d'une colonne présent à une abscisse donnée.*
* *
@@ -247,7 +248,7 @@ static bool column_has_segment(const buffer_line_column *column, const GBufferSe
* *
******************************************************************************/
-static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir)
+static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir, gint *consumed)
{
GBufferSegment *result; /* Trouvaille à retourner */
size_t i; /* Boucle de parcours */
@@ -255,6 +256,7 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
bool included; /* Appartenance à une largeur ?*/
result = NULL;
+ *consumed = 0;
printf(" == gs@ == count = %d width = %d\n",
column->count, get_column_width(column));
@@ -277,11 +279,20 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
if (dir == GDK_SCROLL_LEFT) included = (width >= *x);
else included = (width > *x);
- if (included || (i + 1) == column->count)
+ if (included)
result = column->segments[i];
+ else if ((i + 1) == column->count)
+ {
+ result = column->segments[i];
+ *x = width;
+ }
+
else
+ {
*x -= width;
+ *consumed += width;
+ }
}
@@ -753,7 +764,8 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* Paramètres : line = ligne à venir consulter. *
* max_widths = largeurs de colonne à respecter. *
* display = règles d'affichage des colonnes modulables. *
-* x = position à la colonne visée. [OUT] *
+* base = position jusqu'au segment trouvé. [OUT] *
+* offset = position à la colonne visée. [OUT] *
* dir = direction d'un éventuel déplacement en cours. *
* force = accepte les segments en bordure au pire. *
* *
@@ -765,7 +777,164 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe
* *
******************************************************************************/
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], const bool *display, gint *x, GdkScrollDirection dir, bool force)
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force)
+{
+ GBufferSegment *result; /* Trouvaille à retourner */
+ BufferLineColumn last; /* Dernière colonne remplie */
+ gint last_base; /* Dernière abscisse associée */
+ BufferLineColumn i; /* Boucle de parcours */
+ gint width; /* Largeur d'une colonne donnée*/
+
+ gint limit;
+
+ gint consumed; /* Distance vers le segment */
+ gint old_base; /* Somme de toutes les largeurs*/
+
+ result = NULL;
+
+ *base = 0;
+
+ last = BLC_COUNT;
+
+ //sum = 0;
+
+ printf("---------------\n");
+
+ /* On cible déjà la colonne idéale */
+
+ for (i = 0; i < BLC_COUNT; i++)
+ {
+ printf(" @ (%d) x=%d width=%d max=%d display ? %d\n",
+ i, *offset, get_column_width(&line->columns[i]), max_widths[i], i < BLC_DISPLAY ? display[i] : true);
+
+
+ if (i < BLC_DISPLAY && !display[i]) continue;
+
+ /* Mémorisation de la dernière colonne contenant quelque chose... */
+ if (get_column_width(&line->columns[i]) > 0)
+ {
+ last = i;
+ last_base = *base;
+ }
+
+ if (i < line->merge_start)
+ {
+ width = max_widths[i];
+
+ if ((i + 1) < BLC_COUNT) limit = width + COL_MARGIN / 2;
+ else limit = width;
+
+ if (*offset <= limit) break;
+ else
+ {
+ *offset -= width + COL_MARGIN;
+ *base += width + COL_MARGIN;
+ }
+
+ }
+ else
+ {
+ width = get_column_width(&line->columns[i]);
+
+ if (*offset <= width) break;
+ else
+ {
+ *offset -= width;
+ *base += width;
+ }
+
+ }
+
+
+ }
+
+ printf(" -- get segment at -- found index %u (max=%u)\n", i, BLC_COUNT);
+
+
+ printf(" last seen = %u\n", last);
+
+
+
+
+
+ if (i < BLC_COUNT)
+ {
+
+ printf(" -- width @ %u : %d\n", i, get_column_width(&line->columns[i]));
+
+ if (get_column_width(&line->columns[i]) > 0)
+ {
+ /**
+ * Si la position était au milieu d'une marge, la sélection a pu pousser
+ * jusqu'à la colonne suivante, plus proche.
+ * Relativment à la base de cette dernière, la position est donc devenue négative.
+ */
+ if (*offset < 0) *offset = 0;
+
+ result = get_segment_at(&line->columns[i], offset, dir, &consumed);
+ *base += consumed;
+ }
+
+ /* La position fournie tombe dans une colonne vide ! */
+ else
+ {
+ if (force || get_column_width(&line->columns[i]) == 0)
+ {
+ result = NULL;
+ *offset = 0;
+
+ old_base = *base;
+
+ for (i++; i < BLC_COUNT && result == NULL; i++)
+ {
+ printf(" -- update to col %u -- x = %d\n", i, *offset);
+
+ if ((i - 1) < line->merge_start)
+ *base += (max_widths[i - 1] + COL_MARGIN);
+ else
+ *base += get_column_width(&line->columns[i - 1]);
+
+ result = get_first_segment(&line->columns[i]);
+
+ }
+
+ printf(" -- final x = %d (result=%p)\n", *offset, result);
+
+ if (result == NULL)
+ {
+ *base = old_base;
+ goto use_right_border;
+ }
+
+ }
+
+ }
+
+ }
+
+ else /* if (i == BLC_COUNT) */
+ {
+ if (force && last != BLC_COUNT)
+ {
+ use_right_border:
+
+ result = get_last_segment(&line->columns[last]);
+ *base = last_base;
+ *offset = get_column_width(&line->columns[last]);
+
+ }
+ else
+ result = NULL;
+
+ }
+
+ return result;
+
+}
+
+
+#if 0
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], const bool *display, gint *base, gint *offset, GdkScrollDirection dir, bool force)
{
GBufferSegment *result; /* Trouvaille à retourner */
gint old; /* Valeur d'origine de position*/
@@ -774,6 +943,7 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
gint sum; /* Somme de toutes les largeurs*/
BufferLineColumn i; /* Boucle de parcours */
gint width; /* Largeur d'une colonne donnée*/
+ gint consumed; /* Distance vers le segment */
result = NULL;
@@ -805,12 +975,13 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
if (i < line->merge_start)
{
width = max_widths[i];
+ if ((i + 1) < BLC_COUNT) width += COL_MARGIN;
if (*x <= width) break;
else
{
- *x -= (max_widths[i] + COL_MARGIN);
- sum += width + COL_MARGIN;
+ *x -= width;
+ sum += width;
}
}
@@ -845,7 +1016,10 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
printf(" -- width @ %u : %d\n", i, get_column_width(&line->columns[i]));
if (get_column_width(&line->columns[i]) > 0)
- result = get_segment_at(&line->columns[i], x, dir);
+ {
+ result = get_segment_at(&line->columns[i], x, dir, &consumed);
+ *x += sum + consumed;
+ }
/* La position fournie tombe dans une colonne vide ! */
else
@@ -870,6 +1044,9 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
printf(" -- final x = %d (result=%p)\n", *x, result);
+ if (result == NULL)
+ goto use_right_border;
+
}
}
@@ -880,8 +1057,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
{
if (force && last != BLC_COUNT)
{
+ use_right_border:
+
result = get_last_segment(&line->columns[last]);
*x = last_x + get_column_width(&line->columns[last]);
+
}
else
result = NULL;
@@ -891,6 +1071,8 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint
return result;
}
+#endif
+
/******************************************************************************