From 67c0fe6eddda7ac5ff591ec972425095209d75ff Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 1 Nov 2014 20:31:29 +0000 Subject: Moved the caret with mouse and keyboard. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@417 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 22 +++ src/glibext/gbufferline.c | 324 ++++++++++++++++++++++++++++++++++++----- src/glibext/gbufferline.h | 11 +- src/glibext/gbuffersegment.c | 64 ++++++++ src/glibext/gbuffersegment.h | 3 + src/glibext/gcodebuffer.c | 292 +++++++++++++++++++++++++++++-------- src/glibext/gcodebuffer.h | 4 +- src/gtkext/gtkbufferview-int.h | 4 +- src/gtkext/gtkbufferview.c | 178 ++++++++++++++++++---- src/gtkext/gtkviewpanel-int.h | 4 + src/gtkext/gtkviewpanel.c | 72 +++++++-- src/gui/status.c | 37 ++++- 12 files changed, 857 insertions(+), 158 deletions(-) diff --git a/ChangeLog b/ChangeLog index 78fb8ea..a9b9127 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +14-11-01 Cyrille Bagard + + * src/glibext/gbufferline.c: + * src/glibext/gbufferline.h: + * src/glibext/gbuffersegment.c: + * src/glibext/gbuffersegment.h: + * src/glibext/gcodebuffer.c: + * src/glibext/gcodebuffer.h: + Compute locations of caret using width and neighbourhood of segments. + + * src/gtkext/gtkbufferview.c: + * src/gtkext/gtkbufferview-int.h: + Change some types from 'vmpa_t' to 'vmpa2t'. Move the caret with mouse + and keyboard. Fix the blinking of the caret when focusing on a view widget. + + * src/gtkext/gtkviewpanel.c: + * src/gtkext/gtkviewpanel-int.h: + Define the right steps for scrolling increments. + + * src/gui/status.c: + SHow some information about the current location. + 14-10-22 Cyrille Bagard * configure.ac: 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; } diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 8e436d9..5a45fe2 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -69,6 +69,9 @@ typedef enum _BufferLineColumn } BufferLineColumn; +/* Première colonne de l'ensemble */ +#define BLC_FIRST BLC_PHYSICAL + /* Première colonne toujours affichée */ #define BLC_DISPLAY BLC_ASSEMBLY_HEAD @@ -96,11 +99,11 @@ void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, /* 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, bool); - /* Donne le segment présent à une abscisse donnée. */ -GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool); +GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], const bool *, 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 *); /* 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 c96b092..0c31b9c 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -406,6 +406,70 @@ gint g_buffer_segment_get_caret_position(const GBufferSegment *segment, gint x) /****************************************************************************** * * * Paramètres : segment = fragment de texte à manipuler. * +* x = position du curseur à faire évoluer. [OUT] * +* ctrl = indique la demande d'un parcours rapide. * +* dir = direction du parcours. * +* * +* Description : Déplace le curseur au sein d'un segment de tampon. * +* * +* Retour : true si un déplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_buffer_segment_move_caret(const GBufferSegment *segment, gint *x, bool ctrl, GdkScrollDirection dir) +{ + bool result; /* Bilan d'opération à renvoyer*/ + gint width; /* Largeur du segment */ + gint char_width; /* Largeur de police fixe */ + + result = false; + + width = g_buffer_segment_get_width(segment); + char_width = width / strlen(segment->text); + + if (dir == GDK_SCROLL_LEFT) + { + printf(">>>>> left ::: x=%d width=%d char=%d\n", *x, width, char_width); + + if (*x > width) *x = width + char_width; + + if (*x == 0) goto gbsmc_done; + + if (ctrl) *x = 0; + else *x = MAX(0, *x - char_width); + + result = true; + + } + + else if (dir == GDK_SCROLL_RIGHT) + { + + printf(">>>>> right ::: x=%d width=%d char=%d\n", *x, width, char_width); + + if (*x == width) goto gbsmc_done; + + if (ctrl) *x = width; + else *x = MIN(width, *x + char_width); + + result = true; + + } + + gbsmc_done: + + printf(">>>>> result ::: %d\n", result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : segment = fragment de texte à manipuler. * * style = style de rendu pour le segment. * * * * Description : Module l'apparence finale du composant. * diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h index d570e89..bb82bba 100644 --- a/src/glibext/gbuffersegment.h +++ b/src/glibext/gbuffersegment.h @@ -120,6 +120,9 @@ 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); +/* Déplace le curseur au sein d'un segment de tampon. */ +bool g_buffer_segment_move_caret(const GBufferSegment *, gint *, bool, GdkScrollDirection); + /* Module l'apparence finale du composant. */ void g_buffer_segment_set_style(GBufferSegment *, SegRenderingStyle); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 1ea8f69..eab418e 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -24,6 +24,7 @@ #include "gcodebuffer.h" +#include #include #include @@ -123,10 +124,10 @@ 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(const GCodeBuffer *, vmpa_t, bool); +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *, const vmpa2t *, bool); /* 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(GCodeBuffer *, const vmpa2t *, bool); @@ -407,7 +408,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn main) * * ******************************************************************************/ -static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, vmpa_t addr, bool first) +static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, const vmpa2t *addr, bool first) { size_t result; /* Indice à retourner */ @@ -451,7 +452,7 @@ static size_t _g_code_buffer_get_index_from_address(const GCodeBuffer *buffer, v * * ******************************************************************************/ -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(GCodeBuffer *buffer, const vmpa2t *addr, bool first) { size_t result; /* Indice à retourner */ @@ -1074,11 +1075,12 @@ gint g_buffer_view_get_height(const GBufferView *view) /****************************************************************************** * * -* Paramètres : view = vue de tampon à mettre à jour. * -* line = ligne correspondant à la position. * -* index = indice de cette même ligne dans le tampon. * -* x = abscisse de la zone principale à traiter. * -* caret = position du curseur à construire. [OUT] * +* Paramètres : view = vue de tampon à mettre à jour. * +* line = ligne correspondant à la position. * +* index = indice de cette même ligne dans le tampon. * +* x = abscisse de la zone principale à traiter. * +* display = règles d'affichage des colonnes modulables. * +* caret = position du curseur à construire. [OUT] * * * * Description : Calcule la position idéale de curseur pour un point donné. * * * @@ -1088,7 +1090,7 @@ gint g_buffer_view_get_height(const GBufferView *view) * * ******************************************************************************/ -const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t index, gint x, GdkRectangle *caret) +const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t index, gint x, const bool *display, GdkRectangle *caret) { gint tmp_x; /* Copie de travail modifiable */ GBufferSegment *segment; /* Segment visé par le pointeur*/ @@ -1099,9 +1101,16 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, tmp_x -= view->left_text; if (tmp_x < 0) return NULL; - segment = g_buffer_line_get_segment_at(line, view->max_widths, &tmp_x, true); + segment = g_buffer_line_get_segment_at(line, view->max_widths, display, &tmp_x, GDK_SCROLL_LEFT, true); + if (segment == NULL) printf(" -- no segment\n"); if (segment == NULL) return NULL; + printf("\n[BASE] 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)); + 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); @@ -1110,20 +1119,147 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, caret->width = 2; caret->height = view->line_height; - return NULL;///g_buffer_line_get_address(line); + return get_mrange_addr(g_buffer_line_get_range(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. * -* 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. * +* caret = position du curseur à faire évoluer. * +* ctrl = indique la demande d'un parcours rapide. * +* dir = direction du parcours. * +* display = règles d'affichage des colonnes modulables. * +* * +* Description : Déplace le curseur au sein d'une vue de tampon. * +* * +* Retour : true si un déplacement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +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 */ + GBufferSegment *segment; /* Segment visé par le pointeur*/ + size_t first; /* Première ligne intégrée */ + + gint ref_x; + + + gint offset; + + + + 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); + + if (segment == NULL) printf(" ===== NO SEG...\n"); + + if (segment == NULL) return false; + + + printf(" ====== FIRST SEG :: %p ('%s')\n", segment, g_buffer_segment_get_text(segment)); + + + + ref_x = tmp_x; + + + + //if (dir == GDK_SCROLL_LEFT || dir == GDK_SCROLL_RIGHT) + result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir); + //else + //result = true; + + printf(" ====== MOVE 1 ? %d\n", result); + + + if (!result) + { + + + segment = g_buffer_line_find_near_segment(line, segment, view->max_widths, display, dir, &offset); + + + printf(" ====== NEAR SEG :: %p ('%s')\n", segment, segment ? g_buffer_segment_get_text(segment) : NULL); + + 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 = offset; + + + result = true; + //result = g_buffer_segment_move_caret(segment, &tmp_x, ctrl, dir); + + /* + if (result) + caret->x -= COL_MARGIN; + */ + + printf(" ====== MOVE 2 ? %d (offset=%d)\n", result, offset); + + + } + + + } + + + if (result) + printf(" ====== NEW CARET: %d -> %d\n", caret->x, caret->x + (tmp_x - ref_x)); + else + printf(" ====== NO NEW CARET!\n"); + + + + if (result) + caret->x += (tmp_x - ref_x); + + + + 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; + +} + + +/****************************************************************************** +* * +* 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. * +* display = règles d'affichage des colonnes modulables. * * * * Description : Déplace le curseur au sein d'une vue de tampon. * * * @@ -1133,9 +1269,12 @@ const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, * * ******************************************************************************/ -vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) +const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, const bool *display) { - bool result; /* Actualisation à renvoyer */ + vmpa2t *result; /* Actualisation à renvoyer */ + GBufferLine *line; /* Ligne sous le pointeur */ + + bool computed; /* Récursivité pris en compte */ gint lheight; /* Hauteur d'une ligne */ gint left_pos; /* Retour à la ligne */ @@ -1143,11 +1282,34 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr 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; + size_t index; /* Indice de ligne de tampon */ + + + bool moved; /* Mémorisation d'une évolut° */ + + + + + + + gint tmp_x; /* Copie de travail modifiable */ + GBufferSegment *segment; /* Segment visé par le pointeur*/ + + + + result = NULL; computed = false; + + + line = g_buffer_view_find_line_at(view, caret->y, &index); + if (line == NULL) return NULL; + + + lheight = g_buffer_view_get_line_height(view); + + switch (dir) { case GDK_SCROLL_UP: @@ -1157,12 +1319,17 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr case GDK_SCROLL_LEFT: case GDK_SCROLL_RIGHT: left_pos = view->left_text; - if (phys) left_pos += view->max_widths[BLC_PHYSICAL] + COL_MARGIN; - if (virt) left_pos += view->max_widths[BLC_VIRTUAL] + COL_MARGIN; - if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN; + if (display[BLC_PHYSICAL]) left_pos += view->max_widths[BLC_PHYSICAL] + COL_MARGIN; + if (display[BLC_VIRTUAL]) left_pos += view->max_widths[BLC_VIRTUAL] + COL_MARGIN; + if (display[BLC_BINARY]) 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; + + + + left_pos = view->left_text; + break; default: /* GDK_SCROLL_SMOOTH */ break; @@ -1171,58 +1338,56 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr 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); + first = 0; + switch (dir) { case GDK_SCROLL_UP: - result = (caret->y >= (first * lheight)); - if (result) - caret->y -= lheight; + + if (index > first) + { + line = view->buffer->lines[index - 1]; + result = g_buffer_view_compute_caret(view, line, index - 1, caret->x, display, caret); + } + break; case GDK_SCROLL_DOWN: - result = ((caret->y + lheight) < (last * lheight)); - if (result) - caret->y += lheight; + + if (index < last) + { + line = view->buffer->lines[index + 1]; + result = g_buffer_view_compute_caret(view, line, index + 1, caret->x, display, caret); + } + break; case GDK_SCROLL_LEFT: - line = g_buffer_view_find_line_at(view, caret->y, NULL); + + line = g_buffer_view_find_line_at(view, caret->y, &index); if (line == NULL) break; - result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, phys, virt, code); + moved = _g_buffer_view_move_caret(view, line, caret, ctrl, GDK_SCROLL_LEFT, display); - if (caret->x < left_pos) + if (!moved && index > first) { - caret->x = right_pos; - - result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, phys, virt, code); - - if (result == VMPA_INVALID) - caret->x = left_pos; - else - computed = true; - + line = view->buffer->lines[index - 1]; + result = g_buffer_view_compute_caret(view, line, index - 1, INT_MAX, display, caret); } break; case GDK_SCROLL_RIGHT: - line = g_buffer_view_find_line_at(view, caret->y, NULL); + + line = g_buffer_view_find_line_at(view, caret->y, &index); if (line == NULL) break; - result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, phys, virt, code); + moved = _g_buffer_view_move_caret(view, line, caret, ctrl, GDK_SCROLL_RIGHT, display); - if (!result) + if (!moved && index < last) { - caret->x = left_pos; - - result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, phys, virt, code); - - if (result == VMPA_INVALID) - caret->x = right_pos; - else - computed = true; - + line = view->buffer->lines[index + 1]; + result = g_buffer_view_compute_caret(view, line, index + 1, left_pos, display, caret); } break; @@ -1232,8 +1397,16 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr } + + printf(" --- CARET --- moved = %d index = %d result = %p\n", + moved, index, result); + + + + /* if (result && !computed) - /*result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret, NULL)*/; + result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret, display, NULL); + */ return result; @@ -1292,6 +1465,7 @@ bool g_buffer_view_unhighlight_segments(GBufferView *view) void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) { +#if 0 /* FIXME : inclusion des champs adresses/code */ GBufferLine *line; /* Ligne sous le pointeur */ GBufferSegment *segment; /* Segment visé par le pointeur*/ bool need_redraw; /* Besoin d'actualisation ? */ @@ -1305,7 +1479,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, false); + segment = g_buffer_line_get_segment_at(line, view->max_widths, &x, GDK_SCROLL_LEFT, false); printf(" ... seg @%d ? %p\n", x, segment); if (segment == NULL) return; @@ -1330,7 +1504,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) if (need_redraw) g_signal_emit_by_name(view, "need-redraw"); - +#endif } diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index 1387eb9..ece7c59 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -129,10 +129,10 @@ gint g_buffer_view_get_width(GBufferView *, const bool *); gint g_buffer_view_get_height(const GBufferView *); /* Calcule la position idéale de curseur pour un point donné. */ -const vmpa2t *g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, GdkRectangle *); +const vmpa2t *g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, const bool *, 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, bool); +const vmpa2t *g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, const bool *); /* Supprime toute mise en évidence de segments. */ bool g_buffer_view_unhighlight_segments(GBufferView *); diff --git a/src/gtkext/gtkbufferview-int.h b/src/gtkext/gtkbufferview-int.h index 64d3b0e..4f82757 100644 --- a/src/gtkext/gtkbufferview-int.h +++ b/src/gtkext/gtkbufferview-int.h @@ -45,7 +45,7 @@ struct _GtkBufferView gint left_text; /* Début d'impression du code */ GdkRectangle caret; /* Emplacement du curseur */ - vmpa_t caret_addr; /* Position mémoire du curseur */ + const vmpa2t *caret_addr; /* Position mémoire du curseur */ guint caret_timer; /* Identifiant du chronomètre */ bool show_caret; /* Bascule entre les affichages*/ @@ -58,7 +58,7 @@ struct _GtkBufferViewClass /* Signaux */ - void (* caret_moved) (GtkBufferView *, vmpa_t); + void (* caret_moved) (GtkBufferView *, const vmpa2t *); }; diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index d5780ed..8b9b83b 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -55,6 +55,9 @@ static gboolean gtk_buffer_view_key_press(GtkWidget *, GdkEventKey *); /* Indique les dimensions de travail du composant d'affichage. */ static void gtk_buffer_view_compute_requested_size(GtkBufferView *, gint *, gint *); +/* Détermine la taille des bonds lors de défilements. */ +static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *, gint, GtkOrientation, gdouble *, gdouble *); + /* Indique la position d'affichage d'une adresse donnée. */ static bool gtk_buffer_view_get_address_coordinates(const GtkBufferView *, const vmpa2t *, gint *, gint *); @@ -66,6 +69,9 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *, cairo_t *, const GtkAl /* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ +/* Déplace le curseur en effaçant son éventuelle position. */ +static void gtk_buffer_view_relocate_caret(GtkBufferView *, const GdkRectangle *, const vmpa2t *); + /* Redémarre l'affichage du curseur à l'emplacement courant. */ static void restart_caret_blinking(GtkBufferView *); @@ -109,6 +115,7 @@ static void gtk_buffer_view_class_init(GtkBufferViewClass *class) widget_class->key_press_event = gtk_buffer_view_key_press; panel_class->compute_size = (compute_requested_size)gtk_buffer_view_compute_requested_size; + panel_class->compute_inc = (compute_scroll_inc)gtk_buffer_view_compute_scroll_inc; panel_class->get_coordinates = (get_addr_coordinates_fc)gtk_buffer_view_get_address_coordinates; g_signal_new("caret-moved", @@ -205,14 +212,16 @@ static gboolean gtk_buffer_view_focus(GtkWidget *widget, GtkDirectionType direct static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton *event) { GtkBufferView *view; /* Autre version du composant */ + GtkViewPanel *pview; /* Autre version du composant */ gint real_x; /* Abscisse absolue réelle */ gint real_y; /* Ordonnée absolue réelle */ size_t index; /* Indice de ligne de tampon */ GBufferLine *line; /* Ligne à la position courante*/ - vmpa_t addr; /* Position mémoire associée */ + const vmpa2t *addr; /* Position mémoire associée */ GdkRectangle new; /* Nouvel emplacement calculé */ view = GTK_BUFFER_VIEW(widget); + pview = GTK_VIEW_PANEL(widget); gtk_widget_grab_focus(widget); @@ -230,6 +239,11 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton * if (line == NULL) return FALSE; + + printf(" [init ] %p - line = %p (y=%d)\n", view->buffer_view, line, real_y); + + + if (real_x < view->left_margin) { @@ -241,28 +255,8 @@ static gboolean gtk_buffer_view_button_press(GtkWidget *widget, GdkEventButton * } else { - return FALSE; - /* - addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, &new); - if (addr == VMPA_INVALID) return FALSE; - */ - - gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y); - - printf(" mouse --old-- :: (%d ; %d)\n", - view->caret.x, view->caret.y); - - printf(" mouse --new-- :: (%d ; %d)\n", - new.x, new.y); - - gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y, - view->caret.width, view->caret.height); - - view->caret = new; - view->caret_addr = addr; - - restart_caret_blinking(view); - + addr = g_buffer_view_compute_caret(view->buffer_view, line, index, real_x, pview->display, &new); + gtk_buffer_view_relocate_caret(view, &new, addr); } return FALSE; @@ -343,7 +337,6 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) gint fake_y; /* Ordonnée virtuelle */ view = GTK_BUFFER_VIEW(widget); - widget = GTK_WIDGET(view); pview = GTK_VIEW_PANEL(widget); window = gtk_widget_get_window(widget); @@ -384,6 +377,14 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) } + /* Curseur clignotant ? */ + + if (gtk_widget_is_focus(widget)) + { + view->show_caret = !view->show_caret; + gtk_buffer_view_refresh_caret(view); + } + cairo_restore(cr); return TRUE; @@ -407,32 +408,78 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) static gboolean gtk_buffer_view_key_press(GtkWidget *widget, GdkEventKey *event) { gboolean result; /* Suites à renvoyer */ + + GtkBufferView *view; /* Autre version du composant */ + GtkViewPanel *pview; /* Autre version du composant */ + + bool ctrl; /* Statut de la touche Contrôle*/ + + GdkRectangle area; + + const vmpa2t *addr; + + result = FALSE; + + + view = GTK_BUFFER_VIEW(widget); + pview = GTK_VIEW_PANEL(widget); + + + area = view->caret; + + ctrl = (event->state & GDK_CONTROL_MASK); switch (event->keyval) { case GDK_KEY_Left: + printf("LEFT\n"); + addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_LEFT, pview->display); + gtk_buffer_view_relocate_caret(view, &area, view->caret_addr); result = TRUE; break; + case GDK_KEY_Up: + printf("UP\n"); + addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_UP, pview->display); + gtk_buffer_view_relocate_caret(view, &area, view->caret_addr); result = TRUE; break; + case GDK_KEY_Right: + printf("RIGHT\n"); + addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_RIGHT, pview->display); + gtk_buffer_view_relocate_caret(view, &area, view->caret_addr); result = TRUE; break; + case GDK_KEY_Down: + printf("DOWN\n"); + addr = g_buffer_view_move_caret(view->buffer_view, &area, ctrl, GDK_SCROLL_DOWN, pview->display); + gtk_buffer_view_relocate_caret(view, &area, view->caret_addr); result = TRUE; break; + + default: + addr = NULL; + break; + } printf("ctrl ? %d -- keyval = %d -->> %d\n", ctrl, event->keyval, result); + if (addr != NULL) gtk_view_panel_scroll_to_address(pview, addr); + + + printf("\n"); + + return result; } @@ -466,6 +513,38 @@ static void gtk_buffer_view_compute_requested_size(GtkBufferView *view, gint *wi } +/****************************************************************************** +* * +* Paramètres : panel = composant GTK d'affichage à mettre à jour. * +* size = taille de l'espace dans la direction donnée. * +* orientation = indication sur le défilement à traiter. * +* step = valeur d'un petit pas de défilement. [OUT] * +* page = valeur d'un grand pas de défilement. [OUT] * +* * +* Description : Détermine la taille des bonds lors de défilements. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_buffer_view_compute_scroll_inc(GtkBufferView *view, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) +{ + if (orientation == GTK_ORIENTATION_VERTICAL) + { + *step = 17; // FIXME g_buffer_view_get_line_height(view->buffer_view); + *page = *step * 10; + } + + else + GTK_VIEW_PANEL_CLASS(gtk_buffer_view_parent_class)->compute_inc(GTK_VIEW_PANEL(view), + size, orientation, step, page); + +} + + + @@ -633,10 +712,43 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint /****************************************************************************** * * * Paramètres : view = composant GTK à manipuler. * +* area = emplacement pour le dessin d'un curseur. * +* addr = position dans la mémoire représentée du curseur. * +* * +* Description : Déplace le curseur en effaçant son éventuelle position. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_buffer_view_relocate_caret(GtkBufferView *view, const GdkRectangle *area, const vmpa2t *addr) +{ + if (view->caret_addr != NULL) + { + gtk_buffer_view_compute_relative_coords(view, &view->caret.x, &view->caret.y); + + gtk_widget_queue_draw_area(GTK_WIDGET(view), view->caret.x, view->caret.y, + view->caret.width, view->caret.height); + + } + + view->caret = *area; + view->caret_addr = addr; + + restart_caret_blinking(view); + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant GTK à manipuler. * * * * Description : Redémarre l'affichage du curseur à l'emplacement courant. * * * -* Retour : TRUE pour poursuivre les basculements automatiques. * +* Retour : - * * * * Remarques : - * * * @@ -644,16 +756,20 @@ void gtk_buffer_view_compute_relative_coords(GtkBufferView *view, gint *x, gint static void restart_caret_blinking(GtkBufferView *view) { - if (view->caret_addr == VMPA_INVALID) - return; - if (view->caret_timer != 0) + { g_source_remove(view->caret_timer); + view->caret_timer = 0; + } + + if (view->caret_addr != NULL) + { + view->show_caret = false; + gtk_buffer_view_refresh_caret(view); - view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view); + view->caret_timer = g_timeout_add_seconds(1, (GSourceFunc)gtk_buffer_view_refresh_caret, view); - view->show_caret = false; - gtk_buffer_view_refresh_caret(view); + } g_signal_emit_by_name(view, "caret-moved", view->caret_addr); diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h index 49b5195..f33499d 100644 --- a/src/gtkext/gtkviewpanel-int.h +++ b/src/gtkext/gtkviewpanel-int.h @@ -36,6 +36,9 @@ /* Indique les dimensions de travail du composant d'affichage. */ typedef void (* compute_requested_size) (GtkViewPanel *, gint *, gint *); +/* Détermine la taille des bonds lors de défilements. */ +typedef void (* compute_scroll_inc) (GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *); + /* Prend acte de l'association d'un binaire chargé. */ typedef void (* attach_binary_fc) (GtkViewPanel *, GLoadedBinary *); @@ -82,6 +85,7 @@ struct _GtkViewPanelClass GtkFixedClass parent; /* A laisser en premier */ compute_requested_size compute_size; /* Calcul de la taille requise */ + compute_scroll_inc compute_inc; /* Calcul des bonds */ get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */ }; diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 27799b5..8e41fa1 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -53,6 +53,9 @@ static void gtk_view_panel_size_allocate(GtkWidget *, GtkAllocation *); /* Met à jour l'affichage du composant d'affichage. */ static gboolean gtk_view_panel_draw(GtkWidget *, cairo_t *); +/* Détermine la taille des bonds lors de défilements. */ +static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *, gint, GtkOrientation, gdouble *, gdouble *); + /* Détermine la taille allouée pour le contenu. */ static void gtk_view_panel_compute_allocation(GtkViewPanel *, GtkAllocation *); @@ -94,9 +97,11 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class) { GObjectClass *gobject_class; /* Plus haut niveau équivalent */ GtkWidgetClass *widget_class; /* Classe de haut niveau */ + GtkViewPanelClass *panel_class; /* Classe de lus bas niveau */ gobject_class = G_OBJECT_CLASS(class); widget_class = GTK_WIDGET_CLASS(class); + panel_class = GTK_VIEW_PANEL_CLASS(class); gobject_class->set_property = gtk_view_panel_set_property; gobject_class->get_property = gtk_view_panel_get_property; @@ -112,6 +117,8 @@ static void gtk_view_panel_class_init(GtkViewPanelClass *class) widget_class->size_allocate = gtk_view_panel_size_allocate; widget_class->draw = gtk_view_panel_draw; + panel_class->compute_inc = gtk_view_panel_compute_scroll_inc; + } @@ -365,6 +372,30 @@ static gboolean gtk_view_panel_draw(GtkWidget *widget, cairo_t *cr) /****************************************************************************** * * +* Paramètres : panel = composant GTK d'affichage à mettre à jour. * +* size = taille de l'espace dans la direction donnée. * +* orientation = indication sur le défilement à traiter. * +* step = valeur d'un petit pas de défilement. [OUT] * +* page = valeur d'un grand pas de défilement. [OUT] * +* * +* Description : Détermine la taille des bonds lors de défilements. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_view_panel_compute_scroll_inc(GtkViewPanel *panel, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) +{ + *step = size * 0.1; + *page = size * 0.9; + +} + + +/****************************************************************************** +* * * Paramètres : panel = composant GTK à consulter. * * alloc = emplacement à déterminer. [OUT] * * * @@ -521,6 +552,8 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation GtkAdjustment *adj; /* Ajustement à manipuler */ gint req; /* Dimension requise */ gint allocated; /* Dimension allouée */ + gdouble step_inc; /* Pas de défilement */ + gdouble page_inc; /* ENjambée de défilement */ gtk_view_panel_compute_allocation(panel, &allocation); @@ -541,10 +574,12 @@ static void gtk_view_panel_update_adjustment(GtkViewPanel *panel, GtkOrientation } + GTK_VIEW_PANEL_GET_CLASS(panel)->compute_inc(panel, allocated, orientation, &step_inc, &page_inc); + gtk_adjustment_configure(adj, gtk_adjustment_get_value(adj), 0, MAX(req, allocated), - allocated * 0.1, - allocated * 0.9, + step_inc, + page_inc, allocated); } @@ -736,8 +771,9 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr) gint y; /* Ordonnée à garantir */ GtkWidget *viewport; /* Parent avec défilement */ GtkAdjustment *adj; /* Défilement à mettre à jour */ - double limit; /* Limite à ne pas dépasser */ - + gdouble step_inc; /* Valeur d'un petit pas */ + gdouble page_size; /* Taille de l'affichage */ + double value; /* Valeur courante */ /* if (panel->define != NULL) @@ -749,21 +785,33 @@ void gtk_view_panel_scroll_to_address(GtkViewPanel *panel, const vmpa2t *addr) { viewport = gtk_widget_get_parent(GTK_WIDGET(panel)); + /* Eventuel défilement horizontal */ + g_object_get(G_OBJECT(viewport), "hadjustment", &adj, NULL); - limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj); - if (x > limit) - x = limit; + step_inc = gtk_adjustment_get_step_increment(adj); + page_size = gtk_adjustment_get_page_size(adj); + value = gtk_adjustment_get_value(adj); - gtk_adjustment_set_value(adj, x); + if (x < value) + gtk_adjustment_set_value(adj, x); + + else if ((x + step_inc) > (value + page_size)) + gtk_adjustment_set_value(adj, x + step_inc - page_size); + + /* Eventuel défilement vertical */ g_object_get(G_OBJECT(viewport), "vadjustment", &adj, NULL); - limit = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj); - if (y > limit) - y = limit; + step_inc = gtk_adjustment_get_step_increment(adj); + page_size = gtk_adjustment_get_page_size(adj); + value = gtk_adjustment_get_value(adj); + + if (y < value) + gtk_adjustment_set_value(adj, y); - gtk_adjustment_set_value(adj, y); + else if ((y + step_inc) > (value + page_size)) + gtk_adjustment_set_value(adj, y + step_inc - page_size); } diff --git a/src/gui/status.c b/src/gui/status.c index 2633ba6..3a96ea1 100644 --- a/src/gui/status.c +++ b/src/gui/status.c @@ -75,7 +75,7 @@ static void g_status_info_finalize(GStatusInfo *); static void update_status_info_for_view(GStatusInfo *, GtkViewPanel *); /* Imprime la position du parcours courant dans le statut. */ -static void track_caret_address_on_buffer_views(GtkBufferView *, vmpa_t, GStatusInfo *); +static void track_caret_address_on_buffer_views(GtkBufferView *, const vmpa2t *, GStatusInfo *); /* Concentre l'attention de l'ensemble sur une adresse donnée. */ static void focus_address_in_status_info(GStatusInfo *, GLoadedBinary *, const vmpa2t *); @@ -267,24 +267,42 @@ static void update_status_info_for_view(GStatusInfo *info, GtkViewPanel *view) * * ******************************************************************************/ -static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr, GStatusInfo *info) +static void track_caret_address_on_buffer_views(GtkBufferView *view, const vmpa2t *addr, GStatusInfo *info) { GEditorItem *item; /* Autre version de l'élément */ - char *msg; /* Message à transmettre */ - char tmp[VMPA_MAX_SIZE]; /* Zone de conversion */ GLoadedBinary *binary; /* Binaire courant */ - GExeFormat *format; /* Format associé au binaire */ + GExeFormat *format; /* Format du fichier binaire */ + GArchProcessor *proc; /* Architecture du binaire */ + MemoryDataSize msize; /* Taille par défaut */ + char *msg; /* Message à transmettre */ + VMPA_BUFFER(conv); /* Zone de conversion */ + vmpa_t rel; /* Adresse relative à un symb. */ const char *label; /* Désignation d'un symbole */ item = G_EDITOR_ITEM(info); + binary = g_editor_item_get_current_binary(item); + format = g_loaded_binary_get_format(binary); + proc = get_arch_processor_from_format(format); + /* Adresse brute */ - msg = strdup(_("Address ")); + msize = g_arch_processor_get_memory_size(proc); - snprintf(tmp, VMPA_MAX_SIZE, VMPA_FMT_LONG, addr); - msg = stradd(msg, tmp); + msg = strdup(_("Location phys:")); + + vmpa2_phys_to_string(addr, msize, conv, NULL); + msg = stradd(msg, conv); + + msg = stradd(msg, " virt:"); + + vmpa2_virt_to_string(addr, msize, conv, NULL); + msg = stradd(msg, conv); + + + +#if 0 /* Relation avec les symboles */ @@ -304,6 +322,9 @@ static void track_caret_address_on_buffer_views(GtkBufferView *view, vmpa_t addr } +#endif + + /* Impression */ if (info->msg_id > 0) -- cgit v0.11.2-87-g4458