diff options
Diffstat (limited to 'src/glibext')
-rw-r--r-- | src/glibext/gbufferline.c | 12 | ||||
-rw-r--r-- | src/glibext/gbufferline.h | 2 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.c | 101 | ||||
-rw-r--r-- | src/glibext/gbuffersegment.h | 6 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.c | 121 | ||||
-rw-r--r-- | src/glibext/gcodebuffer.h | 10 |
6 files changed, 238 insertions, 14 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index ac838b8..0422af5 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -1010,15 +1010,15 @@ GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *line, GSLis * * * Description : Ajoute du texte à formater dans une ligne donnée. * * * -* Retour : - * +* Retour : Portion de texte mis en place, voire NULL. * * * * Remarques : - * * * ******************************************************************************/ -void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type) +GBufferSegment *g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const char *text, size_t length, RenderingTagType type) { - GBufferSegment *segment; /* Portion de texte à ajouter */ + GBufferSegment *result; /* Portion de texte à renvoyer */ if (length == 0) return; @@ -1031,8 +1031,10 @@ void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const else line->last_used = column; - segment = g_buffer_segment_new(type, text, length); - g_buffer_line_add_segment(line, column, segment); + result = g_buffer_segment_new(type, text, length); + g_buffer_line_add_segment(line, column, result); + + return result; } diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index bf703ab..3a00ce0 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -122,7 +122,7 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *, GBufferSegm GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *, GSList *, const GBufferSegment *); /* Ajoute du texte à formater dans une ligne donnée. */ -void g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType); +GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const char *, size_t, RenderingTagType); /* Donne le texte représenté par une ligne de tampon. */ char *g_buffer_line_get_text(const GBufferLine *, BufferLineColumn, BufferLineColumn, bool); diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c index 27891a8..d25d728 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -98,6 +98,8 @@ struct _GBufferSegment { GObject parent; /* A laisser en premier */ + GObject *creator; /* Objet à l'origine du segment*/ + char *text; /* Texte brut conservé */ fnv64_t hash; /* Empreinte pour comparaisons */ @@ -131,6 +133,12 @@ static void g_buffer_segment_class_init(GBufferSegmentClass *); /* Procède à l'initialisation d'un fragment de texte. */ static void g_buffer_segment_init(GBufferSegment *); +/* Supprime toutes les références externes. */ +static void g_buffer_segment_dispose(GBufferSegment *); + +/* Procède à la libération totale de la mémoire. */ +static void g_buffer_segment_finalize(GBufferSegment *); + /* Définit les dernières propriétés de rendu restantes. */ static void g_buffer_segment_prepare(GBufferSegment *, size_t); @@ -154,6 +162,7 @@ G_DEFINE_TYPE(GBufferSegment, g_buffer_segment, G_TYPE_OBJECT); static void g_buffer_segment_class_init(GBufferSegmentClass *class) { + GObjectClass *object; /* Autre version de la classe */ GtkStyleContext *context; /* Contexte pour les styles */ GtkWidgetPath *path; /* Chemin d'accès aux thèmes */ gchar *filename; /* Accès à une image 1x1 */ @@ -164,6 +173,11 @@ static void g_buffer_segment_class_init(GBufferSegmentClass *class) cairo_text_extents_t extents; /* Couverture des caractères */ RenderingTagType i; /* Boucle de parcours */ + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_segment_dispose; + object->finalize = (GObjectFinalizeFunc)g_buffer_segment_finalize; + /* Création d'un contexte d'accès */ path = gtk_widget_path_new(); @@ -285,6 +299,47 @@ static void g_buffer_segment_init(GBufferSegment *segment) /****************************************************************************** * * +* Paramètres : segment = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_segment_dispose(GBufferSegment *segment) +{ + if (segment->creator != NULL) + g_object_unref(segment->creator); + + G_OBJECT_CLASS(g_buffer_segment_parent_class)->dispose(G_OBJECT(segment)); + +} + + +/****************************************************************************** +* * +* Paramètres : segment = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_buffer_segment_finalize(GBufferSegment *segment) +{ + G_OBJECT_CLASS(g_buffer_segment_parent_class)->finalize(G_OBJECT(segment)); + +} + + +/****************************************************************************** +* * * Paramètres : type = propriétés de la zone de texte. * * text = chaîne de caractères à traiter. * * length = quantité de ces caractères. * @@ -359,6 +414,52 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, size_t length) /****************************************************************************** * * +* Paramètres : segment = instance de segment à compléter. * +* obj = instance GLib quelconque à mémoriser. * +* * +* Description : Associe à un segment un objet GLib identifié comme créateur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_segment_set_creator(GBufferSegment *segment, GObject *obj) +{ + if (segment->creator != NULL) + g_object_unref(segment->creator); + + segment->creator = obj; + g_object_ref(obj); + +} + + +/****************************************************************************** +* * +* Paramètres : segment = instance de segment à compléter. * +* * +* Description : Renvoie vers un éventuel objet lié en tant que créateur. * +* * +* Retour : Instance GLib quelconque ou NULL si aucune référencée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GObject *g_buffer_segment_get_creator(const GBufferSegment *segment) +{ + if (segment->creator != NULL) + g_object_ref(segment->creator); + + return segment->creator; + +} + + +/****************************************************************************** +* * * 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 ace4e42..51bfb2a 100644 --- a/src/glibext/gbuffersegment.h +++ b/src/glibext/gbuffersegment.h @@ -106,6 +106,12 @@ GType g_buffer_segment_get_type(void); /* Crée un nouveau fragment de texte avec des propriétés. */ GBufferSegment *g_buffer_segment_new(RenderingTagType, const char *, size_t); +/* Associe à un segment un objet GLib identifié comme créateur. */ +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 *); + /* 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 4b5378d..ac6e807 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -145,6 +145,7 @@ struct _GBufferView GCodeBuffer *buffer; /* Tampon de code visualisé */ vmpa_t start; /* Première ligne intégrée */ vmpa_t end; /* Dernière ligne intégrée */ + size_t first_index; /* Indice de la première ligne */ gint line_height; /* Hauteur maximale des lignes */ gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */ @@ -813,6 +814,8 @@ static void g_buffer_view_class_init(GBufferViewClass *class) static void g_buffer_view_init(GBufferView *buffer) { + buffer->first_index = 0; + g_buffer_view_reset_required_height(buffer); g_buffer_view_reset_required_widths(buffer); @@ -1156,6 +1159,112 @@ gint g_buffer_view_get_height(const GBufferView *view) /****************************************************************************** * * +* Paramètres : view = visualisation à consulter. * +* x = abscisse comprise dans le segment recherché. [OUT] * +* y = ordonnée comprise dans la ligne recherchée. * +* idx = indice de la ligne trouvée ou NULL. [OUT] * +* display = règles d'affichage des colonnes modulables. * +* segment = portion de texte recherchée ou NULL. [OUT] * +* * +* Description : Fournit la ligne et son segment présents à une position. * +* * +* Retour : Ligne retrouvée ou NULL si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *view, gint *x, gint y, size_t *idx, const bool *display, GBufferSegment **segment) +{ + GBufferLine *result; /* Ligne trouvée à retourner */ + gint lheight; /* Hauteur d'une ligne */ + size_t index; /* Indice attendu */ + + /* Recherche d'une ligne correspondante */ + + lheight = g_buffer_view_get_line_height(view); + index = view->first_index + y / lheight; + + if (idx != NULL) + *idx = index; + + result = (index < view->buffer->used ? view->buffer->lines[index] : NULL); + + /* Recherche du segment visé éventuel */ + + if (result != NULL && segment != NULL) + { + if (*x < view->left_text) + *segment = NULL; + + else + *segment = g_buffer_line_get_segment_at(result, view->max_widths, display, x, GDK_SCROLL_LEFT, true); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : view = vue de tampon à mettre à jour. * +* x = abscisse de la zone principale à traiter. * +* y = ordonnée 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é. * +* * +* Retour : Adresse si une a pu être déterminée, NULL sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const vmpa2t *g_buffer_view_compute_caret(GBufferView *view, gint x, gint y, const bool *display, GdkRectangle *caret) +{ + gint remaining; /* Copie de travail modifiable */ + size_t index; /* Indice de ligne de tampon */ + GBufferLine *line; /* Ligne à la position courante*/ + GBufferSegment *segment; /* Segment présent sur la place*/ + + remaining = x; + + line = g_buffer_view_find_line_and_segment_at(view, &remaining, y, &index, display, &segment); + + if (line == NULL) return NULL; + 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 - remaining, remaining, g_buffer_segment_get_caret_position(segment, remaining), + g_buffer_segment_get_width(segment)); + + printf(" '%s'\n", g_buffer_segment_get_text(segment, false)); + + + + + caret->x = (x - remaining) + g_buffer_segment_get_caret_position(segment, remaining); + + caret->y = (index - view->first_index) * view->line_height; + + caret->width = 2; + caret->height = view->line_height; + + return get_mrange_addr(g_buffer_line_get_range(line)); + +} + + +/****************************************************************************** +* * * Paramètres : view = vue de tampon à mettre à jour. * * line = ligne correspondant à la position. * * index = indice de cette même ligne dans le tampon. * @@ -1171,7 +1280,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, const bool *display, GdkRectangle *caret) +const vmpa2t *g_buffer_view_compute_caret_old(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*/ @@ -1428,7 +1537,7 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b if (index > first) { line = view->buffer->lines[index - 1]; - result = g_buffer_view_compute_caret(view, line, index - 1, caret->x, display, caret); + result = g_buffer_view_compute_caret_old(view, line, index - 1, caret->x, display, caret); } break; @@ -1438,7 +1547,7 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b if (index < last) { line = view->buffer->lines[index + 1]; - result = g_buffer_view_compute_caret(view, line, index + 1, caret->x, display, caret); + result = g_buffer_view_compute_caret_old(view, line, index + 1, caret->x, display, caret); } break; @@ -1453,7 +1562,7 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b if (!moved && index > first) { line = view->buffer->lines[index - 1]; - result = g_buffer_view_compute_caret(view, line, index - 1, INT_MAX, display, caret); + result = g_buffer_view_compute_caret_old(view, line, index - 1, INT_MAX, display, caret); } break; @@ -1468,7 +1577,7 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b if (!moved && index < last) { line = view->buffer->lines[index + 1]; - result = g_buffer_view_compute_caret(view, line, index + 1, left_pos, display, caret); + result = g_buffer_view_compute_caret_old(view, line, index + 1, left_pos, display, caret); } break; @@ -1486,7 +1595,7 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b /* if (result && !computed) - result = g_buffer_view_compute_caret(view, caret->x, caret->y, caret, display, NULL); + result = g_buffer_view_compute_caret_old(view, caret->x, caret->y, caret, display, NULL); */ return result; diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index 5fd4e7b..e607b9c 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -128,8 +128,14 @@ gint g_buffer_view_get_width(GBufferView *, const bool *); /* Fournit la hauteur requise par une visualisation. */ gint g_buffer_view_get_height(const GBufferView *); +/* Fournit la ligne et son segment présents à une position. */ +GBufferLine *g_buffer_view_find_line_and_segment_at(GBufferView *, gint *, gint, size_t *, const bool *, GBufferSegment **); + +/* Calcule la position idéale de curseur pour un point donné. */ +const vmpa2t *g_buffer_view_compute_caret(GBufferView *, gint, gint, const bool *, GdkRectangle *); + /* Calcule la position idéale de curseur pour un point donné. */ -const vmpa2t *g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, const bool *, GdkRectangle *); +const vmpa2t *g_buffer_view_compute_caret_old(GBufferView *, GBufferLine *, size_t, gint, const bool *, GdkRectangle *) __attribute__ ((deprecated)); /* Déplace le curseur au sein d'une vue de tampon. */ const vmpa2t *g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, const bool *); @@ -147,7 +153,7 @@ void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_ void g_buffer_view_export(const GBufferView *, buffer_export_context *, BufferExportType, const bool *); /* Fournit la ligne présente à une ordonnée donnée. */ -GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); +GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *) __attribute__ ((deprecated)); /* Indique la position d'affichage d'une adresse donnée. */ bool g_buffer_view_get_address_coordinates(GBufferView *, const vmpa2t *, gint *, gint *, bool); |