summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-05-12 18:55:55 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-05-12 18:55:55 (GMT)
commit4605b4ac4a04bb11bdf91d77e248656702774bde (patch)
tree4987c19b0f739ef7cb89ac80068233d6fb037819 /src
parent46bcc7f122245f22772fd3e38d16e6afa7bd5881 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/gtkext/graph/layout.c4
-rw-r--r--src/gtkext/graph/node-int.h7
-rw-r--r--src/gtkext/graph/node.c24
-rw-r--r--src/gtkext/graph/node.h28
-rw-r--r--src/gtkext/graph/nodes/flow.c28
-rw-r--r--src/gtkext/graph/nodes/virtual.c34
6 files changed, 93 insertions, 32 deletions
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);
+
+ }
+
+ }
+
}