summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gtkext/graph/cluster.c704
1 files changed, 352 insertions, 352 deletions
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 765bbac..16afe57 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -97,6 +97,57 @@ static int cmp_incoming_links(const incoming_link_t **, const incoming_link_t **
+/* ------------------------ ENCADREMENTS D'ESPACES VERTICAUX ------------------------ */
+
+
+/* Réservations d'espaces latéraux */
+typedef struct _vspace_booking_t
+{
+ leaving_link_t *from; /* Bloc de départ du lien */
+ incoming_link_t *to; /* Bloc d'arrivée du lien */
+
+ GdkPoint *pts; /* Coordonnées des points */
+
+} vspace_booking_t;
+
+/* Réservations d'espaces latéraux */
+typedef struct _vspace_manager_t
+{
+ vspace_booking_t *pending; /* Besoins exprimés */
+ size_t pending_count; /* Nombre de ces besoins */
+
+ vspace_booking_t **left; /* Lignes disposées à gauche */
+ size_t left_count; /* Quantité de ces lignes */
+
+ vspace_booking_t **right; /* Lignes disposées à droite */
+ size_t right_count; /* Quantité de ces lignes */
+
+} vspace_manager_t;
+
+
+/* Initialise les réservations liens verticaux. */
+static void init_vspace_manager(vspace_manager_t *);
+
+/* Termine les réservations liens verticaux. */
+static void exit_vspace_manager(vspace_manager_t *);
+
+/* Inscrit une nouvelle réservation d'espace latéral. */
+static void extend_vspace_manager(vspace_manager_t *, leaving_link_t *, incoming_link_t *, GdkPoint *);
+
+/* Détermine l'emplacement requis pour les espaces latéraux. */
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, GtkAllocation *);
+
+/* Réorganise au besoin les liens de boucle entre blocs. */
+static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
+
+/* Détermine les abscisses de tous les liens en place. */
+static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
+
+/* Détermine les ordonnées de tous les liens en place. */
+static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
+
+
+
/* ---------------------- DESCENDANTS DIRECTS CLASSES PAR RANG ---------------------- */
@@ -175,57 +226,6 @@ static void set_y_for_graph_rank(const graph_rank_t *, gint *);
-/* ------------------------ ENCADREMENTS D'ESPACES VERTICAUX ------------------------ */
-
-
-/* Réservations d'espaces latéraux */
-typedef struct _vspace_booking_t
-{
- leaving_link_t *from; /* Bloc de départ du lien */
- incoming_link_t *to; /* Bloc d'arrivée du lien */
-
- GdkPoint *pts; /* Coordonnées des points */
-
-} vspace_booking_t;
-
-/* Réservations d'espaces latéraux */
-typedef struct _vspace_manager_t
-{
- vspace_booking_t *pending; /* Besoins exprimés */
- size_t pending_count; /* Nombre de ces besoins */
-
- vspace_booking_t **left; /* Lignes disposées à gauche */
- size_t left_count; /* Quantité de ces lignes */
-
- vspace_booking_t **right; /* Lignes disposées à droite */
- size_t right_count; /* Quantité de ces lignes */
-
-} vspace_manager_t;
-
-
-/* Initialise les réservations liens verticaux. */
-static void init_vspace_manager(vspace_manager_t *);
-
-/* Termine les réservations liens verticaux. */
-static void exit_vspace_manager(vspace_manager_t *);
-
-/* Inscrit une nouvelle réservation d'espace latéral. */
-static void extend_vspace_manager(vspace_manager_t *, leaving_link_t *, incoming_link_t *, GdkPoint *);
-
-/* Détermine l'emplacement requis pour les espaces latéraux. */
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, GtkAllocation *);
-
-/* Réorganise au besoin les liens de boucle entre blocs. */
-static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
-
-/* Détermine les abscisses de tous les liens en place. */
-static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
-
-/* Détermine les ordonnées de tous les liens en place. */
-static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
-
-
-
/* -------------------------- DEFINITION D'UN CHEF DE FILE -------------------------- */
@@ -592,6 +592,307 @@ static int cmp_incoming_links(const incoming_link_t **a, const incoming_link_t *
/* ---------------------------------------------------------------------------------- */
+/* ENCADREMENTS D'ESPACES VERTICAUX */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = structure à initialiser. *
+* *
+* Description : Initialise les réservations liens verticaux. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void init_vspace_manager(vspace_manager_t *manager)
+{
+ manager->pending = NULL;
+ manager->pending_count = 0;
+
+ manager->left = NULL;
+ manager->left_count = 0;
+
+ manager->right = NULL;
+ manager->right_count = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = structure à vider. *
+* *
+* Description : Termine les réservations liens verticaux. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void exit_vspace_manager(vspace_manager_t *manager)
+{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < manager->pending_count; i++)
+ free(manager->pending[i].pts);
+
+ if (manager->pending != NULL)
+ free(manager->pending);
+
+ if (manager->left != NULL)
+ free(manager->left);
+
+ if (manager->right != NULL)
+ free(manager->right);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = structure à compléter. *
+* from = point de départ du lien concerné. *
+* to = point d'arrivée du lien concerné. *
+* pts = points intermédiaires du tracé complet final. *
+* *
+* Description : Inscrit une nouvelle réservation d'espace latéral. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
+{
+ vspace_booking_t *new; /* Réservation à constituer */
+
+ manager->pending = realloc(manager->pending, ++manager->pending_count * sizeof(vspace_booking_t));
+
+ new = &manager->pending[manager->pending_count - 1];
+
+ new->from = from;
+ new->to = to;
+
+ new->pts = pts;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestion des espaces latéraux à consulter. *
+* alloc = emplacement idéal pour l'affichage. [OUT] *
+* *
+* Description : Détermine l'emplacement requis pour les espaces latéraux. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, GtkAllocation *alloc)
+{
+ gint width; /* Largeur supplémentaire */
+
+ /* Extension de la largeur */
+
+ width = 0;
+
+ width += manager->left_count * LINK_MARGIN;
+
+ width += manager->right_count * LINK_MARGIN;
+
+ alloc->x -= width / 2;
+ alloc->width += width;
+
+ /* Extension de la hauteur */
+
+ alloc->height += manager->pending_count * VERTICAL_MARGIN;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = gestion d'espaces latéraux à manipuler. *
+* *
+* Description : Réorganise au besoin les liens de boucle entre blocs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void sort_incoming_links_for_vspace_manager(vspace_manager_t *manager)
+{
+ size_t i; /* Boucle de parcours */
+ vspace_booking_t *pending; /* Elément traité */
+ gint x1; /* Abscisse de départ de lien */
+ size_t idx; /* Indice du lien entrant */
+ gint x2; /* Abscisse d'arrivée de lien */
+
+ for (i = 0; i < manager->pending_count; i++)
+ {
+ pending = &manager->pending[i];
+
+ x1 = g_graph_cluster_compute_leaving_link_position(pending->from->owner, pending->from->index);
+
+ idx = g_graph_cluster_find_incoming_link(pending->to->owner, pending->from);
+
+ x2 = g_graph_cluster_compute_incoming_link_position(pending->to->owner, idx);
+
+ if (x1 < x2)
+ {
+ manager->left = realloc(manager->left, ++manager->left_count * sizeof(vspace_booking_t *));
+ manager->left[manager->left_count - 1] = pending;
+ }
+ else
+ {
+ manager->right = realloc(manager->right, ++manager->right_count * sizeof(vspace_booking_t *));
+ manager->right[manager->right_count - 1] = pending;
+ }
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = structure à consulter. *
+* cluster = graphique de blocs sur lequel s'appuyer. *
+* *
+* Description : Détermine les abscisses de tous les liens en place. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
+{
+ GtkAllocation needed; /* Espace nécessaire et alloué */
+ size_t i; /* Boucle de parcours */
+ vspace_booking_t *booking; /* Réservation à traiter */
+ gint x; /* Position à appliquer */
+ GGraphCluster *container; /* Parent direct à décaler */
+
+ g_graph_cluster_compute_needed_alloc(cluster, &needed);
+
+ for (i = 0; i < manager->left_count; i++)
+ {
+ booking = manager->left[i];
+
+ x = i * LINK_MARGIN;
+
+ booking->pts[0].x = needed.x + x;
+ booking->pts[1].x = needed.x + x;
+
+ }
+
+ if (manager->left_count > 0)
+ {
+ x = manager->left_count * LINK_MARGIN;
+
+ /**
+ * Si la routine est une boucle sans fin,
+ * alors la boucle peut renvoyer vers le premier bloc.
+ */
+ if (cluster->owner != NULL)
+ {
+ container = cluster->owner;
+
+ /**
+ * On recherche le plus haut propritétaire bénéficiant d'une chaîne
+ * de liens directs et droits, histoire de transmettre le décalage
+ * et de garder ces liens bien verticaux.
+ */
+ while (container->owner != NULL)
+ {
+ if (!container->owner->has_straight)
+ break;
+
+ if (container->owner->straight_index != *container->parent_index)
+ break;
+
+ container = container->owner;
+
+ }
+
+ g_graph_cluster_offset_x(container, x);
+
+ }
+
+ }
+
+ for (i = 0; i < manager->right_count; i++)
+ {
+ booking = manager->right[i];
+
+ x = (i + 1) * LINK_MARGIN;
+
+ booking->pts[0].x = x;
+ booking->pts[1].x = x;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = structure à consulter. *
+* cluster = graphique de blocs sur lequel s'appuyer. *
+* *
+* Description : Détermine les ordonnées de tous les liens en place. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
+{
+ GtkAllocation needed; /* Espace nécessaire et alloué */
+ size_t i; /* Boucle de parcours */
+ vspace_booking_t *booking; /* Réservation à traiter */
+
+ g_graph_cluster_compute_needed_alloc(cluster, &needed);
+
+ for (i = 0; i < manager->pending_count; i++)
+ {
+ booking = &manager->pending[i];
+
+ /**
+ * On corrige le raccourci pris sans distinction de type de lien dans
+ * la fonction g_graph_cluster_compute_link_y_positions().
+ */
+
+ booking->from->start[1].y = needed.y + needed.height;
+
+ /* Définition de l'ordonnée des points du lien */
+
+ booking->pts[0].y = booking->from->start[1].y;
+
+ booking->pts[1].y = booking->to->end[0].y;
+
+ }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
/* DESCENDANTS DIRECTS CLASSES PAR RANG */
/* ---------------------------------------------------------------------------------- */
@@ -1141,307 +1442,6 @@ static void set_y_for_graph_rank(const graph_rank_t *grank, gint *base)
/* ---------------------------------------------------------------------------------- */
-/* ENCADREMENTS D'ESPACES VERTICAUX */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = structure à initialiser. *
-* *
-* Description : Initialise les réservations liens verticaux. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void init_vspace_manager(vspace_manager_t *manager)
-{
- manager->pending = NULL;
- manager->pending_count = 0;
-
- manager->left = NULL;
- manager->left_count = 0;
-
- manager->right = NULL;
- manager->right_count = 0;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = structure à vider. *
-* *
-* Description : Termine les réservations liens verticaux. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void exit_vspace_manager(vspace_manager_t *manager)
-{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < manager->pending_count; i++)
- free(manager->pending[i].pts);
-
- if (manager->pending != NULL)
- free(manager->pending);
-
- if (manager->left != NULL)
- free(manager->left);
-
- if (manager->right != NULL)
- free(manager->right);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = structure à compléter. *
-* from = point de départ du lien concerné. *
-* to = point d'arrivée du lien concerné. *
-* pts = points intermédiaires du tracé complet final. *
-* *
-* Description : Inscrit une nouvelle réservation d'espace latéral. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
-{
- vspace_booking_t *new; /* Réservation à constituer */
-
- manager->pending = realloc(manager->pending, ++manager->pending_count * sizeof(vspace_booking_t));
-
- new = &manager->pending[manager->pending_count - 1];
-
- new->from = from;
- new->to = to;
-
- new->pts = pts;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = gestion des espaces latéraux à consulter. *
-* alloc = emplacement idéal pour l'affichage. [OUT] *
-* *
-* Description : Détermine l'emplacement requis pour les espaces latéraux. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, GtkAllocation *alloc)
-{
- gint width; /* Largeur supplémentaire */
-
- /* Extension de la largeur */
-
- width = 0;
-
- width += manager->left_count * LINK_MARGIN;
-
- width += manager->right_count * LINK_MARGIN;
-
- alloc->x -= width / 2;
- alloc->width += width;
-
- /* Extension de la hauteur */
-
- alloc->height += manager->pending_count * VERTICAL_MARGIN;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = gestion d'espaces latéraux à manipuler. *
-* *
-* Description : Réorganise au besoin les liens de boucle entre blocs. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void sort_incoming_links_for_vspace_manager(vspace_manager_t *manager)
-{
- size_t i; /* Boucle de parcours */
- vspace_booking_t *pending; /* Elément traité */
- gint x1; /* Abscisse de départ de lien */
- size_t idx; /* Indice du lien entrant */
- gint x2; /* Abscisse d'arrivée de lien */
-
- for (i = 0; i < manager->pending_count; i++)
- {
- pending = &manager->pending[i];
-
- x1 = g_graph_cluster_compute_leaving_link_position(pending->from->owner, pending->from->index);
-
- idx = g_graph_cluster_find_incoming_link(pending->to->owner, pending->from);
-
- x2 = g_graph_cluster_compute_incoming_link_position(pending->to->owner, idx);
-
- if (x1 < x2)
- {
- manager->left = realloc(manager->left, ++manager->left_count * sizeof(vspace_booking_t *));
- manager->left[manager->left_count - 1] = pending;
- }
- else
- {
- manager->right = realloc(manager->right, ++manager->right_count * sizeof(vspace_booking_t *));
- manager->right[manager->right_count - 1] = pending;
- }
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = structure à consulter. *
-* cluster = graphique de blocs sur lequel s'appuyer. *
-* *
-* Description : Détermine les abscisses de tous les liens en place. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
-{
- GtkAllocation needed; /* Espace nécessaire et alloué */
- size_t i; /* Boucle de parcours */
- vspace_booking_t *booking; /* Réservation à traiter */
- gint x; /* Position à appliquer */
- GGraphCluster *container; /* Parent direct à décaler */
-
- g_graph_cluster_compute_needed_alloc(cluster, &needed);
-
- for (i = 0; i < manager->left_count; i++)
- {
- booking = manager->left[i];
-
- x = i * LINK_MARGIN;
-
- booking->pts[0].x = needed.x + x;
- booking->pts[1].x = needed.x + x;
-
- }
-
- if (manager->left_count > 0)
- {
- x = manager->left_count * LINK_MARGIN;
-
- /**
- * Si la routine est une boucle sans fin,
- * alors la boucle peut renvoyer vers le premier bloc.
- */
- if (cluster->owner != NULL)
- {
- container = cluster->owner;
-
- /**
- * On recherche le plus haut propritétaire bénéficiant d'une chaîne
- * de liens directs et droits, histoire de transmettre le décalage
- * et de garder ces liens bien verticaux.
- */
- while (container->owner != NULL)
- {
- if (!container->owner->has_straight)
- break;
-
- if (container->owner->straight_index != *container->parent_index)
- break;
-
- container = container->owner;
-
- }
-
- g_graph_cluster_offset_x(container, x);
-
- }
-
- }
-
- for (i = 0; i < manager->right_count; i++)
- {
- booking = manager->right[i];
-
- x = (i + 1) * LINK_MARGIN;
-
- booking->pts[0].x = x;
- booking->pts[1].x = x;
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : manager = structure à consulter. *
-* cluster = graphique de blocs sur lequel s'appuyer. *
-* *
-* Description : Détermine les ordonnées de tous les liens en place. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
-{
- GtkAllocation needed; /* Espace nécessaire et alloué */
- size_t i; /* Boucle de parcours */
- vspace_booking_t *booking; /* Réservation à traiter */
-
- g_graph_cluster_compute_needed_alloc(cluster, &needed);
-
- for (i = 0; i < manager->pending_count; i++)
- {
- booking = &manager->pending[i];
-
- /**
- * On corrige le raccourci pris sans distinction de type de lien dans
- * la fonction g_graph_cluster_compute_link_y_positions().
- */
-
- booking->from->start[1].y = needed.y + needed.height;
-
- /* Définition de l'ordonnée des points du lien */
-
- booking->pts[0].y = booking->from->start[1].y;
-
- booking->pts[1].y = booking->to->end[0].y;
-
- }
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
/* DEFINITION D'UN CHEF DE FILE */
/* ---------------------------------------------------------------------------------- */