From d80df591b6104c98d21e1db5143610fb84e35941 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 26 May 2013 10:49:51 +0000 Subject: Improved the graph rendering. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@347 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 12 ++ src/gtkext/graph/layout.c | 2 +- src/gtkext/graph/node-int.h | 2 + src/gtkext/graph/node.c | 98 ++++++++++++++ src/gtkext/graph/node.h | 8 +- src/gtkext/graph/nodes/flow.c | 274 +++++++++++++++++++++++++++++++++++++++ src/gtkext/graph/nodes/flow.h | 3 + src/gtkext/graph/nodes/virtual.c | 95 +++++++++----- src/gtkext/graph/nodes/virtual.h | 2 +- 9 files changed, 461 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75b2b0c..1b39630 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +13-05-26 Cyrille Bagard + + * src/gtkext/graph/layout.c: + * src/gtkext/graph/node.c: + * src/gtkext/graph/node.h: + * src/gtkext/graph/node-int.h: + * src/gtkext/graph/nodes/flow.c: + * src/gtkext/graph/nodes/flow.h: + * src/gtkext/graph/nodes/virtual.c: + * src/gtkext/graph/nodes/virtual.h: + Improve the graph rendering. + 13-05-05 Cyrille Bagard * src/gtkext/graph/edge.c: diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c index 0a14854..43caf44 100644 --- a/src/gtkext/graph/layout.c +++ b/src/gtkext/graph/layout.c @@ -655,7 +655,7 @@ void g_graph_layout_refresh(GGraphLayout *layout) /* Traitement des positions horizontales */ g_graph_node_set_position(layout->nodes, (gint []) { 0 }, NULL); - g_virtual_node_organize_x_line(G_VIRTUAL_NODE(layout->nodes)); + g_virtual_node_organize_x_line(G_VIRTUAL_NODE(layout->nodes), layout->nodes); for (i = 0; i < layout->edges_count; i++) g_graph_edge_reserve_horizontal_space(layout->edges[i], layout->ranks); diff --git a/src/gtkext/graph/node-int.h b/src/gtkext/graph/node-int.h index 6d1086f..dca4af5 100644 --- a/src/gtkext/graph/node-int.h +++ b/src/gtkext/graph/node-int.h @@ -71,6 +71,8 @@ struct _GGraphNode char name[NODE_NAME_LEN]; /* Adresse sous forme humaine */ GtkAllocation alloc; /* Emplacement du bloc rattaché*/ + gint pending_x; /* Décallage à appliquer #1 */ + gint pending_y; /* Décallage à appliquer #2 */ }; diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c index 7b1d2b3..47531e2 100644 --- a/src/gtkext/graph/node.c +++ b/src/gtkext/graph/node.c @@ -274,6 +274,19 @@ void g_graph_node_reset_position(GGraphNode *node) void g_graph_node_set_position(GGraphNode *node, gint *x, gint *y) { +#if 1 + if (x != NULL && node->pending_x != 0) + { + *x += node->pending_x; + printf(" ((%p)) adding %d => %d\n", node, node->pending_x, *x); + node->pending_x = 0; + } + if (y != NULL && node->pending_y != 0) + { + *y += node->pending_y; + node->pending_y = 0; + } +#endif node->set_pos(node, x, y); } @@ -281,6 +294,51 @@ void g_graph_node_set_position(GGraphNode *node, gint *x, gint *y) /****************************************************************************** * * +* Paramètres : node = noeud graphique à manipuler. * +* x = éventuelle abscisse à intégrer ou NULL. * +* y = éventuelle ordonnée à intégrer ou NULL. * +* * +* Description : Prépare la position du noeud pour l'alignement des liens. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_node_set_pending_position(GGraphNode *node, gint *x, gint *y) +{ + gint cur_x; /* Abscisse courante */ + gint cur_y; /* Ordonnée courante */ + bool update_x; /* Mise à jour des abscisses */ + bool update_y; /* Mise à jour des ordonnées */ + + g_graph_node_get_position(node, &cur_x, &cur_y); + + if (x != NULL) + { + update_x = (cur_x != UNINITIALIZED_NODE_POS); + if (!update_x) node->pending_x += *x; + } + else update_x = false; + + if (y != NULL) + { + update_y = (cur_y != UNINITIALIZED_NODE_POS); + if (!update_y) node->pending_y += *y; + } + else update_y = false; + + if (update_x || update_y) + g_graph_node_set_position(node, + update_x ? cur_x + *x : NULL, + update_y ? cur_x + *y : NULL); + +} + + +/****************************************************************************** +* * * Paramètres : node = noeud graphique à consulter. * * x = éventuelle abscisse à recevoir ou NULL. [OUT] * * y = éventuelle ordonnée à recevoir ou NULL. [OUT] * @@ -367,6 +425,46 @@ GGraphNode *g_graph_node_find_container(GGraphNode *nodes, GGraphNode *target) } +/****************************************************************************** +* * +* Paramètres : nodes = noeud au sommet de la hiérarchie. * +* ref = noeud indiquant le niveau de référence. * +* target = élément à retrouver dans l'ensemble de noeuds. * +* * +* Description : Recherche le noeud contenant un autre noeud à un même niveau.* +* * +* Retour : Noeud trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGraphNode *g_graph_node_find_container_at_same_level(GGraphNode *nodes, GGraphNode *ref, GGraphNode *target) +{ + GGraphNode *result; /* Trouvaille à retourner */ + GGraphNode *level; /* Niveau de référence */ + GGraphNode *container; /* Support de la cible */ + + result = NULL; + + level = g_graph_node_find_container(nodes, ref); + + container = g_graph_node_find_container(nodes, target); + + if (container == level) + result = target; + else + { + if (container == NULL) + result = NULL; + else + result = g_graph_node_find_container_at_same_level(nodes, ref, container); + } + + return result; + +} + diff --git a/src/gtkext/graph/node.h b/src/gtkext/graph/node.h index 53232d9..fa2fa27 100644 --- a/src/gtkext/graph/node.h +++ b/src/gtkext/graph/node.h @@ -89,6 +89,9 @@ void g_graph_node_reset_position(GGraphNode *); /* Altère la position du noeud d'encapsulation. */ void g_graph_node_set_position(GGraphNode *, gint *, gint *); +/* Prépare la position du noeud pour l'alignement des liens. */ +void g_graph_node_set_pending_position(GGraphNode *, gint *, gint *); + /* Fournit la position du noeud d'encapsulation. */ void g_graph_node_get_position(const GGraphNode *, gint *, gint *); @@ -96,7 +99,7 @@ void g_graph_node_get_position(const GGraphNode *, gint *, gint *); ({ \ gint _x; \ g_graph_node_get_position(node, &_x, NULL); \ - _x != UNINITIALIZED_NODE_POS; \ + _x != UNINITIALIZED_NODE_POS/* || node->pending_x != 0*/; \ }) /* Espace constitué, entièrement ou non. */ @@ -108,6 +111,9 @@ bool g_graph_node_visit_nodes(GGraphNode *, graph_node_visitor_cb, void *); /* Recherche le noeud contenant un autre noeud. */ GGraphNode *g_graph_node_find_container(GGraphNode *, GGraphNode *); +/* Recherche le noeud contenant un autre noeud à un même niveau. */ +GGraphNode *g_graph_node_find_container_at_same_level(GGraphNode *, GGraphNode *, GGraphNode *); + /* Inscrit le noeud au rang donné. */ 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); -- cgit v0.11.2-87-g4458