diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-03-11 14:48:59 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-03-11 14:48:59 (GMT) |
commit | d53249c8021270a4070181d032da33e129c36e9f (patch) | |
tree | 0891d2cc22fdb034c103aa3806b6695646b30bd6 /src/gtkext | |
parent | bf53af268d38ebb3224886e6d916e6148e78778b (diff) |
Enforced straight link rending in graph views.
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/graph/cluster.c | 144 |
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; } |