summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/edge.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/graph/edge.c')
-rw-r--r--src/gtkext/graph/edge.c287
1 files changed, 41 insertions, 246 deletions
diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c
index 5750198..a917cc3 100644
--- a/src/gtkext/graph/edge.c
+++ b/src/gtkext/graph/edge.c
@@ -24,10 +24,10 @@
#include "edge.h"
+#include <assert.h>
+#include <malloc.h>
#include <math.h>
-
-
-#include "nodes/virtual.h"
+#include <string.h>
@@ -36,18 +36,13 @@ 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 */
- 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 */
+ const GdkPoint *start; /* Point de départ du lien */
+ GdkPoint *mid[2]; /* Etapes intermédiaires */
+ size_t m_count; /* Quantité de ces étapes */
+ const GdkPoint *end; /* Point d'arrivée du lien */
- EdgeColor color; /* Couleur du rendu */
GdkPoint *points; /* Points de la ligne dessinée */
size_t count; /* Quantité de ces points */
@@ -61,6 +56,11 @@ struct _GGraphEdgeClass
};
+/* Dimensions des flêches */
+#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 *);
@@ -120,8 +120,6 @@ 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;
}
@@ -140,12 +138,6 @@ static void g_graph_edge_init(GGraphEdge *edge)
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));
}
@@ -175,11 +167,11 @@ static void g_graph_edge_finalize(GGraphEdge *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. *
+* Paramètres : start = point de départ de la flêche. *
+* mid = points intermédiares variables. *
+* count = nombre de ces points fournis. *
+* end = point d'arrivée de la flêche. *
+* color = couleur de rendu à l'écran. *
* *
* Description : Etablit un lien graphique entre deux noeuds graphiques. *
* *
@@ -189,84 +181,33 @@ static void g_graph_edge_finalize(GGraphEdge *edge)
* *
******************************************************************************/
-GGraphEdge *g_graph_edge_new(GFlowNode *src_node, node_slot_t *src_slot, GFlowNode *dest_node, node_slot_t *dest_slot, EdgeColor color)
+GGraphEdge *_g_graph_edge_new(const GdkPoint *start, const GdkPoint **mid, size_t count, const GdkPoint *end, 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 : a = premier lien à considérer. *
-* b = second lien à considérer. *
-* *
-* Description : Etablit la comparaison entre deux liens graphiques. *
-* *
-* Retour : Bilan de la comparaison : -1, 0 ou 1. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-int g_graph_edge_compare(const GGraphEdge **a, const GGraphEdge **b)
-{
- int result; /* Bilan à retourner */
- const GGraphEdge *_a; /* Commodité d'accès #1 */
- const GGraphEdge *_b; /* Commodité d'accès #2 */
- GdkPoint start_a; /* Point de départ A */
- GdkPoint start_b; /* Point de départ B */
-
- _a = *a;
- _b = *b;
-
- /**
- * La comparaison s'établit sur le noeud d'arrivée.
- */
-
- if (_a->dest_node < _b->dest_node)
- result = -1;
+ assert(count == 1 || count == 2);
- else if (_a->dest_node > _b->dest_node)
- result = 1;
+ result->start = start;
- else
- {
- start_a = g_flow_node_get_point_from_slot(_a->src_node, false, _a->src_slot);
- start_b = g_flow_node_get_point_from_slot(_b->src_node, false, _b->src_slot);
+ memcpy(result->mid, mid, count * sizeof(GdkPoint));
+ result->m_count = count;
- result = g_flow_node_compare_slots_for_edges(_a->dest_node,
- _a->dest_slot, start_a.x,
- _b->dest_slot, start_b.x);
-
- }
+ result->end = end;
- return result;
+ return G_GRAPH_EDGE(result);
}
/******************************************************************************
* *
-* Paramètres : edge = ligne de rendu à mettre à jour. *
-* nodes = noeud au sommet de la hiérarchie. *
-* ranks = classement global dans lequel s'intégrer. *
+* Paramètres : edge = ligne de rendu à définir dans les détails. *
* *
-* Description : Prend les dispositions nécessaires à l'insertion du lien. *
+* Description : Détermine les positions finales d'un lien graphique. *
* *
* Retour : - *
* *
@@ -274,177 +215,31 @@ int g_graph_edge_compare(const GGraphEdge **a, const GGraphEdge **b)
* *
******************************************************************************/
-void g_graph_edge_reserve_vertical_space(GGraphEdge *edge, GGraphNode *nodes, GGraphRanks *ranks)
+void g_graph_edge_resolve(GGraphEdge *edge)
{
- 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 = true; /* 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 : - *
-* *
-******************************************************************************/
+ edge->count = 2 + 2 * edge->m_count;
+ edge->points = (GdkPoint *)calloc(edge->count, sizeof(GdkPoint));
-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 */
+ edge->points[0] = *edge->start;
- 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);
+ edge->points[1].x = edge->start->x;
+ edge->points[1].y = edge->mid[0]->y;
- switch (edge->color)
+ if (edge->m_count == 1)
{
- 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;
-
+ edge->points[2].x = edge->end->x;
+ edge->points[2].y = edge->mid[0]->y;
}
-
-}
-
-
-/******************************************************************************
-* *
-* 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. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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);
-
- /* 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 */
-
- switch (edge->color)
+ else
{
- 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);
+ memcpy(&edge->points[2], edge->mid, edge->m_count * sizeof(GdkPoint));
- 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;
+ edge->points[4].x = edge->end->x;
+ edge->points[4].y = edge->mid[3]->y;
}
- /* Point d'arrivée */
-
- edge->count += 2;
- edge->points = (GdkPoint *)realloc(edge->points, edge->count * sizeof(GdkPoint));
-
- edge->points[edge->count - 2] = end;
- edge->points[edge->count - 2].y -= SLOT_VERT_SEP;
- edge->points[edge->count - 1] = end;
+ edge->points[edge->count - 1] = *edge->end;
}