From 7bd707cb43ed8830add9d9eec3a670c9a0ce4d68 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 11 Apr 2015 20:01:03 +0000 Subject: 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 --- ChangeLog | 8 ++ src/glibext/gbufferline.c | 204 ++++++++++++++++++++++++++++++++++++++++++--- src/glibext/gbufferline.h | 2 +- src/glibext/gcodebuffer.c | 85 +++++-------------- src/gtkext/gtkbufferview.c | 3 +- 5 files changed, 227 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index f971576..55e8dde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +15-04-11 Cyrille Bagard + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + * src/glibext/gcodebuffer.c: + * src/gtkext/gtkbufferview.c: + Fix the remaining bugs in all kinds of navigation in buffer views. + 15-04-10 Cyrille Bagard * src/core/params.c: 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); } -- cgit v0.11.2-87-g4458