summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/edge.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-03-19 21:13:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-03-19 21:13:51 (GMT)
commitcf97db0ea4d1ea983db38df85984034b49fa4f77 (patch)
treeb6d69945b24ec8da93f0bef7ccf4dfdbe1d920a2 /src/gtkext/graph/edge.c
parente7a85861ba8bcd00ceb7bf9e47f4eadccd48ce3f (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.c400
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);
+
+}