summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/nodes/flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/graph/nodes/flow.c')
-rw-r--r--src/gtkext/graph/nodes/flow.c274
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;
}