diff options
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/gbufferline.c | 65 | ||||
-rw-r--r-- | src/glibext/gbufferline.h | 5 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.c | 51 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.h | 3 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.c | 180 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.h | 8 |
6 files changed, 294 insertions, 18 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 95d6126..18f8a2a 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -61,7 +61,7 @@ static gint get_column_width(buffer_line_column *); static void add_segment_to_column(buffer_line_column *, GBufferSegment *); /* Donne le segment d'une colonne présent à une abscisse donnée. */ -static GBufferSegment *get_segment_at(const buffer_line_column *, gint); +static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, bool); /* Met en surbrillance des segments similaires. */ GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *); @@ -194,7 +194,8 @@ 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. * +* x = position de recherche à ajuster. [OUT] * +* force = accepte les segments en bordure au pire. * * * * Description : Donne le segment d'une colonne présent à une abscisse donnée.* * * @@ -204,7 +205,7 @@ static void add_segment_to_column(buffer_line_column *column, GBufferSegment *se * * ******************************************************************************/ -static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x) +static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x, bool force) { GBufferSegment *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ @@ -216,11 +217,11 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint x) { width = g_buffer_segment_get_width(column->segments[i]); - if (width <= x) - x -= width; + if (width > *x || ((i + 1) == column->count && force)) + result = column->segments[i]; else - result = column->segments[i]; + *x -= width; } @@ -552,7 +553,8 @@ void g_buffer_line_add_segment(GBufferLine *line, BufferLineColumn index, GBuffe * * * Paramètres : line = ligne à venir consulter. * * max_widths = largeurs de colonne à respecter. * -* x = position à la colonne visée par la procédure. * +* x = position à la colonne visée. [OUT] * +* force = accepte les segments en bordure au pire. * * * * Description : Donne le segment présent à une abscisse donnée. * * * @@ -562,7 +564,7 @@ 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) +GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint max_widths[BLC_COUNT], gint *x, bool force) { GBufferSegment *result; /* Trouvaille à retourner */ BufferLineColumn i; /* Boucle de parcours */ @@ -570,11 +572,22 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint result = NULL; for (i = BLC_ADDRESS; i < BLC_COUNT; i++) - if (x < max_widths[i]) break; - else x -= (max_widths[i] + COL_MARGIN); + { + /* FIXME : addr/code */ + + if (*x < max_widths[i]) break; + else *x -= (max_widths[i] + COL_MARGIN); + + } + + if (i == BLC_COUNT && force) + { + i = BLC_COUNT - 1; + *x += (max_widths[i] + COL_MARGIN); + } if (i < BLC_COUNT) - result = get_segment_at(&line->columns[i], x); + result = get_segment_at(&line->columns[i], x, force); return result; @@ -583,6 +596,36 @@ 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. * +* addr = indique si les positions doivent être affichées. * +* code = indique si le code binaire doit être affiché. * +* * +* Description : Déplace le curseur au sein d'une vue de tampon. * +* * +* Retour : true si un déplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code) +{ + + caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10); + + return true; + + + return false; + +} + + +/****************************************************************************** +* * * Paramètres : line = ligne à venir consulter. * * list = liste de segments identiques à constituer. * * ref = segment de référence à comparer avec tous les autres. * diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 6eb4e27..2a46b5a 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -129,8 +129,11 @@ vmpa_t g_buffer_line_get_address(const GBufferLine *); /* Ajoute un fragment de texte à une colonne de ligne. */ void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated)); +/* Déplace le curseur au sein d'une vue de tampon. */ +bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool); + /* Donne le segment présent à une abscisse donnée. */ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint); +GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool); /* Met en surbrillance des segments similaires. */ GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *, GSList *, const GBufferSegment *); diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c index 861c7cb..031075c 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -478,6 +478,57 @@ gint g_buffer_segment_get_width(const GBufferSegment *segment) /****************************************************************************** * * +* Paramètres : segment = fragment de texte à consulter. * +* x = position horizontale au niveau du segment. * +* * +* Description : Fournit la position idéale pour un marqueur. * +* * +* Retour : Position dans le segment donné. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x) +{ + gint result; /* Position à retourner */ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + width = g_buffer_segment_get_width(segment); + + printf("(seg) x=%d width=%d\n", x, width); + + if (x <= 0) + result = 0; + + else if (x >= width) + result = width; + + else + { + if (strlen(segment->text) != segment->glyphs->num_glyphs) + { + + printf("STOP ::: %d vs %d\n", strlen(segment->text), segment->glyphs->num_glyphs); + exit(0); + } + + char_width = width / segment->glyphs->num_glyphs; + + result = (x / char_width) * char_width; + if ((x % char_width) > (char_width / 2)) + result += char_width; + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : segment = fragment de texte à manipuler. * * * * Description : (Re)charge les couleurs à partir de la liste d'attributs. * diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h index 96011bb..bc0d512 100644 --- a/src/glibext/gbuffersegment.h +++ b/src/glibext/gbuffersegment.h @@ -86,6 +86,9 @@ const char *g_buffer_segment_get_text(const GBufferSegment *); /* Fournit la quantité de pixels requise pour l'impression. */ gint g_buffer_segment_get_width(const GBufferSegment *); +/* Fournit la position idéale pour un marqueur. */ +gint g_buffer_segment_get_caret_position(const GBufferSegment *, gint); + /* (Re)charge les couleurs à partir de la liste d'attributs. */ void g_buffer_segment_cache_colors(GBufferSegment *); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index e81966e..920b17c 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -123,7 +123,7 @@ static void g_code_buffer_class_init(GCodeBufferClass *); static void g_code_buffer_init(GCodeBuffer *); /* Convertit une adresse en indice de ligne. */ -static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool); +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, vmpa_t, bool); /* Convertit une adresse en indice de ligne. */ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, vmpa_t, bool); @@ -411,7 +411,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn main) * * ******************************************************************************/ -static size_t _g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t addr, bool first) +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, vmpa_t addr, bool first) { size_t result; /* Indice à retourner */ @@ -1053,6 +1053,172 @@ void g_buffer_view_get_size(GBufferView *view, gint *width, gint *height, bool a /****************************************************************************** * * +* Paramètres : view = vue de tampon à mettre à jour. * +* x = abscisse de la zone principale à traiter. * +* y = ordonnée de la zone principale à traiter. * +* caret = position du curseur à construire. [OUT] * +* * +* Description : Calcule la position idéale de curseur pour un point donné. * +* * +* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, GdkRectangle *caret) +{ + size_t index; /* Indice de la ligne trouvée */ + GBufferLine *line; /* Ligne sous le pointeur */ + gint tmp_x; /* Copie de travail modifiable */ + GBufferSegment *segment; /* Segment visé par le pointeur*/ + size_t first; /* Première ligne intégrée */ + + line = g_buffer_view_find_line_at(view, y, &index); + if (line == NULL) return VMPA_INVALID; + + tmp_x = x; + + tmp_x -= view->left_text; + if (tmp_x < 0) return VMPA_INVALID; + + segment = g_buffer_line_get_segment_at(line, view->max_widths, &tmp_x, true); + if (segment == NULL) printf("no segment\n"); + if (segment == NULL) return VMPA_INVALID; + + caret->x = (x - tmp_x) + g_buffer_segment_get_caret_position(segment, tmp_x); + + first = g_code_buffer_get_index_from_address(view->buffer, view->start, true); + caret->y = (index - first) * view->line_height; + + caret->width = 2; + caret->height = view->line_height; + + return g_buffer_line_get_address(line); + +} + + +/****************************************************************************** +* * +* Paramètres : view = vue de tampon à mettre à jour. * +* caret = position du curseur à faire évoluer. * +* ctrl = indique la demande d'un parcours rapide. * +* dir = direction du parcours. * +* addr = indique si les positions doivent être affichées. * +* code = indique si le code binaire doit être affiché. * +* * +* Description : Déplace le curseur au sein d'une vue de tampon. * +* * +* Retour : Adresse si une a pu être déterminée, VMPA_INVALID sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code) +{ + bool result; /* Actualisation à renvoyer */ + bool computed; /* Récursivité pris en compte */ + gint lheight; /* Hauteur d'une ligne */ + gint left_pos; /* Retour à la ligne */ + gint right_pos; /* Position d'extrème droite */ + BufferLineColumn i; /* Boucle de parcours */ + size_t first; /* Première ligne intégrée */ + size_t last; /* Dernière ligne intégrée */ + GBufferLine *line; /* Ligne sous le pointeur */ + + result = VMPA_INVALID; + computed = false; + + switch (dir) + { + case GDK_SCROLL_UP: + case GDK_SCROLL_DOWN: + lheight = g_buffer_view_get_line_height(view); + break; + case GDK_SCROLL_LEFT: + case GDK_SCROLL_RIGHT: + left_pos = view->left_text; + if (addr) left_pos += view->max_widths[BLC_ADDRESS] + COL_MARGIN; + if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN; + right_pos = left_pos; + for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++) + right_pos += view->max_widths[i] + COL_MARGIN; + break; + } + + first = g_code_buffer_get_index_from_address(view->buffer, view->start, true); + last = g_code_buffer_get_index_from_address(view->buffer, view->end, false); + + switch (dir) + { + case GDK_SCROLL_UP: + result = (caret->y >= (first * lheight)); + if (result) + caret->y -= lheight; + break; + + case GDK_SCROLL_DOWN: + result = ((caret->y + lheight) < (last * lheight)); + if (result) + caret->y += lheight; + break; + + case GDK_SCROLL_LEFT: + line = g_buffer_view_find_line_at(view, caret->y, NULL); + if (line == NULL) break; + + result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, addr, code); + + if (caret->x < left_pos) + { + caret->x = right_pos; + + result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, addr, code); + + if (result == VMPA_INVALID) + caret->x = left_pos; + else + computed = true; + + } + + break; + + case GDK_SCROLL_RIGHT: + line = g_buffer_view_find_line_at(view, caret->y, NULL); + if (line == NULL) break; + + result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, addr, code); + + if (!result) + { + caret->x = left_pos; + + result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, addr, code); + + if (result == VMPA_INVALID) + caret->x = right_pos; + else + computed = true; + + } + + break; + + } + + if (result && !computed) + result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : view = vue de tampon à mettre à jour. * * * * Description : Supprime toute mise en évidence de segments. * @@ -1110,7 +1276,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) size_t last; /* Dernière ligne intégrée */ size_t i; /* Boucle de parcours */ - line = g_buffer_view_find_line_at(view, y); + line = g_buffer_view_find_line_at(view, y, NULL); if (line == NULL) return; @@ -1127,7 +1293,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) x -= view->left_text; if (x < 0) return; - segment = g_buffer_line_get_segment_at(line, view->max_widths, x); + segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, false); printf(" ... seg @%d ? %p\n", x, segment); if (segment == NULL) return; @@ -1259,6 +1425,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd * * * Paramètres : view = visualisation à consulter. * * y = ordonnée comprise dans la ligne recherchée. * +* idx = indice de la ligne trouvée ou NULL. [OUT] * * * * Description : Fournit la ligne présente à une ordonnée donnée. * * * @@ -1268,7 +1435,7 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd * * ******************************************************************************/ -GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y) +GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y, size_t *idx) { gint lheight; /* Hauteur d'une ligne */ size_t index; /* Indice attendu */ @@ -1276,6 +1443,9 @@ GBufferLine *g_buffer_view_find_line_at(GBufferView *view, gint y) lheight = g_buffer_view_get_line_height(view); index = y / lheight; + if (idx != NULL) + *idx = index; + return (index < view->buffer->used ? view->buffer->lines[index] : NULL); } diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index fc4bc66..4ae5c58 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -124,6 +124,12 @@ gint g_buffer_view_get_line_height(GBufferView *); /* Fournit les dimensions requises par une visualisation. */ void g_buffer_view_get_size(GBufferView *, gint *, gint *, bool, bool); +/* Calcule la position idéale de curseur pour un point donné. */ +vmpa_t g_buffer_view_compute_caret(GBufferView *, gint, gint, GdkRectangle *); + +/* Déplace le curseur au sein d'une vue de tampon. */ +vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool); + /* Supprime toute mise en évidence de segments. */ bool g_buffer_view_unhighlight_segments(GBufferView *); @@ -137,7 +143,7 @@ void g_buffer_view_define_extra_drawing(GBufferView *, buffer_line_draw_fc, void void g_buffer_view_draw(const GBufferView *, const GdkEventExpose *, GdkGC *, gint, gint, bool, bool); /* Fournit la ligne présente à une ordonnée donnée. */ -GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint); +GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); /* Indique la position d'affichage d'une adresse donnée. */ bool g_buffer_view_get_address_coordinates(GBufferView *, vmpa_t, gint *, gint *); |