diff options
Diffstat (limited to 'src/gtkext/graph/edge.c')
-rw-r--r-- | src/gtkext/graph/edge.c | 178 |
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; } |