summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glibext/gbufferline.c324
-rw-r--r--src/glibext/gbufferline.h11
-rw-r--r--src/glibext/gbuffersegment.c64
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c292
-rw-r--r--src/glibext/gcodebuffer.h4
-rw-r--r--src/gtkext/gtkbufferview-int.h4
-rw-r--r--src/gtkext/gtkbufferview.c178
-rw-r--r--src/gtkext/gtkviewpanel-int.h4
-rw-r--r--src/gtkext/gtkviewpanel.c72
-rw-r--r--src/gui/status.c37
11 files changed, 835 insertions, 158 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;
}
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 <limits.h>
#include <malloc.h>
#include <string.h>
@@ -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)