From 4605b4ac4a04bb11bdf91d77e248656702774bde Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 12 May 2015 18:55:55 +0000 Subject: Ensured parent nodes are centered on their children when expected. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@534 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 16 ++++++++++++++++ src/gtkext/graph/layout.c | 4 ++-- src/gtkext/graph/node-int.h | 7 +------ src/gtkext/graph/node.c | 24 ++++++++++++------------ src/gtkext/graph/node.h | 28 +++++++++++++++++++++------- src/gtkext/graph/nodes/flow.c | 28 +++++++++++++++++++++++----- src/gtkext/graph/nodes/virtual.c | 34 ++++++++++++++++++++++++++++++++++ 7 files changed, 109 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22cd68e..71a2009 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +15-05-12 Cyrille Bagard + + * src/gtkext/graph/layout.c: + Fix compilation warnings. + + * src/gtkext/graph/node.c: + * src/gtkext/graph/node.h: + Introduce a new kink of pending position. + + * src/gtkext/graph/node-int.h: + Clean and update the code. + + * src/gtkext/graph/nodes/flow.c: + * src/gtkext/graph/nodes/virtual.c: + Ensure parent nodes are centered on their children when expected. + 15-05-11 Cyrille Bagard * configure.ac; diff --git a/src/gtkext/graph/layout.c b/src/gtkext/graph/layout.c index 1084578..13f6270 100644 --- a/src/gtkext/graph/layout.c +++ b/src/gtkext/graph/layout.c @@ -248,7 +248,7 @@ GGraphLayout *g_graph_layout_new(GInstrBlock *blocks, GtkBufferView **views, siz for (i = 0; i < *depth; i++) printf(" "); - g_graph_node_get_pending_position(node, &pending_flag, (pending_position []) { { 0 } }); + g_graph_node_get_pending_position(node, &pending_flag, NULL); flags = flags_list[pending_flag]; alloc = g_graph_node_get_allocation(node); @@ -261,7 +261,7 @@ GGraphLayout *g_graph_layout_new(GInstrBlock *blocks, GtkBufferView **views, siz { printf(" - rank = %u -", g_graph_node_get_rank(node)); - g_flow_block_get_boundary(g_flow_node_get_block(node), &first, &last); + g_flow_block_get_boundary(g_flow_node_get_block(G_FLOW_NODE(node)), &first, &last); printf(" - 0x%08x <-> 0x%08x", first->range.addr.virtual, last->range.addr.virtual); } diff --git a/src/gtkext/graph/node-int.h b/src/gtkext/graph/node-int.h index 2572fce..c052e0d 100644 --- a/src/gtkext/graph/node-int.h +++ b/src/gtkext/graph/node-int.h @@ -57,13 +57,8 @@ struct _GGraphNode GObject parent; /* A laisser en premier */ GtkAllocation alloc; /* Emplacement du bloc rattaché*/ - pending_position pending_pos; /* Indication sur la position */ PendingPositionFlags pending_flag; /* Cible le champ valide */ - GGraphNode *pending_rel; /* Eventuelle ref. relative */ - - bool direct_x; /* Position strictement vert. */ - gint pending_left_margin; /* Limite à ne pas dépasser #1 */ - gint pending_right_margin; /* Limite à ne pas dépasser #2 */ + pending_position pending_pos; /* Indication sur la position */ }; diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c index 0210aa3..08dd970 100644 --- a/src/gtkext/graph/node.c +++ b/src/gtkext/graph/node.c @@ -232,22 +232,22 @@ void g_graph_node_apply_position(GGraphNode *node) switch (node->pending_flag) { case PPF_DIRECT_X: - assert(g_graph_node_has_x_position(node->pending_rel)); - g_graph_node_get_position(node->pending_rel, &x_pos, NULL); + assert(g_graph_node_has_x_position(node->pending_pos.relative_ref)); + g_graph_node_get_position(node->pending_pos.relative_ref, &x_pos, NULL); x_pos += node->pending_pos.direct_x; g_graph_node_set_x_position(node, x_pos); break; case PPF_LEFT_MARGIN: - assert(g_graph_node_has_x_position(node->pending_rel)); - g_graph_node_get_position(node->pending_rel, &x_pos, NULL); + assert(g_graph_node_has_x_position(node->pending_pos.relative_ref)); + g_graph_node_get_position(node->pending_pos.relative_ref, &x_pos, NULL); x_pos += EDGE_SLOT_HORIZ_MARGIN + node->pending_pos.left_margin; g_graph_node_set_x_position(node, x_pos); break; case PPF_RIGHT_MARGIN: - assert(g_graph_node_has_x_position(node->pending_rel)); - g_graph_node_get_position(node->pending_rel, &x_pos, NULL); + assert(g_graph_node_has_x_position(node->pending_pos.relative_ref)); + g_graph_node_get_position(node->pending_pos.relative_ref, &x_pos, NULL); x_pos += node->pending_pos.right_margin; x_pos -= (EDGE_SLOT_HORIZ_MARGIN + node->alloc.width); g_graph_node_set_x_position(node, x_pos); @@ -304,7 +304,6 @@ void g_graph_node_set_x_position(GGraphNode *node, gint x) * Paramètres : node = noeud graphique à manipuler. * * flag = nature de l'indication à intégrer. * * pos = argument supplémentaire à venir chercher. * -* rel = éventuelle référence pour une relation relative. * * * * Description : Prépare la position du noeud pour l'alignement des liens. * * * @@ -314,14 +313,13 @@ void g_graph_node_set_x_position(GGraphNode *node, gint x) * * ******************************************************************************/ -void g_graph_node_set_pending_position(GGraphNode *node, PendingPositionFlags flag, pending_position pos, GGraphNode *rel) +void g_graph_node_set_pending_position(GGraphNode *node, PendingPositionFlags flag, pending_position pos) { - if (node->pending_flag != PPF_NONE) + if (node->pending_flag != PPF_NONE && node->pending_flag != PPF_MIDDLE_OF) return; - node->pending_pos = pos; node->pending_flag = flag; - node->pending_rel = rel; + node->pending_pos = pos; } @@ -342,9 +340,11 @@ void g_graph_node_set_pending_position(GGraphNode *node, PendingPositionFlags fl void g_graph_node_get_pending_position(GGraphNode *node, PendingPositionFlags *flag, pending_position *pos) { - *pos = node->pending_pos; *flag = node->pending_flag; + if (pos != NULL) + *pos = node->pending_pos; + } diff --git a/src/gtkext/graph/node.h b/src/gtkext/graph/node.h index 502b366..6d3589a 100644 --- a/src/gtkext/graph/node.h +++ b/src/gtkext/graph/node.h @@ -55,11 +55,24 @@ typedef struct _GGraphNodeClass GGraphNodeClass; /* Indications sur l'abscisse idéale à adopter */ typedef union _pending_position { - gint direct_x; /* Position strictement vert. */ - gint left_margin; /* Limite à ne pas dépasser #1 */ - gint right_margin; /* Limite à ne pas dépasser #2 */ - GGraphNode *left_node; /* Noeud de référence à droite */ - GGraphNode *right_node; /* Noeud de référence à gauche */ + /* PPF_DIRECT_X, PPF_LEFT_MARGIN, PPF_RIGHT_MARGIN */ + struct + { + union + { + gint direct_x; /* Position strictement vert. */ + gint left_margin; /* Limite à ne pas dépasser #1 */ + gint right_margin; /* Limite à ne pas dépasser #2 */ + }; + GGraphNode *relative_ref; /* Eventuelle ref. relative */ + }; + + /* PPF_LEFT_NODE, PPF_RIGHT_NODE, PPF_MIDDLE_OF */ + struct + { + GGraphNode *left_node; /* Noeud de référence à droite */ + GGraphNode *right_node; /* Noeud de référence à gauche */ + }; } pending_position; @@ -71,7 +84,8 @@ typedef enum _PendingPositionFlags PPF_LEFT_MARGIN, /* Limite à ne pas dépasser #1 */ PPF_RIGHT_MARGIN, /* Limite à ne pas dépasser #2 */ PPF_LEFT_NODE, /* Noeud de référence à droite */ - PPF_RIGHT_NODE /* Noeud de référence à gauche */ + PPF_RIGHT_NODE, /* Noeud de référence à gauche */ + PPF_MIDDLE_OF /* Centré entre deux noeuds */ } PendingPositionFlags; @@ -107,7 +121,7 @@ void g_graph_node_apply_position(GGraphNode *); void g_graph_node_set_x_position(GGraphNode *, gint); /* Prépare la position du noeud pour l'alignement des liens. */ -void g_graph_node_set_pending_position(GGraphNode *, PendingPositionFlags, pending_position, GGraphNode *); +void g_graph_node_set_pending_position(GGraphNode *, PendingPositionFlags, pending_position); /* Indique la position du noeud pour l'alignement des liens. */ void g_graph_node_get_pending_position(GGraphNode *, PendingPositionFlags *, pending_position *); diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index ca5dceb..2f822bd 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -351,6 +351,8 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) pos.direct_x -= (G_GRAPH_NODE(target)->alloc.width - G_GRAPH_NODE(node)->alloc.width) / 2; + pos.relative_ref = base; + size_t count_and_skip_loop(GFlowNode *n) { size_t counter; @@ -364,7 +366,7 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) } if (count_and_skip_loop(target) == 1) - g_graph_node_set_pending_position(G_GRAPH_NODE(target), PPF_DIRECT_X, pos, base); + g_graph_node_set_pending_position(G_GRAPH_NODE(target), PPF_DIRECT_X, pos); break; @@ -377,8 +379,18 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) rank_b = g_flow_node_get_rank(target_b); if (rank_a == rank_b) + { + /* On s'assure que le père est centré par rapport aux deux fils */ + + pos.left_node = G_GRAPH_NODE(target_a); + pos.right_node = G_GRAPH_NODE(target_b); + + g_graph_node_set_pending_position(base, PPF_MIDDLE_OF, pos); + break; + } + /* Alignement d'un bloc lié */ if (rank_a > rank_b) @@ -392,7 +404,8 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) if (container == NULL) container = G_GRAPH_NODE(target_b); pos.left_margin = g_flow_node_get_slot_offset(node, false, &node->exits[0]); - g_graph_node_set_pending_position(container, PPF_LEFT_MARGIN, pos, base); + pos.relative_ref = base; + g_graph_node_set_pending_position(container, PPF_LEFT_MARGIN, pos); /* Trait vertical de l'autre côté... */ @@ -403,7 +416,9 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) pos.direct_x -= g_flow_node_get_slot_offset(target_a, true, dest_slot); - g_graph_node_set_pending_position(G_GRAPH_NODE(target_a), PPF_DIRECT_X, pos, base); + pos.relative_ref = base; + + g_graph_node_set_pending_position(G_GRAPH_NODE(target_a), PPF_DIRECT_X, pos); } else @@ -417,7 +432,8 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) if (container == NULL) container = G_GRAPH_NODE(target_a); pos.right_margin = g_flow_node_get_slot_offset(node, false, &node->exits[1]); - g_graph_node_set_pending_position(container, PPF_RIGHT_MARGIN, pos, base); + pos.relative_ref = base; + g_graph_node_set_pending_position(container, PPF_RIGHT_MARGIN, pos); /* Trait vertical de l'autre côté... */ @@ -428,7 +444,9 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes) pos.direct_x -= g_flow_node_get_slot_offset(target_b, true, dest_slot); - g_graph_node_set_pending_position(G_GRAPH_NODE(target_b), PPF_DIRECT_X, pos, base); + pos.relative_ref = base; + + g_graph_node_set_pending_position(G_GRAPH_NODE(target_b), PPF_DIRECT_X, pos); } diff --git a/src/gtkext/graph/nodes/virtual.c b/src/gtkext/graph/nodes/virtual.c index 894c6b6..62f5b42 100644 --- a/src/gtkext/graph/nodes/virtual.c +++ b/src/gtkext/graph/nodes/virtual.c @@ -528,6 +528,8 @@ static void g_virtual_node_apply_x_line(GVirtualNode *node) size_t j; /* Boucle de parcours #2 */ gint width_sum; /* Largeur d'un étage traité */ gint x_pos; /* Abscisse à attribuer */ + GGraphNode *ref_a; /* Accès rapide #1 */ + GGraphNode *ref_b; /* Accès rapide #2 */ for (i = 0; i < node->lcount; i++) { @@ -559,6 +561,9 @@ static void g_virtual_node_apply_x_line(GVirtualNode *node) } + else if (level->children[0]->pending_flag == PPF_MIDDLE_OF) + continue; + /* On traite les noeuds individuellement */ else { @@ -593,6 +598,35 @@ static void g_virtual_node_apply_x_line(GVirtualNode *node) } + for (i = 0; i < node->lcount; i++) + { + level = &node->levels[i]; + + /* Si l'ensemble de l'étage doit être centré */ + if (level->children[0]->pending_flag == PPF_MIDDLE_OF) + { + ref_a = level->children[0]->pending_pos.left_node; + ref_b = level->children[0]->pending_pos.right_node; + + assert(g_graph_node_has_x_position(ref_a)); + assert(g_graph_node_has_x_position(ref_b)); + + if (ref_a->alloc.x < ref_b->alloc.x) + { + ref_b = level->children[0]->pending_pos.left_node; + ref_a = level->children[0]->pending_pos.right_node; + } + + x_pos = ref_a->alloc.x; + x_pos += (ref_b->alloc.x + ref_b->alloc.width - ref_a->alloc.x) / 2; + x_pos -= level->children[0]->alloc.width / 2; + + g_graph_node_set_x_position(level->children[0], x_pos); + + } + + } + } -- cgit v0.11.2-87-g4458