summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/graph/cluster.c144
1 files changed, 103 insertions, 41 deletions
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 48ad9ca..e425d67 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -728,23 +728,25 @@ void g_graph_cluster_setup_links(GGraphCluster *cluster)
if (cluster->ba_count == 1)
{
- /**
- * Attention : les boucles aussi ont un seul lien sortant !
- * Le filtrage est cependant réalisé au début de l'itération.
- */
+ if (incoming->type == ILT_EXEC_FLOW)
+ leaving->forced_straight = true;
- container = leaving->owner->container;
+ else if (incoming->type == ILT_JUMP)
+ {
+ for (k = 0; k < incoming->owner->ta_count; k++)
+ if (incoming->owner->top_anchors[k] != incoming
+ && incoming->owner->top_anchors[k]->type != ILT_LOOP)
+ {
+ break;
+ }
- for (k = 0; k < container->ranks_count; k++)
- if (has_graph_rank_cluster(&container->ranks[k], incoming->owner))
- break;
+ leaving->forced_straight = (k == incoming->owner->ta_count);
- if (k < container->ranks_count)
- {
- leaving->forced_straight = true;
- leaving->straight_level = target_level;
}
+ if (leaving->forced_straight)
+ leaving->straight_level = target_level;
+
}
}
@@ -772,17 +774,100 @@ void g_graph_cluster_setup_links(GGraphCluster *cluster)
void g_graph_cluster_dispatch_x(GGraphCluster *cluster)
{
size_t i; /* Boucle de parcours #1 */
+ size_t straight_idx; /* Lien vertical le plus adapté*/
+ size_t forced_idx; /* Lien vertical forcé */
+ bool drop_forced; /* Invalidation de cet indice */
+ leaving_link_t *leaving; /* Départ de lien */
+ GCodeBlock *block[2]; /* Accès rapide aux blocs */
+ gint start; /* Position initiale de départ */
+ gint end; /* Position initiale d'arrivée */
leaving_link_t *straight_leaving; /* Lien à présenter vertical */
size_t straight_index; /* Indice du lien vertical */
gint straight_start; /* Position initiale de départ */
size_t straight_level; /* Rang atteint en ligne droite*/
const graph_rank_t *rank; /* Accès confortable au rang */
- gint start; /* Position initiale modifiable*/
size_t j; /* Boucle de parcours #2 */
GGraphCluster *target; /* Unique sous-bloc visé */
- size_t idx; /* Indice du lien entrant */
- gint end; /* Position initiale d'arrivée */
- leaving_link_t *leaving; /* Départ de lien */
+
+ /**
+ * Traitement amont : alignement sur une éventuelle origine.
+ */
+
+ straight_idx = cluster->ta_count;
+ forced_idx = cluster->ta_count;
+
+ drop_forced = false;
+
+ /* Recherche des candidats potentiels */
+
+ for (i = 0; i < cluster->ta_count; i++)
+ {
+ leaving = cluster->top_anchors[i]->other;
+
+ if (leaving->straight)
+ {
+ if (straight_idx < cluster->ta_count)
+ {
+ block[0] = leaving->owner->block;
+ block[1] = cluster->top_anchors[straight_idx]->other->owner->block;
+
+ if (g_code_block_get_rank(block[0]) <= g_code_block_get_rank(block[1]))
+ straight_idx = i;
+
+ }
+
+ else
+ straight_idx = i;
+
+ }
+
+ if (leaving->forced_straight)
+ {
+ /**
+ * Il ne peut y avoir qu'un lien forcé pour une entrée de bloc donnée !
+ */
+ assert(forced_idx == cluster->ta_count);
+
+ forced_idx = i;
+
+ }
+
+ if (cluster->top_anchors[i]->type != ILT_LOOP)
+ drop_forced |= (!leaving->straight && !leaving->forced_straight && !leaving->cluster_exit);
+
+ }
+
+ /* Recalage en fonction d'une éventuelle conduite forcée */
+
+ if (drop_forced)
+ forced_idx = cluster->ta_count;
+
+ if (straight_idx < cluster->ta_count || forced_idx < cluster->ta_count)
+ {
+ if (forced_idx < cluster->ta_count)
+ {
+ leaving = cluster->top_anchors[forced_idx]->other;
+
+ end = g_graph_cluster_compute_incoming_link_position(cluster, forced_idx);
+
+ }
+ else
+ {
+ leaving = cluster->top_anchors[straight_idx]->other;
+
+ end = g_graph_cluster_compute_incoming_link_position(cluster, straight_idx);
+
+ }
+
+ start = g_graph_cluster_compute_leaving_link_position(leaving->owner, leaving->index);
+
+ g_graph_cluster_offset_x(cluster, start - end);
+
+ }
+
+ /**
+ * Traitement aval : alignement selon une éventuelle bordure verticale.
+ */
/* Recherche d'une limite verticale */
@@ -801,9 +886,7 @@ void g_graph_cluster_dispatch_x(GGraphCluster *cluster)
}
- /**
- * Il est désormais temps de placer tous les blocs de code inférieurs.
- */
+ /* Il est désormais temps de placer tous les blocs de code inférieurs. */
for (i = 0; i < cluster->ranks_count; i++)
{
@@ -842,27 +925,6 @@ void g_graph_cluster_dispatch_x(GGraphCluster *cluster)
{
dispatch_x_graph_rank(rank);
- if (straight_leaving->straight || straight_leaving->forced_straight)
- {
- /**
- * Si le bloc pointé en direct a plus d'un lien en entrée (comme
- * dans le cas d'un bloc qui assure un début de boucle par exemple),
- * le lien direct n'est pas centré sur le milieu de ce bloc pointé.
- *
- * On corrige ici le léger décalage.
- */
- assert(rank->count == 1);
-
- target = rank->clusters[0];
-
- idx = g_graph_cluster_find_incoming_link(target, straight_leaving);
-
- end = g_graph_cluster_compute_incoming_link_position(target, idx);
-
- g_graph_cluster_offset_x(target, straight_start - end);
-
- }
-
straight_leaving = NULL;
goto look_for_forced;
@@ -2056,7 +2118,7 @@ static void g_graph_cluster_compute_link_x_positions(GGraphCluster *cluster)
{
pt = &cluster->top_anchors[i]->end[1];
- pt->x = mid_x + LINK_MARGIN / 2 + (half - i) * LINK_MARGIN;
+ pt->x = mid_x + LINK_MARGIN / 2 + (i - half) * LINK_MARGIN;
}