summaryrefslogtreecommitdiff
path: root/src/gtkext/graph/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext/graph/nodes')
-rw-r--r--src/gtkext/graph/nodes/flow.c274
-rw-r--r--src/gtkext/graph/nodes/flow.h3
-rw-r--r--src/gtkext/graph/nodes/virtual.c95
-rw-r--r--src/gtkext/graph/nodes/virtual.h2
4 files changed, 341 insertions, 33 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;
}
diff --git a/src/gtkext/graph/nodes/flow.h b/src/gtkext/graph/nodes/flow.h
index 5a6268e..5c99284 100644
--- a/src/gtkext/graph/nodes/flow.h
+++ b/src/gtkext/graph/nodes/flow.h
@@ -70,6 +70,9 @@ void g_flow_node_apply_rank(GFlowNode *, GGraphRanks *);
/* Etablit les liaison entre un noeud et ses suivants. */
void g_flow_node_link(GFlowNode *, GGraphLayout *, GGraphNode *);
+/* Organise le contenu du noeud selon l'axe des abscisses. */
+void g_flow_node_organize_x_line(GFlowNode *, GGraphNode *);
+
/* Place un noeud sur son support final. */
void g_flow_node_place(const GFlowNode *, GtkGraphView *);
diff --git a/src/gtkext/graph/nodes/virtual.c b/src/gtkext/graph/nodes/virtual.c
index e13dfc8..05a7063 100644
--- a/src/gtkext/graph/nodes/virtual.c
+++ b/src/gtkext/graph/nodes/virtual.c
@@ -129,7 +129,7 @@ static bool g_virtual_node_visit_flow_nodes(GVirtualNode *, graph_node_visitor_c
static GGraphNode *g_virtual_node_find_container(GVirtualNode *, GGraphNode *);
/* Définit les abscisses relatives du contenu d'un noeud. */
-static void g_virtual_node_setup_x_line(GVirtualNode *);
+static void g_virtual_node_setup_x_line(GVirtualNode *, GGraphNode *);
@@ -432,9 +432,46 @@ static void g_virtual_node_reset_position(GVirtualNode *node)
static void g_virtual_node_set_position(GVirtualNode *node, gint *x, gint *y)
{
+ gint old_x; /* Sauvegarde des abscisses */
+ gint old_y; /* Sauvegarde des ordonnées */
+ gint off_x; /* Décallage sur les abscisses */
+ gint off_y; /* Décallage sur les ordonnées */
+ gint pos_x; /* Nouvelle position #1 */
+ gint pos_y; /* Nouvelle position #2 */
+ size_t i; /* Boucle de parcours */
+
+
+ //if (x != NULL) printf("-- setX -- %p -> %d (old=%d)\n", node, *x, node->x);
+
+ old_x = node->x;
+ old_y = node->y;
+
+
+
if (x != NULL) node->x = *x;
if (y != NULL) node->y = *y;
+ off_x = (old_x != UNINITIALIZED_NODE_POS && node->x != UNINITIALIZED_NODE_POS ? node->x - old_x : 0);
+ off_y = (old_y != UNINITIALIZED_NODE_POS ? node->y - old_y : node->y);
+
+ //printf("offx = %d\n", off_x);
+
+
+ for (i = 0; i < node->count; i++)
+ {
+ g_graph_node_get_position(node->children[i], &pos_x, &pos_y);
+
+
+ if (x != NULL) pos_x += off_x;
+
+
+ g_graph_node_set_position(node->children[i], &pos_x, &pos_y);
+
+
+ }
+
+
+
}
@@ -477,7 +514,6 @@ static GtkAllocation g_virtual_node_get_allocation(const GVirtualNode *node)
GtkAllocation result; /* Valeurs à retourner */
gint margins; /* Bordures gauche et droite */
unsigned int last_rank; /* Détection de saut de rangs */
- size_t horiz_count; /* Quantité à l'horizontale */
size_t vert_count; /* Quantité à la verticale */
gint rank_width; /* Largeur d'un rang donné */
gint rank_height; /* Hauteur d'un rang donné */
@@ -503,7 +539,6 @@ static GtkAllocation g_virtual_node_get_allocation(const GVirtualNode *node)
last_rank = -1;
- horiz_count = 0;
vert_count = 0;
rank_width = 0;
@@ -513,41 +548,36 @@ static GtkAllocation g_virtual_node_get_allocation(const GVirtualNode *node)
{
alloc = g_graph_node_get_allocation(node->children[i]);
+ /* Prise en compte de l'étage précédent */
if (last_rank != g_graph_node_get_rank(node->children[i]))
{
last_rank = g_graph_node_get_rank(node->children[i]);
result.width = MAX(result.width, rank_width);
-
- /*
- if (horiz_count > 0)
- result.width = MAX(result.width, rank_width + (horiz_count - 1) * NODE_LEFT_MARGIN);
- */
-
result.height += rank_height;
rank_width = 0;
rank_height = 0;
- horiz_count = 0;
vert_count++;
}
- //rank_width += alloc.width;
- if (rank_width > 0) rank_width += NODE_LEFT_MARGIN;
- rank_width += alloc.width;
- rank_height = MAX(rank_height, alloc.height);
+ /* Mise à jour de l'étage courant */
+
+ if (node->x == UNINITIALIZED_NODE_POS)
+ {
+ rank_width += alloc.width;
+ if (rank_width > 0) rank_width += NODE_LEFT_MARGIN;
+ }
+ else
+ rank_width = MAX(alloc.x + alloc.width - node->x, rank_width);
- horiz_count++;
+ rank_height = MAX(rank_height, alloc.height);
}
result.width = MAX(result.width, rank_width);
- /*
- if (horiz_count > 0)
- result.width = MAX(result.width, rank_width + (horiz_count - 1) * NODE_LEFT_MARGIN);
- */
result.width += margins;
@@ -747,7 +777,8 @@ vspan_slot_t g_virtual_node_reserve_span(GVirtualNode *node, unsigned int r1, un
/******************************************************************************
* *
-* Paramètres : node = noeud d'encapsulation à traiter. *
+* Paramètres : node = noeud d'encapsulation à traiter. *
+* nodes = ensemble des noeuds en place. *
* *
* Description : Organise le contenu du noeud selon l'axe des abscisses. *
* *
@@ -757,13 +788,13 @@ vspan_slot_t g_virtual_node_reserve_span(GVirtualNode *node, unsigned int r1, un
* *
******************************************************************************/
-void g_virtual_node_organize_x_line(GVirtualNode *node)
+void g_virtual_node_organize_x_line(GVirtualNode *node, GGraphNode *nodes)
{
size_t i; /* Boucle de parcours */
gint min; /* Valeur minimale rencontrée */
gint x; /* Position d'un sous-noeud */
- g_virtual_node_setup_x_line(node);
+ g_virtual_node_setup_x_line(node, nodes);
min = 0;
@@ -783,7 +814,8 @@ void g_virtual_node_organize_x_line(GVirtualNode *node)
/******************************************************************************
* *
-* Paramètres : node = noeud d'encapsulation à traiter. *
+* Paramètres : node = noeud d'encapsulation à traiter. *
+* nodes = ensemble des noeuds en place. *
* *
* Description : Définit les abscisses relatives du contenu d'un noeud. *
* *
@@ -793,7 +825,7 @@ void g_virtual_node_organize_x_line(GVirtualNode *node)
* *
******************************************************************************/
-static void g_virtual_node_setup_x_line(GVirtualNode *node)
+static void g_virtual_node_setup_x_line(GVirtualNode *node, GGraphNode *nodes)
{
unsigned int rank_0; /* Rang du premier sous-noeud */
unsigned int rank_1; /* Rang du second sous-noeud */
@@ -852,15 +884,10 @@ static void g_virtual_node_setup_x_line(GVirtualNode *node)
/* Définitions éventuelles des emplacements liés */
if (G_IS_FLOW_NODE(child))
- {
-
+ g_flow_node_organize_x_line(G_FLOW_NODE(child), nodes);
- ;
-
-
- }
else if (G_IS_VIRTUAL_NODE(child))
- g_virtual_node_organize_x_line(G_VIRTUAL_NODE(child));
+ g_virtual_node_organize_x_line(G_VIRTUAL_NODE(child), nodes);
/*else BUG_ON(1); */
@@ -904,7 +931,11 @@ void g_virtual_node_offset_x_line(GVirtualNode *node, gint xoffset)
g_graph_node_get_position(child, &x, NULL);
- x += xoffset + padding;
+ printf("+++ [%p-%d/%p] offsetting %d(%d) + (%d / %d)\n",
+ node, g_graph_node_get_rank(G_GRAPH_NODE(node)), child,
+ node->x, G_GRAPH_NODE(node)->pending_x, x, x + xoffset + padding);
+
+ x += node->x + xoffset + padding;
g_graph_node_set_position(child, &x, NULL);
}
diff --git a/src/gtkext/graph/nodes/virtual.h b/src/gtkext/graph/nodes/virtual.h
index 20106b6..a7a96d7 100644
--- a/src/gtkext/graph/nodes/virtual.h
+++ b/src/gtkext/graph/nodes/virtual.h
@@ -69,7 +69,7 @@ GGraphNode *g_virtual_node_get_child(const GVirtualNode *, size_t);
vspan_slot_t g_virtual_node_reserve_span(GVirtualNode *, unsigned int, unsigned int, bool);
/* Organise le contenu du noeud selon l'axe des abscisses. */
-void g_virtual_node_organize_x_line(GVirtualNode *);
+void g_virtual_node_organize_x_line(GVirtualNode *, GGraphNode *);
/* Procède à un décallage du contenu sur l'axe des abscisses. */
void g_virtual_node_offset_x_line(GVirtualNode *, gint);