summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/edge.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-05-05 13:18:46 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-05-05 13:18:46 (GMT)
commit114e769bc9c3dc48f0293f080d687451e32220e3 (patch)
tree3d79e9a4783adb52f6a14d00102ad6940c04acf6 /src/gtkext/graph/edge.c
parentcf97db0ea4d1ea983db38df85984034b49fa4f77 (diff)
Implemented first basic steps towards nice graph rendering.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@346 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext/graph/edge.c')
-rw-r--r--src/gtkext/graph/edge.c178
1 files changed, 164 insertions, 14 deletions
diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c
index 0eb0230..4aedbde 100644
--- a/src/gtkext/graph/edge.c
+++ b/src/gtkext/graph/edge.c
@@ -27,6 +27,9 @@
#include <math.h>
+#include "nodes/virtual.h"
+
+
/* Lien graphique entre deux noeuds graphiques (instance) */
struct _GGraphEdge
@@ -38,6 +41,12 @@ struct _GGraphEdge
GFlowNode *dest_node; /* Bloc d'arrivée du lien */
node_slot_t *dest_slot; /* Numéro d'ancrage final */
+ hspan_slot_t top_step; /* Niveau sup. de destination */
+ GVirtualNode *container; /* Conteneur pour les tours */
+ bool is_left; /* Tour par la gauche ? */
+ vspan_slot_t vert_step; /* Position de contournement */
+ hspan_slot_t bottom_step; /* Niveau inf. de source */
+
EdgeColor color; /* Couleur du rendu */
GdkPoint *points; /* Points de la ligne dessinée */
size_t count; /* Quantité de ces points */
@@ -52,12 +61,6 @@ struct _GGraphEdgeClass
};
-#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 *);
@@ -117,6 +120,8 @@ static void g_graph_edge_class_init(GGraphEdgeClass *klass)
static void g_graph_edge_init(GGraphEdge *edge)
{
+ edge->top_step = UNINITIALIZED_HSPAN_SLOT;
+ edge->bottom_step = UNINITIALIZED_HSPAN_SLOT;
}
@@ -138,6 +143,9 @@ static void g_graph_edge_dispose(GGraphEdge *edge)
g_object_unref(G_OBJECT(edge->src_node));
g_object_unref(G_OBJECT(edge->dest_node));
+ if (edge->container != NULL)
+ g_object_unref(G_OBJECT(edge->container));
+
G_OBJECT_CLASS(g_graph_edge_parent_class)->dispose(G_OBJECT(edge));
}
@@ -157,6 +165,9 @@ static void g_graph_edge_dispose(GGraphEdge *edge)
static void g_graph_edge_finalize(GGraphEdge *edge)
{
+ if (edge->points != NULL)
+ free(edge->points);
+
G_OBJECT_CLASS(g_graph_edge_parent_class)->finalize(G_OBJECT(edge));
}
@@ -201,7 +212,101 @@ GGraphEdge *g_graph_edge_new(GFlowNode *src_node, node_slot_t *src_slot, GFlowNo
/******************************************************************************
* *
-* Paramètres : edge = ligne de rendu à mettre à jour. *
+* Paramètres : edge = ligne de rendu à mettre à jour. *
+* nodes = noeud au sommet de la hiérarchie. *
+* ranks = classement global dans lequel s'intégrer. *
+* *
+* Description : Prend les dispositions nécessaires à l'insertion du lien. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_graph_edge_reserve_vertical_space(GGraphEdge *edge, GGraphNode *nodes, GGraphRanks *ranks)
+{
+ GGraphNode *container; /* Conteneur du lien de boucle */
+ unsigned int r1; /* Classement de départ */
+ unsigned int r2; /* Classement d'arrivée */
+
+ switch (edge->color)
+ {
+ case EGC_BLUE:
+
+ container = g_graph_node_find_container(nodes, G_GRAPH_NODE(edge->dest_node));
+ g_object_ref(G_OBJECT(container));
+ edge->container = G_VIRTUAL_NODE(container);
+
+ edge->is_left = false; /* TODO */
+
+ r1 = g_graph_node_get_rank(G_GRAPH_NODE(edge->src_node));
+ r2 = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node));
+
+ edge->vert_step = g_virtual_node_reserve_span(edge->container, r1, r2, edge->is_left);
+
+ break;
+
+ default:
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : edge = ligne de rendu à mettre à jour. *
+* ranks = classement global dans lequel s'intégrer. *
+* *
+* Description : Prend les dispositions nécessaires à l'insertion du lien. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_graph_edge_reserve_horizontal_space(GGraphEdge *edge, GGraphRanks *ranks)
+{
+ GdkPoint x_src; /* Abscisse au niveau du départ*/
+ GdkPoint x_dest; /* Abscisse au niveau d'arrivée*/
+ gint x_step; /* Transition verticale */
+ unsigned int rank; /* Indice de classement */
+
+ x_src = g_flow_node_get_point_from_slot(edge->src_node, false, edge->src_slot);
+ x_dest = g_flow_node_get_point_from_slot(edge->dest_node, true, edge->dest_slot);
+
+ switch (edge->color)
+ {
+ case EGC_BLUE:
+
+ x_step = g_virtual_node_get_x_for_vspan_slot(edge->container,
+ edge->vert_step, edge->is_left);
+
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->src_node));
+ edge->bottom_step = g_graph_ranks_reserve_span(ranks, rank, x_src.x, x_step, false);
+
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node));
+ edge->top_step = g_graph_ranks_reserve_span(ranks, rank, x_dest.x, x_step, true);
+
+ break;
+
+ default:
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node));
+ edge->top_step = g_graph_ranks_reserve_span(ranks, rank, x_src.x, x_dest.x, true);
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : edge = ligne de rendu à mettre à jour. *
+* ranks = classement global dans lequel s'intégrer. *
* *
* Description : Etablit le tracé du lien graphique entre deux noeuds. *
* *
@@ -211,19 +316,16 @@ GGraphEdge *g_graph_edge_new(GFlowNode *src_node, node_slot_t *src_slot, GFlowNo
* *
******************************************************************************/
-void g_graph_edge_compute(GGraphEdge *edge)
+void g_graph_edge_compute(GGraphEdge *edge, GGraphRanks *ranks)
{
GdkPoint start; /* Point de départ */
GdkPoint end; /* Point d'arrivée */
+ gint x_step; /* Transition verticale */
+ unsigned int rank; /* Indice de classement */
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;
@@ -235,16 +337,64 @@ void g_graph_edge_compute(GGraphEdge *edge)
/* Points de jonction */
+ switch (edge->color)
+ {
+ case EGC_BLUE:
+
+ edge->count += 4;
+ edge->points = (GdkPoint *)realloc(edge->points, edge->count * sizeof(GdkPoint));
+
+ x_step = g_virtual_node_get_x_for_vspan_slot(edge->container,
+ edge->vert_step, edge->is_left);
+
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->src_node));
+ edge->points[edge->count - 4].x = start.x;
+ edge->points[edge->count - 4].y = g_graph_ranks_get_y_for_hspan_slot(ranks, rank,
+ edge->bottom_step,
+ false);
+
+ edge->points[edge->count - 3].x = x_step;
+ edge->points[edge->count - 3].y = edge->points[edge->count - 4].y;
+
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node));
+
+ edge->points[edge->count - 2].x = x_step;
+ edge->points[edge->count - 2].y = g_graph_ranks_get_y_for_hspan_slot(ranks, rank,
+ edge->top_step,
+ true);
+ edge->points[edge->count - 1].x = end.x;
+ edge->points[edge->count - 1].y = edge->points[edge->count - 2].y;
+
+ break;
+
+ default:
+
+ edge->count += 2;
+ edge->points = (GdkPoint *)realloc(edge->points, edge->count * sizeof(GdkPoint));
+
+ rank = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node));
+
+ edge->points[edge->count - 2].x = start.x;
+ edge->points[edge->count - 2].y = g_graph_ranks_get_y_for_hspan_slot(ranks, rank,
+ edge->top_step,
+ true);
+
+ edge->points[edge->count - 1].x = end.x;
+ edge->points[edge->count - 1].y = edge->points[edge->count - 2].y;
+
+ break;
+
+ }
/* 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;
+ edge->points[edge->count - 1] = end;
}