summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-01-16 21:12:08 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-01-16 21:12:08 (GMT)
commit52ac5b1b340335f56ceb599dba63164a26f10b10 (patch)
tree275104896dffa65e7887284857fa8fed831e9ea8 /src/glibext
parent2ddb5c26af896b10517a89abf0c9498c598b7697 (diff)
Changed the display of a segment containing the value of an immediate.
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/gbufferline.c115
-rw-r--r--src/glibext/gbufferline.h3
-rw-r--r--src/glibext/gbuffersegment.c42
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c132
5 files changed, 284 insertions, 11 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index 2680dae..1a17a9c 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -74,6 +74,9 @@ static GBufferSegment *get_segment_at(const buffer_line_column *, gint *, GdkScr
/* Fournit le segment voisin d'un autre segment identifié. */
static GBufferSegment *find_near_segment(const buffer_line_column *, GBufferSegment *, GdkScrollDirection);
+/* Fournit le segment créé par un objet particulier. */
+static GBufferSegment *find_segment_from_creator(const buffer_line_column *, GObject *);
+
/* Imprime le contenu d'une colonne de ligne de texte. */
static void draw_segments_of_column(buffer_line_column *, cairo_t *, gint, gint, const segcnt_list *);
@@ -121,6 +124,8 @@ struct _GBufferLineClass
/* Signaux */
+ void (* content_changed) (GBufferLine *, GBufferSegment *);
+
void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags);
};
@@ -138,6 +143,9 @@ static void g_buffer_line_dispose(GBufferLine *);
/* Procède à la libération totale de la mémoire. */
static void g_buffer_line_finalize(GBufferLine *);
+/* Réagit au changement de contenu d'un segment encapsulé. */
+static void on_line_segment_changed(GBufferSegment *, GBufferLine *);
+
/* ---------------------------------------------------------------------------------- */
@@ -145,9 +153,6 @@ static void g_buffer_line_finalize(GBufferLine *);
/* ---------------------------------------------------------------------------------- */
-
-
-
/******************************************************************************
* *
* Paramètres : column = colonne de ligne à mettre à jour. *
@@ -333,13 +338,14 @@ static GBufferSegment *get_segment_at(const buffer_line_column *column, gint *x,
static GBufferSegment *find_near_segment(const buffer_line_column *column, GBufferSegment *target, GdkScrollDirection dir)
{
GBufferSegment *result; /* Trouvaille à retourner */
+ bool found; /* Le segment est bien présent */
size_t i; /* Boucle de parcours */
result = NULL;
- column_has_segment(column, target, &i);
+ found = column_has_segment(column, target, &i);
- if (i < column->count)
+ if (found)
switch (dir)
{
case GDK_SCROLL_LEFT:
@@ -364,6 +370,41 @@ static GBufferSegment *find_near_segment(const buffer_line_column *column, GBuff
/******************************************************************************
* *
+* Paramètres : column = colonne de ligne de texte à consulter. *
+* creator = créateur à l'origine du segment recherché. *
+* *
+* Description : Fournit le segment créé par un objet particulier. *
+* *
+* Retour : Segment trouvé ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBufferSegment *find_segment_from_creator(const buffer_line_column *column, GObject *creator)
+{
+ GBufferSegment *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours #1 */
+ GBufferSegment *iter; /* Boucle de parcours #2 */
+
+ result = NULL;
+
+ for (i = 0; i < column->count && result == NULL; i++)
+ {
+ iter = column->segments[i];
+
+ if (g_buffer_segment_get_creator(iter) == creator)
+ result = iter;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : column = colonne de ligne de texte à manipuler. *
* cairo = contexte graphique à utiliser pour les pinceaux. *
* x_init = abscisse du point d'impression de départ. *
@@ -491,6 +532,14 @@ static void g_buffer_line_class_init(GBufferLineClass *class)
g_free(filename);
+ g_signal_new("content-changed",
+ G_TYPE_BUFFER_LINE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GBufferLineClass, content_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
g_signal_new("flip-flag",
G_TYPE_BUFFER_LINE,
G_SIGNAL_RUN_LAST,
@@ -1097,6 +1146,57 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer
/******************************************************************************
* *
+* Paramètres : line = ligne à venir consulter. *
+* creator = créateur à l'origine du segment recherché. *
+* *
+* Description : Fournit le segment créé par un objet particulier. *
+* *
+* Retour : Segment trouvé dans la ligne ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *line, GObject *creator)
+{
+ GBufferSegment *result; /* Trouvaille à retourner */
+ BufferLineColumn i; /* Boucle de parcours */
+
+ result = NULL;
+
+ for (i = 0; i < BLC_COUNT && result == NULL; i++)
+ result = find_segment_from_creator(&line->columns[i], creator);
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : segment = segment de texte dont le contenu vient de changer. *
+* line = ligne contenant ce segment. *
+* *
+* Description : Réagit au changement de contenu d'un segment encapsulé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_segment_changed(GBufferSegment *segment, GBufferLine *line)
+{
+ g_signal_emit_by_name(line, "content-changed");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne à venir compléter. *
* column = colonne de la ligne visée par l'insertion. *
* text = texte à insérer dans l'existant. *
@@ -1115,8 +1215,7 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co
{
GBufferSegment *result; /* Portion de texte à renvoyer */
- if (length == 0)
- return;
+ assert(length > 0);
if (column == BLC_MAIN)
column = line->main_column;
@@ -1129,6 +1228,8 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn co
result = g_buffer_segment_new(type, text, length);
g_buffer_line_add_segment(line, column, result);
+ g_signal_connect(result, "content-changed", G_CALLBACK(on_line_segment_changed), line);
+
return result;
}
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 7ba5467..13ba87b 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -122,6 +122,9 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BL
/* 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 *);
+/* Fournit le segment créé par un objet particulier. */
+GBufferSegment *g_buffer_line_find_segment_from_creator(const GBufferLine *, GObject *);
+
/* Ajoute du texte à formater dans une ligne donnée. */
GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 8e7613f..af77c38 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -125,6 +125,10 @@ struct _GBufferSegmentClass
double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */
rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */
+ /* Signaux */
+
+ void (* content_changed) (GBufferSegment *);
+
};
@@ -296,6 +300,16 @@ static void g_buffer_segment_class_init(GBufferSegmentClass *class)
gtk_widget_path_free(path);
g_object_unref(context);
+ /* Signaux */
+
+ g_signal_new("content-changed",
+ G_TYPE_BUFFER_SEGMENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GBufferSegmentClass, content_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
}
@@ -478,6 +492,34 @@ GObject *g_buffer_segment_get_creator(const GBufferSegment *segment)
/******************************************************************************
* *
+* Paramètres : segment = fragment de texte à mettre à jour. *
+* text = chaîne de caractères à traiter. *
+* length = quantité de ces caractères. *
+* *
+* Description : Met à jour le contenu d'un fragment de texte. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_segment_update_text(GBufferSegment *segment, const char *text, size_t length)
+{
+ free(segment->text);
+
+ segment->text = strndup(text, length);
+ segment->hash = fnv_64a_hash(segment->text);
+
+ g_buffer_segment_prepare(segment, length);
+
+ g_signal_emit_by_name(segment, "content-changed");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : segment = fragment de texte à consulter. *
* ref = segment de référence servant à la comparaison. *
* *
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 67091fb..57e3575 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -109,6 +109,9 @@ void g_buffer_segment_set_creator(GBufferSegment *, GObject *);
/* Renvoie vers un éventuel objet lié en tant que créateur. */
GObject *g_buffer_segment_get_creator(const GBufferSegment *);
+/* Met à jour le contenu d'un fragment de texte. */
+void g_buffer_segment_update_text(GBufferSegment *, const char *, size_t);
+
/* Indique si les textes de deux segments sont identiques. */
bool g_buffer_segment_compare(const GBufferSegment *, const GBufferSegment *);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index b211c4a..1654a72 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -111,6 +111,10 @@ struct _GCodeBufferClass
{
GObjectClass parent; /* A laisser en premier */
+ /* Signaux */
+
+ void (* line_changed) (GCodeBuffer *, GBufferLine *, GBufferSegment *);
+
};
@@ -136,6 +140,15 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, const vmpa2t *
/* Actualise les largeurs maximales par groupes de lignes. */
static void g_code_buffer_update_line_max_widths(const GCodeBuffer *, size_t, size_t);
+/* Réagit à un changement de contenu d'une ligne donnée. */
+static void on_line_content_change(GBufferLine *, GBufferSegment *, GCodeBuffer *);
+
+/* Réagit à un changement de propriété rattachée à une ligne. */
+static void on_line_flag_flip(GBufferLine *, BufferLineFlags, BufferLineFlags, GCodeBuffer *);
+
+/* Ajoute une nouvelle ligne à une position donnée. */
+static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *, size_t, const mrange_t *);
+
/* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */
@@ -191,6 +204,9 @@ static void g_buffer_view_dispose(GBufferView *);
/* Procède à la libération totale de la mémoire. */
static void g_buffer_view_finalize(GBufferView *);
+/* Réagit à un changement de contenu d'une ligne donnée. */
+static void on_buffer_line_changed(GCodeBuffer *, GBufferLine *, GBufferSegment *, GBufferView *);
+
/* Réinitialise le cache de la hauteur des lignes. */
static void g_buffer_view_reset_required_height(GBufferView *);
@@ -366,6 +382,13 @@ G_DEFINE_TYPE(GCodeBuffer, g_code_buffer, G_TYPE_OBJECT);
static void g_code_buffer_class_init(GCodeBufferClass *class)
{
+ g_signal_new("line-changed",
+ G_TYPE_CODE_BUFFER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(GCodeBufferClass, line_changed),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT);
}
@@ -691,10 +714,53 @@ static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size
/******************************************************************************
* *
-* Paramètres : buffer = composant GTK à mettre à jour. *
+* Paramètres : line = ligne dont la définition vient d'évoluer. *
+* segment = éventuel segment qui vient d'évoluer ou NULL. *
+* buffer = tampon de lignes cohérentes à manipuler. *
+* *
+* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_content_change(GBufferLine *line, GBufferSegment *segment, GCodeBuffer *buffer)
+{
+ g_signal_emit_by_name(buffer, "line-changed", line, segment);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : line = ligne dont la définition vient d'évoluer. *
+* old = ancien groupe de propriétés associées. *
+* old = nouveau groupe de propriétés associées. *
+* buffer = tampon de lignes cohérentes à manipuler. *
+* *
+* Description : Réagit à un changement de propriété rattachée à une ligne. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_line_flag_flip(GBufferLine *line, BufferLineFlags old, BufferLineFlags new, GCodeBuffer *buffer)
+{
+ g_signal_emit_by_name(buffer, "line-changed", line, NULL);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GLib à mettre à jour. *
* range = emplacement où va se situer la ligne. *
* *
-* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. *
+* Description : Ajoute une nouvelle ligne à une position donnée. *
* *
* Retour : Nouvelle ligne vierge à écrire. *
* *
@@ -702,7 +768,7 @@ static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size
* *
******************************************************************************/
-GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range)
+static GBufferLine *g_code_buffer_create_new_line(GCodeBuffer *buffer, size_t index, const mrange_t *range)
{
GBufferLine *result; /* Instance à retourner */
size_t i; /* Boucle de parcours */
@@ -714,12 +780,42 @@ GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *
buffer->count * sizeof(GBufferLine *));
}
+ buffer->used++;
+ assert(index < buffer->used);
+
result = g_buffer_line_new(range, buffer->main_column);
- buffer->lines[buffer->used++] = result;
+ buffer->lines[index] = result;
for (i = 0; i < buffer->indent; i++)
g_buffer_line_insert_text(result, BLC_ASSEMBLY_HEAD, " ", 4, RTT_RAW);
+ g_signal_connect(result, "content-changed", G_CALLBACK(on_line_content_change), buffer);
+ g_signal_connect(result, "flip-flag", G_CALLBACK(on_line_flag_flip), buffer);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : buffer = composant GLib à mettre à jour. *
+* range = emplacement où va se situer la ligne. *
+* *
+* Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. *
+* *
+* Retour : Nouvelle ligne vierge à écrire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const mrange_t *range)
+{
+ GBufferLine *result; /* Instance à retourner */
+
+ result = g_code_buffer_create_new_line(buffer, buffer->used, range);
+
return result;
}
@@ -1031,6 +1127,8 @@ static void g_buffer_view_init(GBufferView *buffer)
static void g_buffer_view_dispose(GBufferView *view)
{
+ g_object_unref(G_OBJECT(view->buffer));
+
G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view));
}
@@ -1083,6 +1181,8 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
g_buffer_view_restrict(result, NULL, NULL);
+ g_signal_connect(buffer, "line-changed", G_CALLBACK(on_buffer_line_changed), result);
+
if (highlighted != NULL)
result->highlighted = highlighted;
else
@@ -1097,6 +1197,30 @@ GBufferView *g_buffer_view_new(GCodeBuffer *buffer, segcnt_list *highlighted)
/******************************************************************************
* *
+* Paramètres : buffer = tampon de lignes cohérentes à manipuler. *
+* line = ligne dont la définition vient d'évoluer. *
+* segment = éventuel segment qui vient d'évoluer ou NULL. *
+* view = vue active du tampon de lignes concerné. *
+* *
+* Description : Réagit à un changement de contenu d'une ligne donnée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_buffer_line_changed(GCodeBuffer *buffer, GBufferLine *line, GBufferSegment *segment, GBufferView *view)
+{
+ /* TODO : regarder si la vue et concernée et cibler d'avantage l'actualisation */
+
+ g_signal_emit_by_name(view, "need-redraw");
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : view = visualisateur à mettre à jour. *
* first = première ligne à imprimer. *
* last = première ligne hors cadre. *