diff options
Diffstat (limited to 'src/glibext/gbufferline.c')
-rw-r--r-- | src/glibext/gbufferline.c | 324 |
1 files changed, 284 insertions, 40 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index cb5c267..6970dac 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -56,13 +56,19 @@ typedef struct _buffer_line_column static void reset_column(buffer_line_column *); /* Fournit la quantité de pixels requise pour l'impression. */ -static gint get_column_width(buffer_line_column *); +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 *); +#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) + /* Donne le segment d'une colonne présent à une abscisse donnée. */ -static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, bool); +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 *); /* Met en surbrillance des segments similaires. */ GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *); @@ -129,7 +135,7 @@ static void g_buffer_line_init(GBufferLine *); static void reset_column(buffer_line_column *column) { - column->max_width = -1; + column->max_width = 0; } @@ -146,19 +152,8 @@ static void reset_column(buffer_line_column *column) * * ******************************************************************************/ -static gint get_column_width(buffer_line_column *column) +static gint get_column_width(const buffer_line_column *column) { - size_t i; /* Boucle de parcours */ - - if (column->max_width == -1) - { - column->max_width = 0; - - for (i = 0; i < column->count; i++) - column->max_width += g_buffer_segment_get_width(column->segments[i]); - - } - return column->max_width; } @@ -189,6 +184,8 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se column->segments[column->count - 1] = segment; + column->max_width += g_buffer_segment_get_width(segment); + } @@ -196,7 +193,7 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se * * * Paramètres : column = colonne de ligne de texte à consulter. * * x = position de recherche à ajuster. [OUT] * -* force = accepte les segments en bordure au pire. * +* dir = direction d'un éventuel déplacement en cours. * * * * Description : Donne le segment d'une colonne présent à une abscisse donnée.* * * @@ -206,19 +203,37 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se * * ******************************************************************************/ -static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, bool force) +static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, GdkScrollDirection dir) { GBufferSegment *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ gint width; /* Largeur à retirer */ + bool included; /* Appartenance à une largeur ?*/ result = NULL; + printf(" == gs@ == count = %d width = %d\n", + column->count, get_column_width(column)); + for (i = 0; i < column->count && result == NULL; i++) { width = g_buffer_segment_get_width(column->segments[i]); - if (width > *x || ((i + 1) == column->count && force)) + printf(" -s- |%d| -> x=%d w=%d\n", i, *x, width); + + /** + * Soit une limite entre deux segments A et B : + * + * - dans le cas d'un déplacement vers la gauche, on part de cette limite + * pour progresser à l'intérieur de A. Donc la limite fait partie de A. + * + * - dans le cas d'un déplacement vers la droite, on part de cette limite + * pour progresser à l'intérieur de B. Donc la limite ne fait pas partie de A. + */ + if (dir == GDK_SCROLL_LEFT) included = (width >= *x); + else included = (width > *x); + + if (included || (i + 1) == column->count) result = column->segments[i]; else @@ -226,6 +241,59 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, } + printf(" == gs@ == > segment = %p\n", result); + + return result; + +} + + +/****************************************************************************** +* * +* 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é. * +* * +* Retour : Segment trouvé ou NULL si hors borne ou inconnu. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir, bool *out) +{ + 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; + + if (i < column->count) + switch (dir) + { + case GDK_SCROLL_LEFT: + *out = (i == 0); + if (!*out) + result = column->segments[i - 1]; + break; + + case GDK_SCROLL_RIGHT: + *out = ((i + 1) == column->count); + if (!*out) + result = column->segments[i + 1]; + break; + + default: + break; + + } + return result; } @@ -518,7 +586,9 @@ 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] * +* dir = direction d'un éventuel déplacement en cours. * * force = accepte les segments en bordure au pire. * * * * Description : Donne le segment présent à une abscisse donnée. * @@ -529,30 +599,120 @@ 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], gint *x, bool force) +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 *result; /* Trouvaille à retourner */ + gint old; /* Valeur d'origine de position*/ + BufferLineColumn last; /* Dernière colonne remplie */ + gint last_x; /* Dernière abscisse associée */ BufferLineColumn i; /* Boucle de parcours */ + gint width; /* Largeur d'une colonne donnée*/ result = NULL; + old = *x; + last = BLC_COUNT; + last_x = *x; /* Pour GCC */ + + printf(" {{ ADDR }} 0x%08x\n", line->range.addr.physical); + + + + for (i = 0; i < BLC_COUNT; i++) { - /* FIXME : addr/code */ + printf(" @ (%d) x=%d width=%d max=%d display ? %d\n", + i, *x, 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_x = *x; + } + + if (i < line->merge_start) + { + width = max_widths[i]; + + if (*x <= width) break; + else *x -= (max_widths[i] + COL_MARGIN); + + } + else + { + width = get_column_width(&line->columns[i]); + + if (*x <= width) break; + else *x -= width; + + } - if (*x < max_widths[i]) break; - else *x -= (max_widths[i] + COL_MARGIN); } - if (i == BLC_COUNT && force) + printf(" -- get segment at -- found index %u (max=%u)\n", i, BLC_COUNT); + + + printf(" last seen = %u\n", last); + + + + if (force) { - i = BLC_COUNT - 1; - *x += (max_widths[i] + COL_MARGIN); + if (i == BLC_COUNT) + { + + /* Re-calcul des largeurs cumulées */ + + if (last == BLC_COUNT) i = BLC_COUNT; + else + { + *x = old; + + for (i = 0; i < last; i++) + { + if (i < line->merge_start) + *x -= (max_widths[i] + COL_MARGIN); + else + *x -= get_column_width(&line->columns[i]); + } + + } + + + printf(" -- get segment at -- last index %u (max=%u) -->> x = %d\n", i, BLC_COUNT, *x); + + + + } + + /* Si on s'est arrêté sur un champ vide... */ + else if (i != last) + { + i = last; + *x = last_x; + } + } + + + + if (i < BLC_COUNT) - result = get_segment_at(&line->columns[i], x, force); + 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)); + + return result; @@ -561,33 +721,117 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint /****************************************************************************** * * -* Paramètres : line = ligne à venir consulter. * -* caret = position du curseur à faire évoluer. * -* ctrl = indique la demande d'un parcours rapide. * -* dir = direction du parcours. * -* phys = indique si les positions doivent être affichées. * -* virt = indique si les adresses doivent être affichées. * -* code = indique si le code binaire doit être affiché. * +* Paramètres : line = ligne à venir consulter. * +* target = segment dont un voisin est à retourner. * +* max_widths = largeurs de colonne à respecter. XXXXXXXXXXXXXXX * +* display = règles d'affichage des colonnes modulables. * +* dir = orientation des recherches. * +* offset = décalage pour amener à l'extrémité voisine. [OUT] * * * -* Description : Déplace le curseur au sein d'une vue de tampon. * +* Description : Fournit le segment voisin d'un autre segment identifié. * * * -* Retour : true si un déplacement a été effectué, false sinon. * +* Retour : Segment trouvé dans la ligne ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) +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*/ - /* TODO : utiliser les arguments booléens */ + result = NULL; + *offset = 0; + + for (i = 0; i < BLC_COUNT && result == NULL; i++) + { + if (i < BLC_DISPLAY && !display[i]) continue; + + result = find_near_segment(&line->columns[i], target, dir, &out); + + printf(" [%d] near seg = %p (out ? %d)\n", i, result, out); + + if (result != NULL) break; + + if (out) + { + switch (dir) + { + case GDK_SCROLL_LEFT: + + gblfns_loop_left: + + /* 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 (i > BLC_FIRST) result = get_last_segment(&line->columns[i - 1]); + + printf(" [near] (%d) %p\n", i, result); + + 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; + } + + if (result != NULL) + *offset += g_buffer_segment_get_width(result) - max_widths[i - 1] - COL_MARGIN; + + break; - caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10); + case GDK_SCROLL_RIGHT: - return true; + gblfns_loop_right: + /* On s'assure que la colonne suivante est visible */ + for (; (i + 1) < BLC_DISPLAY; i++) + if (display[i + 1]) break; - return false; + if ((i + 1) < BLC_COUNT) result = get_first_segment(&line->columns[i + 1]); + + + printf(" [near] (%d) %p\n", i, result); + + 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 -= g_buffer_segment_get_width(target); + *offset += max_widths[i] + COL_MARGIN; + printf(" -- add %d ~> %d\n", max_widths[i], *offset); + } + + + /* + if (result != NULL) + *offset += max_widths[i + 1] - g_buffer_segment_get_width(result) + COL_MARGIN; + */ + + break; + + default: + break; + + } + + } + + } + + return result; } |