diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-01-16 21:12:08 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-01-16 21:12:08 (GMT) |
commit | 52ac5b1b340335f56ceb599dba63164a26f10b10 (patch) | |
tree | 275104896dffa65e7887284857fa8fed831e9ea8 /src/glibext | |
parent | 2ddb5c26af896b10517a89abf0c9498c598b7697 (diff) |
Changed the display of a segment containing the value of an immediate.
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/gbufferline.c | 115 | ||||
-rw-r--r-- | src/glibext/gbufferline.h | 3 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.c | 42 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.h | 3 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.c | 132 |
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. * |