summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/cluster.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-02-23 00:55:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-02-23 00:55:50 (GMT)
commit427f80181b1d839bf97d9a7caec88f81bf961e25 (patch)
tree9059f556656ed14601c25064811a7674e30399a7 /src/gtkext/graph/cluster.c
parentd6bf56e4a75be0fe0946189a42dd7baecb399903 (diff)
Limited the length of some loop links in the graph view.
Diffstat (limited to 'src/gtkext/graph/cluster.c')
-rw-r--r--src/gtkext/graph/cluster.c216
1 files changed, 163 insertions, 53 deletions
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 51d73c7..4f39b28 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -108,6 +108,8 @@ typedef struct _vspace_booking_t
GdkPoint *pts; /* Coordonnées des points */
+ bool external; /* Lien vers un cluster parent */
+
} vspace_booking_t;
/* Réservations d'espaces latéraux */
@@ -132,10 +134,10 @@ static void init_vspace_manager(vspace_manager_t *);
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 *);
+static void extend_vspace_manager(vspace_manager_t *, leaving_link_t *, incoming_link_t *, GdkPoint *, bool);
/* Détermine l'emplacement requis pour les espaces latéraux. */
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, GtkAllocation *);
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, bool, GtkAllocation *);
/* Réorganise au besoin les liens de boucle entre blocs. */
static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
@@ -144,7 +146,7 @@ static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
static void offset_x_vspace_manager(vspace_manager_t *, gint);
/* Détermine les abscisses de tous les liens en place. */
-static gint compute_loop_link_x_with_vspace_manager(const vspace_manager_t *, const GtkAllocation *);
+static gint compute_loop_link_x_with_vspace_manager(const vspace_manager_t *, const GtkAllocation *, bool);
/* Détermine les ordonnées de tous les liens en place. */
static void compute_loop_link_y_with_vspace_manager(const vspace_manager_t *, const GtkAllocation *);
@@ -211,8 +213,11 @@ static int cmp_graph_rank(const graph_rank_t *, const graph_rank_t *);
/* Etend un ensemble de blocs de même rang. */
static void extend_graph_rank(graph_rank_t *, GGraphCluster *);
+/* Détermine si un groupe de blocs contient un bloc particulier. */
+static bool has_graph_rank_cluster(const graph_rank_t *, GGraphCluster *);
+
/* Inscrit à l'endroit idéal une réservation d'espace latéral. */
-static bool extend_graph_rank_vspace_manager(graph_rank_t *, leaving_link_t *, incoming_link_t *, GdkPoint *);
+static bool extend_graph_rank_vspace_manager(graph_rank_t *, leaving_link_t *, incoming_link_t *, GdkPoint *, bool);
/* Détermine l'emplacement requis d'un ensemble de blocs. */
static void compute_graph_rank_needed_alloc(const graph_rank_t *, bool, GtkAllocation *);
@@ -275,7 +280,7 @@ struct _GGraphCluster
graph_rank_t *ranks; /* Répartition verticale */
size_t ranks_count; /* Nombre de divisions */
- vspace_manager_t vspaces; /* Gestion des liens latéraux */
+ vspace_manager_t self; /* Gestion d'un retour direct */
};
@@ -675,10 +680,11 @@ static void exit_vspace_manager(vspace_manager_t *manager)
/******************************************************************************
* *
-* 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. *
+* 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. *
+* external = précise une sortie du cadre du cluster premier. *
* *
* Description : Inscrit une nouvelle réservation d'espace latéral. *
* *
@@ -688,7 +694,7 @@ static void exit_vspace_manager(vspace_manager_t *manager)
* *
******************************************************************************/
-static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
+static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts, bool external)
{
vspace_booking_t *new; /* Réservation à constituer */
@@ -701,13 +707,16 @@ static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *fro
new->pts = pts;
+ new->external = external;
+
}
/******************************************************************************
* *
-* Paramètres : manager = gestion des espaces latéraux à consulter. *
-* alloc = emplacement idéal pour l'affichage. [OUT] *
+* Paramètres : manager = gestion des espaces latéraux à consulter. *
+* external = précise une sortie du cadre du cluster premier. *
+* alloc = emplacement idéal pour l'affichage. [OUT] *
* *
* Description : Détermine l'emplacement requis pour les espaces latéraux. *
* *
@@ -717,25 +726,42 @@ static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *fro
* *
******************************************************************************/
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, GtkAllocation *alloc)
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, bool external, GtkAllocation *alloc)
{
gint width; /* Largeur supplémentaire */
-
- /* Extension de la largeur */
+ size_t count; /* Nombre de liens retenus */
+ size_t i; /* Boucle de parcours */
width = 0;
- width += manager->left_count * LINK_MARGIN;
+ /* Extension de la largeur, à gauche */
+
+ count = 0;
+
+ for (i = 0; i < manager->left_count; i++)
+ if (manager->left[i]->external == external)
+ count++;
+
+ width += count * LINK_MARGIN;
alloc->x -= width;
- width += manager->right_count * LINK_MARGIN;
+ /* Extension de la largeur, à droite */
+
+ count = 0;
+
+ for (i = 0; i < manager->right_count; i++)
+ if (manager->right[i]->external == external)
+ count++;
+
+ width += count * LINK_MARGIN;
alloc->width += width;
/* Extension de la hauteur */
- alloc->height += manager->pending_count * VERTICAL_MARGIN;
+ if (!external)
+ alloc->height += manager->pending_count * VERTICAL_MARGIN;
}
@@ -836,8 +862,9 @@ static void offset_x_vspace_manager(vspace_manager_t *manager, gint offset)
/******************************************************************************
* *
-* Paramètres : manager = structure à consulter. *
-* needed = espace nécessaire et alloué pour les blocs. *
+* Paramètres : manager = structure à consulter. *
+* needed = espace nécessaire et alloué pour les blocs. *
+* external = précise une sortie du cadre du cluster premier. *
* *
* Description : Détermine les abscisses de tous les liens en place. *
* *
@@ -847,37 +874,42 @@ static void offset_x_vspace_manager(vspace_manager_t *manager, gint offset)
* *
******************************************************************************/
-static gint compute_loop_link_x_with_vspace_manager(const vspace_manager_t *manager, const GtkAllocation *needed)
+static gint compute_loop_link_x_with_vspace_manager(const vspace_manager_t *manager, const GtkAllocation *needed, bool external)
{
gint result; /* Eventuelle marge à renvoyer */
+ size_t count; /* Quantité de liens traités */
size_t i; /* Boucle de parcours */
vspace_booking_t *booking; /* Réservation à traiter */
gint x; /* Position à appliquer */
+ count = 0;
+
for (i = 0; i < manager->left_count; i++)
{
booking = manager->left[i];
- x = (i + 1) * LINK_MARGIN;
+ x = ++count * LINK_MARGIN;
booking->pts[0].x = needed->x - x;
booking->pts[1].x = needed->x - x;
}
+ result = count * LINK_MARGIN;
+
+ count = 0;
+
for (i = 0; i < manager->right_count; i++)
{
booking = manager->right[i];
- x = (i + 1) * LINK_MARGIN;
+ x = ++count * LINK_MARGIN;
booking->pts[0].x = needed->x + needed->width + x;
booking->pts[1].x = needed->x + needed->width + x;
}
- result = manager->left_count * LINK_MARGIN;
-
return result;
}
@@ -1199,20 +1231,18 @@ static void extend_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
/******************************************************************************
* *
-* Paramètres : grank = ensemble de descendants d'un même rang. *
-* from = point de départ du lien concerné. *
-* to = point d'arrivée du lien concerné. *
-* pts = points intermédiaires du tracé complet final. *
+* Paramètres : grank = structure à compléter. *
+* cluster = chef de file d'un ensemble de blocs. *
* *
-* Description : Inscrit à l'endroit idéal une réservation d'espace latéral. *
+* Description : Détermine si un groupe de blocs contient un bloc particulier.*
* *
-* Retour : true si la demande a bien été traitée. *
+* Retour : true si le chef est bien contenu, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool extend_graph_rank_vspace_manager(graph_rank_t *grank, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
+static bool has_graph_rank_cluster(const graph_rank_t *grank, GGraphCluster *cluster)
{
bool result; /* Bilan à renvoyer */
size_t i; /* Boucle de parcours */
@@ -1220,10 +1250,37 @@ static bool extend_graph_rank_vspace_manager(graph_rank_t *grank, leaving_link_t
result = false;
for (i = 0; i < grank->count && !result; i++)
- result = (grank->clusters[i] == from->owner);
+ result = (grank->clusters[i] == cluster);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : grank = ensemble de descendants d'un même rang. *
+* from = point de départ du lien concerné. *
+* to = point d'arrivée du lien concerné. *
+* pts = points intermédiaires du tracé complet final. *
+* external = précise une sortie du cadre du cluster premier. *
+* *
+* Description : Inscrit à l'endroit idéal une réservation d'espace latéral. *
+* *
+* Retour : true si la demande a bien été traitée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool extend_graph_rank_vspace_manager(graph_rank_t *grank, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts, bool external)
+{
+ bool result; /* Bilan à renvoyer */
+
+ result = has_graph_rank_cluster(grank, from->owner);
if (result)
- extend_vspace_manager(&grank->vspaces, from, to, pts);
+ extend_vspace_manager(&grank->vspaces, from, to, pts, external);
return result;
@@ -1307,7 +1364,7 @@ static void compute_graph_rank_needed_alloc(const graph_rank_t *grank, bool last
}
- compute_vspace_manager_needed_alloc(&grank->vspaces, alloc);
+ compute_vspace_manager_needed_alloc(&grank->vspaces, false, alloc);
}
@@ -1459,7 +1516,7 @@ static void offset_x_graph_rank(graph_rank_t *grank, gint offset)
/******************************************************************************
* *
* Paramètres : grank = ensemble de blocs de même rang à actualiser. *
-* needed = espace nécessaire et alloué pour les blocs. *
+* needed = espace nécessaire et alloué pour les blocs. *
* *
* Description : Détermine les abscisses des liens de boucle en place. *
* *
@@ -1477,7 +1534,7 @@ static gint compute_loop_link_x_positions_with_graph_rank(const graph_rank_t *gr
for (i = 0; i < grank->count; i++)
g_graph_cluster_compute_loop_link_x_positions(grank->clusters[i]);
- result = compute_loop_link_x_with_vspace_manager(&grank->vspaces, needed);
+ result = compute_loop_link_x_with_vspace_manager(&grank->vspaces, needed, false);
return result;
@@ -1619,7 +1676,7 @@ static void g_graph_cluster_class_init(GGraphClusterClass *klass)
static void g_graph_cluster_init(GGraphCluster *cluster)
{
- init_vspace_manager(&cluster->vspaces);
+ init_vspace_manager(&cluster->self);
}
@@ -1680,7 +1737,7 @@ static void g_graph_cluster_finalize(GGraphCluster *cluster)
if (cluster->ranks != NULL)
free(cluster->ranks);
- exit_vspace_manager(&cluster->vspaces);
+ exit_vspace_manager(&cluster->self);
G_OBJECT_CLASS(g_graph_cluster_parent_class)->finalize(G_OBJECT(cluster));
@@ -1867,17 +1924,28 @@ static void g_graph_cluster_setup_link_for_target(GGraphCluster *source, GGraphC
static void g_graph_cluster_extend_vspace_manager(GGraphCluster *target, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
{
bool done; /* Bilan des traitements */
+ GGraphCluster *container; /* Arrivée de boucle extérieure*/
size_t i; /* Boucle de parcours */
assert(target == to->owner);
done = false;
- for (i = 0; i < target->ranks_count && !done; i++)
- done = extend_graph_rank_vspace_manager(&target->ranks[i], from, to, pts);
+ if (from->owner == target)
+ extend_vspace_manager(&target->self, from, to, pts, false);
+
+ else
+ {
+ for (i = 0; i < target->ranks_count && !done; i++)
+ done = extend_graph_rank_vspace_manager(&target->ranks[i], from, to, pts, false);
+
+ container = from->owner->owner;
+ assert(container != NULL);
- if (!done)
- extend_vspace_manager(&target->vspaces, from, to, pts);
+ for (i = 0; i < container->ranks_count && !done; i++)
+ done = extend_graph_rank_vspace_manager(&container->ranks[i], from, to, pts, true);
+
+ }
}
@@ -2193,7 +2261,7 @@ static void g_graph_cluster_sort_incoming_links(GGraphCluster *cluster)
for (i = 0; i < cluster->ranks_count; i++)
sort_graph_rank_incoming_links(&cluster->ranks[i]);
- sort_incoming_links_for_vspace_manager(&cluster->vspaces);
+ sort_incoming_links_for_vspace_manager(&cluster->self);
}
@@ -2248,7 +2316,7 @@ static void g_graph_cluster_offset_x(GGraphCluster *cluster, gint offset)
for (i = 0; i < cluster->ranks_count; i++)
offset_x_graph_rank(&cluster->ranks[i], offset);
- offset_x_vspace_manager(&cluster->vspaces, offset);
+ offset_x_vspace_manager(&cluster->self, offset);
}
@@ -2295,14 +2363,34 @@ static void g_graph_cluster_set_y(GGraphCluster *cluster, gint base)
void g_graph_cluster_compute_needed_alloc(const GGraphCluster *cluster, GtkAllocation *alloc)
{
- size_t i; /* Boucle de parcours */
+ size_t i; /* Boucle de parcours #1 */
+ GGraphCluster *start; /* Départ de boucle extérieure */
+ GGraphCluster *container; /* Arrivée de boucle extérieure*/
+ size_t k; /* Boucle de parcours #2 */
*alloc = cluster->alloc;
for (i = 0; i < cluster->ranks_count; i++)
compute_graph_rank_needed_alloc(&cluster->ranks[i], (i + 1) == cluster->ranks_count, alloc);
- compute_vspace_manager_needed_alloc(&cluster->vspaces, alloc);
+ for (i = 0; i < cluster->ta_count; i++)
+ if (cluster->top_anchors[i]->type == ILT_LOOP)
+ {
+ start = cluster->top_anchors[i]->other->owner;
+
+ container = start->owner;
+ assert(container != NULL);
+
+ for (k = 0; k < container->ranks_count; k++)
+ if (has_graph_rank_cluster(&container->ranks[k], start))
+ {
+ compute_vspace_manager_needed_alloc(&container->ranks[k].vspaces, true, alloc);
+ break;
+ }
+
+ assert(k < container->ranks_count);
+
+ }
}
@@ -2549,7 +2637,10 @@ static void g_graph_cluster_compute_loop_link_x_positions(GGraphCluster *cluster
{
GtkAllocation alloc; /* Emplacement à faire évoluer */
gint margin; /* Marge à gauche éventuelle */
- size_t i; /* Boucle de parcours */
+ size_t i; /* Boucle de parcours #1 */
+ GGraphCluster *start; /* Départ de boucle extérieure */
+ GGraphCluster *container; /* Arrivée de boucle extérieure*/
+ size_t k; /* Boucle de parcours #2 */
/* Propagation des déterminations */
@@ -2565,11 +2656,32 @@ static void g_graph_cluster_compute_loop_link_x_positions(GGraphCluster *cluster
}
- /* Liens de boucle */
+ /* Liens de boucle (#1) */
g_graph_cluster_compute_needed_alloc(cluster, &alloc);
- margin = compute_loop_link_x_with_vspace_manager(&cluster->vspaces, &alloc);
+ margin = compute_loop_link_x_with_vspace_manager(&cluster->self, &alloc, false);
+
+ /* Liens de boucle (#2) */
+
+ for (i = 0; i < cluster->ta_count; i++)
+ if (cluster->top_anchors[i]->type == ILT_LOOP)
+ {
+ start = cluster->top_anchors[i]->other->owner;
+
+ container = start->owner;
+ assert(container != NULL);
+
+ for (k = 0; k < container->ranks_count; k++)
+ if (has_graph_rank_cluster(&container->ranks[k], start))
+ {
+ margin += compute_loop_link_x_with_vspace_manager(&container->ranks[k].vspaces, &alloc, true);
+ break;
+ }
+
+ assert(k < container->ranks_count);
+
+ }
g_graph_cluster_insert_left_margin(cluster, margin);
@@ -2813,9 +2925,7 @@ static void g_graph_cluster_compute_link_y_positions(GGraphCluster *cluster)
/* Définition des liens de boucle */
- g_graph_cluster_compute_needed_alloc(cluster, &alloc);
-
- compute_loop_link_y_with_vspace_manager(&cluster->vspaces, &alloc);
+ compute_loop_link_y_with_vspace_manager(&cluster->self, &cluster->alloc);
}