diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-02-15 22:58:40 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-02-15 22:58:40 (GMT) |
commit | 16242be5838a77690946cbb2f30b2e89f2df0b94 (patch) | |
tree | d3c2b2725f41f2a0d45ae7f32e2ab9cb1886b230 /src/gtkext | |
parent | 5ed40f0afbd58fbfdf05be7b2a10ab8d0819759f (diff) |
Displayed tooltips for graph view edges.
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/graph/cluster.c | 25 | ||||
-rw-r--r-- | src/gtkext/graph/edge.c | 39 | ||||
-rw-r--r-- | src/gtkext/graph/edge.h | 36 | ||||
-rw-r--r-- | src/gtkext/gtkgraphdisplay.c | 71 |
4 files changed, 151 insertions, 20 deletions
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c index c4deeaa..765bbac 100644 --- a/src/gtkext/graph/cluster.c +++ b/src/gtkext/graph/cluster.c @@ -460,6 +460,8 @@ static gint compute_leaving_link_position(const leaving_link_t *link) static incoming_link_t *create_incoming_link(GGraphCluster *owner, InstructionLinkType type, leaving_link_t *other) { incoming_link_t *result; /* Structure à retourner */ + GCodeBlock *src; /* Bloc d'origine du lien */ + GCodeBlock *dst; /* Bloc de destination du lien */ result = malloc(sizeof(incoming_link_t)); @@ -467,14 +469,23 @@ static incoming_link_t *create_incoming_link(GGraphCluster *owner, InstructionLi result->type = type; + src = other->owner->block; + dst = owner->block; + if (type == ILT_JUMP_IF_TRUE) - result->edge = g_graph_edge_new_true(&other->start[0], &other->start[1], &result->end[0], &result->end[1]); + result->edge = g_graph_edge_new_true(src, dst, + &other->start[0], &other->start[1], + &result->end[0], &result->end[1]); else if (type == ILT_JUMP_IF_FALSE) - result->edge = g_graph_edge_new_false(&other->start[0], &other->start[1], &result->end[0], &result->end[1]); + result->edge = g_graph_edge_new_false(src, dst, + &other->start[0], &other->start[1], + &result->end[0], &result->end[1]); else - result->edge = g_graph_edge_new(&other->start[0], &other->start[1], &result->end[0], &result->end[1]); + result->edge = g_graph_edge_new(src, dst, + &other->start[0], &other->start[1], + &result->end[0], &result->end[1]); result->other = other; @@ -499,6 +510,8 @@ static incoming_link_t *create_incoming_link(GGraphCluster *owner, InstructionLi static incoming_link_t *create_incoming_loop_link(GGraphCluster *owner, const GdkPoint *midpts, leaving_link_t *other) { incoming_link_t *result; /* Structure à retourner */ + GCodeBlock *src; /* Bloc d'origine du lien */ + GCodeBlock *dst; /* Bloc de destination du lien */ result = malloc(sizeof(incoming_link_t)); @@ -506,7 +519,11 @@ static incoming_link_t *create_incoming_loop_link(GGraphCluster *owner, const Gd result->type = ILT_LOOP; - result->edge = g_graph_edge_new_loop(&other->start[0], &other->start[1], + src = other->owner->block; + dst = owner->block; + + result->edge = g_graph_edge_new_loop(src, dst, + &other->start[0], &other->start[1], &midpts[0], &midpts[1], &result->end[0], &result->end[1]); diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c index 9a2f848..20f1988 100644 --- a/src/gtkext/graph/edge.c +++ b/src/gtkext/graph/edge.c @@ -36,6 +36,9 @@ struct _GGraphEdge { GObject parent; /* A laisser en premier */ + GCodeBlock *src; /* Bloc d'origine du lien */ + GCodeBlock *dst; /* Bloc de destination du lien */ + EdgeColor color; /* Couleur du rendu */ union @@ -137,6 +140,9 @@ static void g_graph_edge_init(GGraphEdge *edge) static void g_graph_edge_dispose(GGraphEdge *edge) { + g_clear_object(&edge->src); + g_clear_object(&edge->dst); + G_OBJECT_CLASS(g_graph_edge_parent_class)->dispose(G_OBJECT(edge)); } @@ -177,12 +183,18 @@ static void g_graph_edge_finalize(GGraphEdge *edge) * * ******************************************************************************/ -GGraphEdge *_g_graph_edge_new(const GdkPoint **templates, size_t count, EdgeColor color) +GGraphEdge *_g_graph_edge_new(GCodeBlock *src, GCodeBlock *dst, const GdkPoint **templates, size_t count, EdgeColor color) { GGraphEdge *result; /* Structure à retourner */ result = g_object_new(G_TYPE_GRAPH_EDGE, NULL); + result->src = src; + result->dst = dst; + + g_object_ref(G_OBJECT(src)); + g_object_ref(G_OBJECT(dst)); + result->color = color; assert(count == 4 || count == 6); @@ -200,6 +212,31 @@ GGraphEdge *_g_graph_edge_new(const GdkPoint **templates, size_t count, EdgeColo /****************************************************************************** * * * Paramètres : edge = ligne de rendu à consulter. * +* src = bloc d'origine du lien. [OUT] * +* dst = bloc de destination du lien. [OUT] * +* * +* Description : Fournit les deux blocs aux extrémités d'un lien. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_edge_get_boundaries(const GGraphEdge *edge, GCodeBlock **src, GCodeBlock **dst) +{ + *src = edge->src; + *dst = edge->dst; + + g_object_ref(G_OBJECT(*src)); + g_object_ref(G_OBJECT(*dst)); + +} + + +/****************************************************************************** +* * +* Paramètres : edge = ligne de rendu à consulter. * * x1 = abscisse du point de départ de la ligne. [OUT] * * x2 = abscisse du point d'arrivée de la ligne. [OUT] * * * diff --git a/src/gtkext/graph/edge.h b/src/gtkext/graph/edge.h index e905685..ec33544 100644 --- a/src/gtkext/graph/edge.h +++ b/src/gtkext/graph/edge.h @@ -30,13 +30,16 @@ #include <gtk/gtk.h> +#include "../../analysis/disass/block.h" -#define G_TYPE_GRAPH_EDGE g_graph_edge_get_type() -#define G_GRAPH_EDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GRAPH_EDGE, GGraphEdge)) -#define G_IS_GRAPH_EDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GRAPH_EDGE)) -#define G_GRAPH_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GRAPH_EDGE, GGraphEdgeClass)) -#define G_IS_GRAPH_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GRAPH_EDGE)) -#define G_GRAPH_EDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GRAPH_EDGE, GGraphEdgeClass)) + + +#define G_TYPE_GRAPH_EDGE g_graph_edge_get_type() +#define G_GRAPH_EDGE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GRAPH_EDGE, GGraphEdge)) +#define G_IS_GRAPH_EDGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GRAPH_EDGE)) +#define G_GRAPH_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GRAPH_EDGE, GGraphEdgeClass)) +#define G_IS_GRAPH_EDGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GRAPH_EDGE)) +#define G_GRAPH_EDGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GRAPH_EDGE, GGraphEdgeClass)) /* Lien graphique entre deux noeuds graphiques (instance) */ @@ -68,19 +71,22 @@ typedef enum _EdgeColor GType g_graph_edge_get_type(void); /* Etablit un lien graphique entre deux noeuds graphiques. */ -GGraphEdge *_g_graph_edge_new(const GdkPoint **, size_t, EdgeColor); +GGraphEdge *_g_graph_edge_new(GCodeBlock *, GCodeBlock *, const GdkPoint **, size_t, EdgeColor); + +#define g_graph_edge_new(src, dst, pts0, pts1, pte0, pte1) \ + _g_graph_edge_new(src, dst, (const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_DEFAULT) -#define g_graph_edge_new(pts0, pts1, pte0, pte1) \ - _g_graph_edge_new((const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_DEFAULT) +#define g_graph_edge_new_true(src, dst, pts0, pts1, pte0, pte1) \ + _g_graph_edge_new(src, dst, (const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_GREEN) -#define g_graph_edge_new_true(pts0, pts1, pte0, pte1) \ - _g_graph_edge_new((const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_GREEN) +#define g_graph_edge_new_false(src, dst, pts0, pts1, pte0, pte1) \ + _g_graph_edge_new(src, dst, (const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_RED) -#define g_graph_edge_new_false(pts0, pts1, pte0, pte1) \ - _g_graph_edge_new((const GdkPoint *[]) { pts0, pts1, pte0, pte1 }, 4, EGC_RED) +#define g_graph_edge_new_loop(src, dst, pts0, pts1, ptl0, ptl1, pte0, pte1) \ + _g_graph_edge_new(src, dst, (const GdkPoint *[]) { pts0, pts1, ptl0, ptl1, pte0, pte1 }, 6, EGC_BLUE) -#define g_graph_edge_new_loop(pts0, pts1, ptl0, ptl1, pte0, pte1) \ - _g_graph_edge_new((const GdkPoint *[]) { pts0, pts1, ptl0, ptl1, pte0, pte1 }, 6, EGC_BLUE) +/* Fournit les deux blocs aux extrémités d'un lien. */ +void g_graph_edge_get_boundaries(const GGraphEdge *, GCodeBlock **, GCodeBlock **); /* Fournit les abscisses des points extrèmes de la ligne. */ void g_graph_edge_get_x_borders(const GGraphEdge *, gint *, gint *); diff --git a/src/gtkext/gtkgraphdisplay.c b/src/gtkext/gtkgraphdisplay.c index 0915f3a..0865e04 100644 --- a/src/gtkext/gtkgraphdisplay.c +++ b/src/gtkext/gtkgraphdisplay.c @@ -27,11 +27,15 @@ #include <assert.h> +#include <i18n.h> + + #include "gtkblockdisplay.h" #include "gtkbufferdisplay.h" #include "gtkdisplaypanel-int.h" #include "graph/cluster.h" #include "../analysis/routine.h" +#include "../common/extstr.h" #include "../format/format.h" #include "../glibext/gbinarycursor.h" #include "../glibext/gloadedpanel.h" @@ -115,6 +119,9 @@ static gboolean gtk_graph_display_button_release(GtkWidget *, GdkEventButton *, /* Assure la suivi des déplacements de souris sur le composant. */ static gboolean gtk_graph_display_motion_notify(GtkWidget *, GdkEventMotion *, GtkGraphDisplay *); +/* Prépare l'affichage d'une astuce. */ +static gboolean gtk_graph_display_query_tooltip(GtkWidget *, gint, gint, gboolean, GtkTooltip *, GtkGraphDisplay *); + /* Ajuste au besoin la zone affichée pour un curseur. */ static void gtk_graph_display_prepare_for_cursor(GtkGraphDisplay *, const GLineCursor *); @@ -213,6 +220,10 @@ static void gtk_graph_display_init(GtkGraphDisplay *display) G_CALLBACK(gtk_graph_display_button_release), display); g_signal_connect(G_OBJECT(display->support), "motion-notify-event", G_CALLBACK(gtk_graph_display_motion_notify), display); + g_signal_connect(G_OBJECT(display->support), "query-tooltip", + G_CALLBACK(gtk_graph_display_query_tooltip), display); + + g_object_set(G_OBJECT(display->support), "has-tooltip", TRUE, NULL); gtk_widget_add_events(display->support, GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -649,6 +660,66 @@ static gboolean gtk_graph_display_motion_notify(GtkWidget *widget, GdkEventMotio /****************************************************************************** * * +* Paramètres : widget = composant GTK visé par l'opération. * +* x = abscisse de la position du message. * +* y = ordonnée de la position du message. * +* keyboard = indique une demande suite à obtiention du focus. * +* tooltip = astuce à compléter. [OUT] * +* display = support maître à consulter. * +* * +* Description : Prépare l'affichage d'une astuce. * +* * +* Retour : TRUE pour un affichage validé, FALSE sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_graph_display_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard, GtkTooltip *tooltip, GtkGraphDisplay *display) +{ + gboolean result; /* Bilan à retourner */ + GCodeBlock *src; /* Bloc d'origine du lien */ + GCodeBlock *dst; /* Bloc de destination du lien */ + char *info; /* Information à faire paraître*/ + char *desc; /* Description d'un bloc */ + + result = FALSE; + + if (display->hl_edge_index < display->edges_count) + { + g_graph_edge_get_boundaries(display->edges[display->hl_edge_index], &src, &dst); + + info = stradd(NULL, _("<b>Source:</b> ")); + + desc = g_code_block_build_tooltip(src); + info = stradd(info, desc); + free(desc); + + info = stradd(info, "\n\n"); + + info = stradd(info, _("<b>Destination:</b> ")); + + desc = g_code_block_build_tooltip(dst); + info = stradd(info, desc); + free(desc); + + gtk_tooltip_set_markup(tooltip, info); + free(info); + + g_object_unref(G_OBJECT(src)); + g_object_unref(G_OBJECT(dst)); + + result = TRUE; + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : display = composant GTK à mettre à jour. * * cursor = emplacement à présenter à l'écran. * * * |