summaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/glibext/gbufferline.c204
-rw-r--r--src/glibext/gbufferline.h2
-rw-r--r--src/glibext/gcodebuffer.c85
-rw-r--r--src/gtkext/gtkbufferview.c3
4 files changed, 219 insertions, 75 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
+
/******************************************************************************
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 3a00ce0..e8916ac 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -113,7 +113,7 @@ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize,
void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated));
/* Donne le segment présent à une abscisse donnée. */
-GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], const bool *, gint *, GdkScrollDirection, bool);
+GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], const bool *, gint *, gint *, GdkScrollDirection, bool);
/* Fournit le segment voisin d'un autre segment identifié. */
GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegment *, const gint [BLC_COUNT], const bool *, GdkScrollDirection, gint *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 4b4b2a6..f7c7cd6 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -1303,7 +1303,8 @@ GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x,
else
{
*x -= view->left_text;
- *segment = g_buffer_line_get_segment_at(result, view->max_widths, display, x, GDK_SCROLL_LEFT, true);
+ *segment = g_buffer_line_get_segment_at(result, view->max_widths, display,
+ (gint []) { 0 }, x, GDK_SCROLL_LEFT, true);
}
}
@@ -1388,26 +1389,20 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, con
const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret)
{
- gint tmp_x; /* Copie de travail modifiable */
+ gint offset; /* Point de travail modifiable */
+ gint base; /* Position absolue de segment */
GBufferSegment *segment; /* Segment visé par le pointeur*/
size_t first; /* Première ligne intégrée */
- tmp_x = x;
+ offset = x;
- tmp_x -= view->left_text;
- if (tmp_x < 0) return NULL;
+ offset -= view->left_text;
+ if (offset < 0) return NULL;
- segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &tmp_x, GDK_SCROLL_LEFT, true);
- if (segment == NULL) printf(" -- no segment OLD\n");
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &base, &offset, GDK_SCROLL_LEFT, true);
if (segment == NULL) return NULL;
- printf("\n[BASE OLD] tronc = %d reste = %d dernier = %d largeur = %d\n",
- x - tmp_x, tmp_x, g_buffer_segment_get_caret_position(segment, tmp_x),
- g_buffer_segment_get_width(segment));
-
- printf(" '%s'\n", g_buffer_segment_get_text(segment, false));
-
- caret->x = view->left_text + tmp_x;//(x - tmp_x) + g_buffer_segment_get_caret_position(segment, tmp_x);
+ caret->x = view->left_text + base + offset;
first = g_code_buffer_get_index_from_address(view->buffer, view->start, true);
caret->y = (index - first) * view->line_height;
@@ -1438,25 +1433,21 @@ const vmpa2t *g_buffer_view_compute_caret_full(GBufferView *view, GBufferLine *l
static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display)
{
- bool result;
-
- gint tmp_x; /* Copie de travail modifiable */
+ bool result; /* Bilan à retourner */
+ gint offset; /* Point de travail modifiable */
+ gint base; /* Position absolue de segment */
GBufferSegment *segment; /* Segment visé par le pointeur*/
size_t first; /* Première ligne intégrée */
gint ref_x;
- gint offset;
-
+ offset = caret->x;
+ offset -= view->left_text;
+ if (offset < 0) return false;
- tmp_x = caret->x;
-
- tmp_x -= view->left_text;
- if (tmp_x < 0) return false;
-
- segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &tmp_x, dir, false);
+ segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &base, &offset, dir, false);
if (segment == NULL) printf(" ===== NO SEG...\n");
@@ -1467,25 +1458,22 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
- ref_x = tmp_x;
+ ref_x = offset;
//if (dir == GDK_SCROLL_LEFT || dir == GDK_SCROLL_RIGHT)
- result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir);
+ result = g_buffer_segment_move_caret(segment, &offset, ctrl, dir);
//else
//result = true;
printf(" ====== MOVE 1 ? %d\n", result);
- if (result)
- caret->x += (tmp_x - ref_x);
-
///////////////////
if (!result)
{
-
+ base = 0;
segment = g_buffer_line_find_near_segment(line, segment, view->max_widths, display, dir, &offset);
@@ -1494,20 +1482,9 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
if (segment != NULL)
{
- //tmp_x = /*ref_x + */g_buffer_segment_get_width(segment);
-
-
- //ref_x = tmp_x;
- ref_x = tmp_x = 0;
-
-
- ref_x = 0;
- tmp_x = view->left_text + offset;
-
- caret->x = tmp_x;
result = true;
- //result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir);
+ //result = g_buffer_segment_move_caret(segment, &offset, ctrl, dir);
/*
if (result)
@@ -1524,33 +1501,17 @@ static bool _g_buffer_view_move_caret(GBufferView *view, const GBufferLine *line
if (result)
- printf(" ====== NEW CARET: %d -> %d\n", caret->x, caret->x + (tmp_x - ref_x));
+ printf(" ====== NEW CARET: %d -> %d\n", caret->x, view->left_text + base + offset);
else
printf(" ====== NO NEW CARET!\n");
- /*
- if (result)
- caret->x += (tmp_x - ref_x);
- */
+ if (result)
+ caret->x = view->left_text + base + offset;
return result;
-
- //bool g_buffer_segment_move_caret(const GBufferSegment *segment, gint *x, bool ctrl, GdkScrollDirection dir)
-
-
-
- /* TODO : utiliser les arguments booléens */
-
- caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10);
-
- return true;
-
-
- return false;
-
}
diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c
index ef4f985..ef5aac6 100644
--- a/src/gtkext/gtkbufferview.c
+++ b/src/gtkext/gtkbufferview.c
@@ -260,7 +260,8 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *
else
{
//addr = g_buffer_view_compute_caret_old(view->buffer_view, line, index, real_x, pview->display, &new);
- addr = g_buffer_view_compute_caret(view->buffer_view, real_x, real_y, pview->display, &new);
+ //addr = g_buffer_view_compute_caret(view->buffer_view, real_x, real_y, pview->display, &new);
+ addr = g_buffer_view_compute_caret_full(view->buffer_view, line, index, real_x, pview->display, &new);
gtk_buffer_view_relocate_caret(view, &new, addr);
}