diff options
Diffstat (limited to 'src/gtkext/graph/nodes/flow.c')
-rw-r--r-- | src/gtkext/graph/nodes/flow.c | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index 1848048..de434ab 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -113,6 +113,10 @@ static void g_flow_node_setup_exit_slots(GFlowNode *); /* Etablit un lien entre deux noeuds graphiques. */ static node_slot_t *g_flow_node_get_slot(const GFlowNode *, bool, GArchInstruction *, size_t); +/* Localise un point d'accroche à un noeud graphique. */ +static gint g_flow_node_get_slot_offset(const GFlowNode *, bool, const node_slot_t *); + + /* Indique le type définit par la GLib pour l'encapsulation d'un bloc d'exécution. */ @@ -488,6 +492,217 @@ void g_flow_node_apply_rank(GFlowNode *node, GGraphRanks *ranks) } +/****************************************************************************** +* * +* Paramètres : node = noeud d'encapsulation à traiter. * +* nodes = ensemble des noeuds en place. * +* * +* Description : Organise le contenu du noeud selon l'axe des abscisses. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_flow_node_organize_x_line(GFlowNode *node, GGraphNode *nodes) +{ + GArchInstruction *last; /* Dernière instr. du noeud */ + GFlowNode *target; /* Bloc visé par le lien */ + node_slot_t *dest_slot; /* Accrochage d'arrivée */ + gint offset; /* Décallage d'une accroche */ + gint ref_pos; /* Position de référence */ + GdkPoint ref; /* Position de référence */ + GFlowNode *target_a; /* Bloc visé par le lien #a */ + GFlowNode *target_b; /* Bloc visé par le lien #b */ + unsigned int rank_a; /* Indice du rang associé #a */ + unsigned int rank_b; /* Indice du rang associé #b */ + GGraphNode *container; /* Conteneur à positionner */ + + g_flow_block_get_boundary(node->block, NULL, &last); + + switch (node->exits_count) + { + case 1: + + if (node->exits[0].type == ILT_LOOP) + break; + + target = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[0].instr)); + +#if 0 + /** + * La recherche ne se faisant que dans le sous-ensemble des blocs voisins, + * on écarte des recherches les cibles se situant dans des blocs virtuels parents. + */ + if (target == NULL) + break; +#endif + + if (g_graph_node_has_x_position(G_GRAPH_NODE(target))) + break; + + dest_slot = g_flow_node_get_slot(target, true, + last, node->exits[0].group_index); + + offset = g_flow_node_get_slot_offset(target, true, dest_slot); + offset = (target->alloc.width / 2) - offset; + + if (G_GRAPH_NODE(target)->pending_x == 0) + + g_graph_node_set_pending_position(G_GRAPH_NODE(target), (gint []) { offset }, NULL); + + break; + + case 2: + + target_a = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[0].instr)); + target_b = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[1].instr)); + +#if 0 + /** + * La recherche ne se faisant que dans le sous-ensemble des blocs voisins, + * on écarte des recherches les cibles se situant dans des blocs virtuels parents. + */ + if (target_a == NULL || target_b == NULL) + break; +#endif + + /* + if (g_graph_node_has_x_position(G_GRAPH_NODE(target_a)) + || g_graph_node_has_x_position(G_GRAPH_NODE(target_b))) + break; + */ + + rank_a = g_flow_node_get_rank(target_a); + rank_b = g_flow_node_get_rank(target_b); + + printf("\nRANKS : a=%d vs b=%d\n", rank_a, rank_b); + + if (rank_a == rank_b) + break; + + /* Alignement d'un bloc lié */ + + if (rank_a > rank_b) + { + + g_graph_node_get_position(G_GRAPH_NODE(node), &ref_pos, NULL); + ref_pos += (node->alloc.width / 2); + //printf("parent = %d mid = %d\n", ref_pos, (node->alloc.width / 2)); + + + ref_pos += g_flow_node_get_slot_offset(node, false, &node->exits[0]); + ref_pos -= (node->alloc.width / 2); + + //printf("ref_pos = %d mid = %d\n", ref_pos, node->alloc.width / 2); + + + dest_slot = g_flow_node_get_slot(target_a, true, + last, node->exits[0].group_index); + + offset = g_flow_node_get_slot_offset(target_a, true, dest_slot); + + //printf("offset = %d mid = %d\n", offset, (target_a->alloc.width / 2)); + + offset = (target_a->alloc.width / 2) - offset; + offset += ref_pos; + + //ref = g_flow_node_get_point_from_slot(node, false, &node->exits[0]); + + + + printf("> offset = %d\n", offset); + + + //offset += (ref.x < 0 ? - ref.x : ref.x); + +#if 1 + + if (!g_graph_node_has_x_position(G_GRAPH_NODE(target_a)) + && G_GRAPH_NODE(target_a)->pending_x == 0) + + g_graph_node_set_pending_position(G_GRAPH_NODE(target_a), + (gint []) { offset }, NULL); + + else printf("pending...\n"); + +#endif + + } + else + { + dest_slot = g_flow_node_get_slot(target_b, true, + last, node->exits[1].group_index); + + offset = g_flow_node_get_slot_offset(target_b, true, dest_slot); + offset = (target_b->alloc.width / 2) - offset; + + ref = g_flow_node_get_point_from_slot(node, false, &node->exits[1]); + //offset += (ref.x < 0 ? - ref.x : ref.x); + + + + if (G_GRAPH_NODE(target_b)->pending_x == 0) + + g_graph_node_set_pending_position(G_GRAPH_NODE(target_b), + (gint []) { offset }, NULL); + + } + + /* Balance du bloc non aligné */ + + if (rank_a > rank_b) + { + container = g_graph_node_find_container_at_same_level(nodes, + G_GRAPH_NODE(node), + G_GRAPH_NODE(target_b)); + + if (container == NULL) break; + + + printf("----\n"); + printf("node = %p (%d)\n", node, g_graph_node_get_rank(G_GRAPH_NODE(node))); + printf("target a = %p\n", target_a); + printf("target b = %p\n", target_b); + printf("container= %p (%d)\n", container, g_graph_node_get_rank(G_GRAPH_NODE(container))); + + printf("(%p) container %p --> %d\n", nodes, container, ref.x + 20); + + printf("has pos ? %d\n", g_graph_node_has_x_position(container)); + + + dest_slot = g_flow_node_get_slot(target_a, true, + last, node->exits[0].group_index); + + offset += g_flow_node_get_slot_offset(target_a, true, dest_slot); + + + offset += 200; + + //if (ref.x < -10000) + // printf(" !!!! REF.X = %d\n", ref.x); + + //g_graph_node_set_position(container, (gint []) { ref.x + 20 }, NULL); + + + printf(">> set offset : %d\n", offset + 50); + printf(">> pending :: %d\n", G_GRAPH_NODE(container)->pending_x); + + g_graph_node_set_pending_position(container, (gint []) { offset + 50 }, NULL); + + } + + + break; + + + } + + + +} + /****************************************************************************** * * @@ -712,6 +927,53 @@ static node_slot_t *g_flow_node_get_slot(const GFlowNode *node, bool entry, GArc * * * Description : Localise un point d'accroche à un noeud graphique. * * * +* Retour : Décallage relatif pour l'accroche fournie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gint g_flow_node_get_slot_offset(const GFlowNode *node, bool entry, const node_slot_t *slot) +{ + gint result; /* Valeur à retourner */ + node_slot_t *slots; /* Accroches à parcourir */ + size_t count; /* Nombre de ces points */ + gint slots_width; /* Largeur des accroches */ + gint slots_left; /* Abscisse de la première */ + size_t index; /* Indice de l'accroche visée */ + + if (entry) + { + slots = node->entries; + count = node->entries_count; + } + else + { + slots = node->exits; + count = node->exits_count; + } + + slots_width = (count - 1) * SPACE_BETWEEN_SLOT; + slots_left = (node->alloc.width - slots_width) / 2; + + index = (slot - slots); + /* BUG_ON(index >= count); */ + + result = slots_left + index * SPACE_BETWEEN_SLOT; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique à consulter. * +* entry = indique le type d'accrochage recherché. * +* slot = accroche dont l'emplacement est à définir. * +* * +* Description : Localise un point d'accroche à un noeud graphique. * +* * * Retour : Emplacement réservé pour l'accroche fournie. * * * * Remarques : - * @@ -744,6 +1006,7 @@ GdkPoint g_flow_node_get_point_from_slot(const GFlowNode *node, bool entry, cons } + slots_width = (count - 1) * SPACE_BETWEEN_SLOT; slots_left = node->alloc.x + (node->alloc.width - slots_width) / 2; @@ -752,6 +1015,17 @@ GdkPoint g_flow_node_get_point_from_slot(const GFlowNode *node, bool entry, cons result.x = slots_left + index * SPACE_BETWEEN_SLOT; + + +#if 0 + slots_width = (count - 1) * SPACE_BETWEEN_SLOT; + slots_left = node->alloc.x + (node->alloc.width - slots_width) / 2; + + index = (slot - slots)/* / sizeof(node_slot_t)*/; + /* BUG_ON(index >= count); */ + + result.x = slots_left + index * SPACE_BETWEEN_SLOT; +#endif return result; } |