diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2013-03-19 21:13:51 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2013-03-19 21:13:51 (GMT) |
commit | cf97db0ea4d1ea983db38df85984034b49fa4f77 (patch) | |
tree | b6d69945b24ec8da93f0bef7ccf4dfdbe1d920a2 /src/gtkext/graph/edge.c | |
parent | e7a85861ba8bcd00ceb7bf9e47f4eadccd48ce3f (diff) |
Defined the first steps towards new graph renderings.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@345 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext/graph/edge.c')
-rw-r--r-- | src/gtkext/graph/edge.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c new file mode 100644 index 0000000..0eb0230 --- /dev/null +++ b/src/gtkext/graph/edge.c @@ -0,0 +1,400 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * edge.c - liens entre les noeuds d'un graphique + * + * Copyright (C) 2013 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "edge.h" + + +#include <math.h> + + + +/* Lien graphique entre deux noeuds graphiques (instance) */ +struct _GGraphEdge +{ + GObject parent; /* A laisser en premier */ + + GFlowNode *src_node; /* Bloc de départ du lien */ + node_slot_t *src_slot; /* Numéro d'ancrage initial */ + GFlowNode *dest_node; /* Bloc d'arrivée du lien */ + node_slot_t *dest_slot; /* Numéro d'ancrage final */ + + EdgeColor color; /* Couleur du rendu */ + GdkPoint *points; /* Points de la ligne dessinée */ + size_t count; /* Quantité de ces points */ + +}; + +/* Lien graphique entre deux noeuds graphiques (classe) */ +struct _GGraphEdgeClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +#define SLOT_VERT_SEP 20 + +#define ARROW_LENGHT 10 +#define ARROW_DEGREES 10 + + +/* Initialise la classe des liens graphiques entre deux noeuds. */ +static void g_graph_edge_class_init(GGraphEdgeClass *); + +/* Initialise une encapsulation de bloc virtuel. */ +static void g_graph_edge_init(GGraphEdge *); + +/* Supprime toutes les références externes. */ +static void g_graph_edge_dispose(GGraphEdge *); + +/* Procède à la libération totale de la mémoire. */ +static void g_graph_edge_finalize(GGraphEdge *); + +/* Dessine une flèche au bout du lien représenté. */ +static void draw_link_arrow(cairo_t *, gint, gint, gint, gint); + + + +/* Indique le type définit par la GLib pour les liens graphiques entre noeuds. */ +G_DEFINE_TYPE(GGraphEdge, g_graph_edge, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des liens graphiques entre deux noeuds. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_graph_edge_class_init(GGraphEdgeClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_graph_edge_dispose; + object->finalize = (GObjectFinalizeFunc)g_graph_edge_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : edge = instance à initialiser. * +* * +* Description : Initialise un lien graphique entre deux noeuds graphiques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_graph_edge_init(GGraphEdge *edge) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : edge = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_graph_edge_dispose(GGraphEdge *edge) +{ + g_object_unref(G_OBJECT(edge->src_node)); + g_object_unref(G_OBJECT(edge->dest_node)); + + G_OBJECT_CLASS(g_graph_edge_parent_class)->dispose(G_OBJECT(edge)); + +} + + +/****************************************************************************** +* * +* Paramètres : edge = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_graph_edge_finalize(GGraphEdge *edge) +{ + G_OBJECT_CLASS(g_graph_edge_parent_class)->finalize(G_OBJECT(edge)); + +} + + +/****************************************************************************** +* * +* Paramètres : src_node = bloc de départ du lien. * +* src_slot = point d'ancrage associé. * +* dest_node = bloc d'arrivée du lien. * +* dest_slot = point d'ancrage associé. * +* color = couleur de rendu à l'écran. * +* * +* Description : Etablit un lien graphique entre deux noeuds graphiques. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGraphEdge *g_graph_edge_new(GFlowNode *src_node, node_slot_t *src_slot, GFlowNode *dest_node, node_slot_t *dest_slot, EdgeColor color) +{ + GGraphEdge *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_GRAPH_EDGE, NULL); + + g_object_ref(G_OBJECT(src_node)); + g_object_ref(G_OBJECT(dest_node)); + + result->src_node = src_node; + result->src_slot = src_slot; + result->dest_node = dest_node; + result->dest_slot = dest_slot; + + result->color = color; + + return G_GRAPH_EDGE(result); + +} + + +/****************************************************************************** +* * +* Paramètres : edge = ligne de rendu à mettre à jour. * +* * +* Description : Etablit le tracé du lien graphique entre deux noeuds. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_edge_compute(GGraphEdge *edge) +{ + GdkPoint start; /* Point de départ */ + GdkPoint end; /* Point d'arrivée */ + + start = g_flow_node_get_point_from_slot(edge->src_node, false, edge->src_slot); + end = g_flow_node_get_point_from_slot(edge->dest_node, true, edge->dest_slot); + + printf(" -- (%d ; %d) - (%d ; %d)\n", + start.x, start.y, + end.x, end.y); + + + /* Point de départ */ + + edge->count = 2; + edge->points = (GdkPoint *)calloc(edge->count, sizeof(GdkPoint)); + + edge->points[0] = start; + edge->points[1] = start; + edge->points[1].y += SLOT_VERT_SEP; + + /* Points de jonction */ + + + + /* Point d'arrivée */ + + edge->count += 2; + edge->points = (GdkPoint *)realloc(edge->points, edge->count * sizeof(GdkPoint)); + + edge->points[edge->count - 1] = end; + edge->points[edge->count - 2] = end; + edge->points[edge->count - 2].y -= SLOT_VERT_SEP; + +} + + +/****************************************************************************** +* * +* Paramètres : edge = ligne de rendu à manipuler. * +* drawable = surface de rendu à utiliser. * +* gc = contexte graphique du dessin. * +* * +* Description : Dessine les liens graphiques enregistrés dans le moteur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_edge_draw(const GGraphEdge *edge, GdkDrawable *drawable, GdkGC *gc) +{ + cairo_t *cairo; /* Gestionnaire de rendu */ + + cairo = gdk_cairo_create(drawable); + + _g_graph_edge_draw(edge, cairo, true); + + cairo_destroy(cairo); + +} + + +/****************************************************************************** +* * +* Paramètres : edge = ligne de rendu à manipuler. * +* cairo = assistant pour le rendu graphique. * +* arrow = indique le besoin en flèche à l'arrivée. * +* * +* Description : Dessine les liens graphiques enregistrés dans le moteur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void _g_graph_edge_draw(const GGraphEdge *edge, cairo_t *cairo, bool arrow) +{ + size_t i; /* Boucle de parcours */ + + switch (edge->color) + { + default: + case EGC_DEFAULT: + cairo_set_source_rgb(cairo, 0, 0, 0); + break; + case EGC_GREEN: + cairo_set_source_rgb(cairo, 0, 0.6, 0); + break; + case EGC_RED: + cairo_set_source_rgb(cairo, 0.8, 0, 0); + break; + case EGC_BLUE: + cairo_set_source_rgb(cairo, 0, 0, 0.8); + break; + case EGC_DASHED_GRAY: + cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4); + break; + } + + switch (edge->color) + { + default: + case EGC_DEFAULT: + case EGC_GREEN: + case EGC_RED: + case EGC_BLUE: + cairo_set_dash(cairo, (double []) { 6.0 }, 0, 0.0); + break; + case EGC_DASHED_GRAY: + cairo_set_dash(cairo, (double []) { 6.0 }, 1, 0.0); + break; + } + + /** + * Si on ne veut pas de flèche, on doit se destiner à un aperçu... + * Dans ce cas, pour plus de lisibilité, on double la taille d'impression. + * Et pour faire ressortir les boucles, on double encore les liens associés. + */ + cairo_set_line_width(cairo, arrow ? 1 : (edge->color == EGC_BLUE ? 4 : 2)); + + cairo_move_to(cairo, edge->points[0].x + 0.5, edge->points[0].y); + + for (i = 1; i < edge->count; i++) + cairo_line_to(cairo, edge->points[i].x + 0.5, edge->points[i].y); + + cairo_stroke(cairo); + + if (arrow) + draw_link_arrow(cairo, + edge->points[edge->count - 2].x, + edge->points[edge->count - 2].y, + edge->points[edge->count - 1].x, + edge->points[edge->count - 1].y); + +} + + +/****************************************************************************** +* * +* Paramètres : cairo = gestionnaire de rendu graphique. * +* start_x = abscisse du début du segment final. * +* start_y = ordonnée du début du segment final. * +* end_x = abscisse de fin de segment et pointe de flèche. * +* end_y = ordonnée de fin de segment et pointe de flèche. * +* * +* Description : Dessine une flèche au bout du lien représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void draw_link_arrow(cairo_t *cairo, gint start_x, gint start_y, gint end_x, gint end_y) +{ + double angle; /* Angle du triangle à remplir */ + double factor_x; /* Direction de la flèche #1 */ + double factor_y; /* Direction de la flèche #2 */ + double x1; /* Abscisse du point n°1 */ + double y1; /* Ordonnée du point n°1 */ + double x2; /* Abscisse du point n°2 */ + double y2; /* Ordonnée du point n°2 */ + + angle = atan2(end_y - start_y, end_x - start_x) + M_PI; + + factor_x = -1; + factor_y = -1; + + x1 = end_x + factor_x * ARROW_LENGHT * cos(angle - ARROW_DEGREES); + y1 = end_y + factor_y * ARROW_LENGHT * sin(angle - ARROW_DEGREES); + x2 = end_x + factor_x * ARROW_LENGHT * cos(angle + ARROW_DEGREES); + y2 = end_y + factor_y * ARROW_LENGHT * sin(angle + ARROW_DEGREES); + + cairo_move_to(cairo, end_x, end_y); + + cairo_line_to(cairo, x1, y1); + cairo_line_to(cairo, x2, y2); + + cairo_move_to(cairo, end_x, end_y); + + cairo_fill(cairo); + +} |