summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-12-21 19:30:29 +0000
committerDavid Robillard <d@drobilla.net>2012-12-21 19:30:29 +0000
commit9306840a17b29faa3dccb614dfe27a15fa0250c8 (patch)
tree7eb3cdfcd74d4371a9e234e8bea60e1b23656583
parent2c3cbd04b0d62382bad891e7933f709ef48c4be1 (diff)
downloadganv-9306840a17b29faa3dccb614dfe27a15fa0250c8.tar.gz
ganv-9306840a17b29faa3dccb614dfe27a15fa0250c8.tar.bz2
ganv-9306840a17b29faa3dccb614dfe27a15fa0250c8.zip
Implement item stacking.
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@4876 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ganv/Item.hpp1
-rw-r--r--ganv/canvas-base.h13
-rw-r--r--src/Canvas.cpp1
-rw-r--r--src/canvas-base.c97
-rw-r--r--src/edge.c3
-rw-r--r--src/ganv-private.h1
-rw-r--r--src/ganv_test.c2
-rw-r--r--src/group.c20
-rw-r--r--src/module.c1
-rw-r--r--src/node.c2
10 files changed, 43 insertions, 98 deletions
diff --git a/ganv/Item.hpp b/ganv/Item.hpp
index 08ad2d3..1009e12 100644
--- a/ganv/Item.hpp
+++ b/ganv/Item.hpp
@@ -55,7 +55,6 @@ public:
METHOD0(ganv_item, show);
METHOD0(ganv_item, hide);
- METHOD0(ganv_item, raise_to_top);
METHOD2(ganv_item, move, double, dx, double, dy);
GanvItem* property_parent() const {
diff --git a/ganv/canvas-base.h b/ganv/canvas-base.h
index 816fb28..161df81 100644
--- a/ganv/canvas-base.h
+++ b/ganv/canvas-base.h
@@ -83,6 +83,9 @@ struct _GanvItem {
/* Parent for this item */
GanvItem* parent;
+ /* Layer (z order), higher values are on top */
+ guint layer;
+
/* Position in parent-relative coordinates. */
double x, y;
@@ -172,14 +175,12 @@ void ganv_item_set(GanvItem* item, const gchar* first_arg_name, ...);
void ganv_item_set_valist(GanvItem* item,
const gchar* first_arg_name, va_list args);
-/* Move an item by the specified amount */
-void ganv_item_move(GanvItem* item, double dx, double dy);
+void ganv_item_raise(GanvItem* item);
-/* Raise an item to the top of its parent's z-order. */
-void ganv_item_raise_to_top(GanvItem* item);
+void ganv_item_lower(GanvItem* item);
-/* Lower an item to the bottom of its parent's z-order */
-void ganv_item_lower_to_bottom(GanvItem* item);
+/* Move an item by the specified amount */
+void ganv_item_move(GanvItem* item, double dx, double dy);
/* Show an item (make it visible). If the item is already shown, it has no
* effect.
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index 7674813..dcc59b2 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -960,7 +960,6 @@ GanvCanvasImpl::select_drag_handler(GdkEvent* event)
"fill-color", SELECT_RECT_FILL_COLOUR,
"border-color", SELECT_RECT_BORDER_COLOUR,
NULL));
- ganv_item_lower_to_bottom(GANV_ITEM(_select_rect));
ganv_item_grab(
GANV_ITEM(root()), GDK_POINTER_MOTION_MASK|GDK_BUTTON_RELEASE_MASK,
NULL, event->button.time);
diff --git a/src/canvas-base.c b/src/canvas-base.c
index 76e34e0..653ebf2 100644
--- a/src/canvas-base.c
+++ b/src/canvas-base.c
@@ -216,6 +216,7 @@ ganv_item_construct(GanvItem* item, GanvItem* parent,
item->parent = parent;
item->canvas = item->parent->canvas;
+ item->layer = 0;
g_object_set_valist(G_OBJECT(item), first_arg_name, args);
@@ -402,6 +403,18 @@ ganv_item_set_valist(GanvItem* item, const gchar* first_arg_name, va_list args)
item->canvas->need_repick = TRUE;
}
+void
+ganv_item_raise(GanvItem* item)
+{
+ ++item->layer;
+}
+
+void
+ganv_item_lower(GanvItem* item)
+{
+ --item->layer;
+}
+
/**
* ganv_item_move:
* @item: A canvas item.
@@ -421,90 +434,6 @@ ganv_item_move(GanvItem* item, double dx, double dy)
item->canvas->need_repick = TRUE;
}
-/* Convenience function to reorder items in a group's child list. This puts the
- * specified link after the "before" link. Returns TRUE if the list was changed.
- */
-#if 0
-static gboolean
-put_item_after(GList* link, GList* before)
-{
- GanvGroup* parent;
- GList* old_before, * old_after;
- GList* after;
-
- parent = GANV_GROUP(GANV_ITEM(link->data)->parent);
-
- if (before) {
- after = before->next;
- } else {
- after = parent->item_list;
- }
-
- if (( before == link) || ( after == link) ) {
- return FALSE;
- }
-
- /* Unlink */
-
- old_before = link->prev;
- old_after = link->next;
-
- if (old_before) {
- old_before->next = old_after;
- } else {
- parent->item_list = old_after;
- }
-
- if (old_after) {
- old_after->prev = old_before;
- } else {
- parent->item_list_end = old_before;
- }
-
- /* Relink */
-
- link->prev = before;
- if (before) {
- before->next = link;
- } else {
- parent->item_list = link;
- }
-
- link->next = after;
- if (after) {
- after->prev = link;
- } else {
- parent->item_list_end = link;
- }
-
- return TRUE;
-}
-#endif
-
-/**
- * ganv_item_raise_to_top:
- * @item: A canvas item.
- *
- * Raises an item to the top of its parent's stack.
- **/
-void
-ganv_item_raise_to_top(GanvItem* item)
-{
- fprintf(stderr, "FIXME: ganv_item_raise_to_top\n");
-}
-
-/**
- * ganv_item_lower_to_bottom:
- * @item: A canvas item.
- *
- * Lowers an item to the bottom of its parent's stack.
- **/
-void
-ganv_item_lower_to_bottom(GanvItem* item)
-{
- fprintf(stderr, "FIXME: ganv_item_lower_to_bottom\n");
-}
-
/**
* ganv_item_show:
* @item: A canvas item.
diff --git a/src/edge.c b/src/edge.c
index 3a34c20..21ce8de 100644
--- a/src/edge.c
+++ b/src/edge.c
@@ -644,7 +644,7 @@ void
ganv_edge_highlight(GanvEdge* edge)
{
edge->impl->highlighted = TRUE;
- ganv_item_raise_to_top(GANV_ITEM(edge));
+ ganv_item_raise(GANV_ITEM(edge));
ganv_item_request_update(GANV_ITEM(edge));
}
@@ -652,6 +652,7 @@ void
ganv_edge_unhighlight(GanvEdge* edge)
{
edge->impl->highlighted = FALSE;
+ ganv_item_lower(GANV_ITEM(edge));
ganv_item_request_update(GANV_ITEM(edge));
}
diff --git a/src/ganv-private.h b/src/ganv-private.h
index ad36e21..ddf6ab5 100644
--- a/src/ganv-private.h
+++ b/src/ganv-private.h
@@ -104,6 +104,7 @@ struct _GanvNodeImpl {
double border_width;
guint fill_color;
guint border_color;
+ guint layer;
gboolean can_tail;
gboolean can_head;
gboolean selected;
diff --git a/src/ganv_test.c b/src/ganv_test.c
index 971b3e1..97de437 100644
--- a/src/ganv_test.c
+++ b/src/ganv_test.c
@@ -84,7 +84,6 @@ main(int argc, char** argv)
ganv_port_set_control_is_toggle(tport, TRUE);
ganv_item_show(GANV_ITEM(module));
- ganv_item_raise_to_top(GANV_ITEM(module));
GanvModule* module2 = ganv_module_new(canvas,
"x", 200.0,
@@ -104,7 +103,6 @@ main(int argc, char** argv)
G_CALLBACK(on_disconnect), canvas);
ganv_item_show(GANV_ITEM(module2));
- ganv_item_raise_to_top(GANV_ITEM(module2));
gtk_widget_show_all(GTK_WIDGET(win));
gtk_window_present(win);
diff --git a/src/group.c b/src/group.c
index cd5e912..2a12951 100644
--- a/src/group.c
+++ b/src/group.c
@@ -195,6 +195,12 @@ ganv_group_unmap(GanvItem* item)
(*group_parent_class->unmap)(item);
}
+static gint
+item_layer_cmp(const void* a, const void* b, void* user_data)
+{
+ return ((GanvItem*)a)->layer - ((GanvItem*)b)->layer;
+}
+
static void
ganv_group_draw(GanvItem* item, cairo_t* cr,
int x, int y, int width, int height)
@@ -210,6 +216,7 @@ ganv_group_draw(GanvItem* item, cairo_t* cr,
cairo_rectangle(cr, x, y, width, height);
cairo_fill(cr);
+ GSequence* items = g_sequence_new(NULL);
for (list = group->item_list; list; list = list->next) {
child = (GanvItem*)list->data;
@@ -224,11 +231,20 @@ ganv_group_draw(GanvItem* item, cairo_t* cr,
&& (child->x2 > child->canvas->redraw_x1)
&& (child->y2 > child->canvas->redraw_y2))) {
if (GANV_ITEM_GET_CLASS(child)->draw) {
- (*GANV_ITEM_GET_CLASS(child)->draw)(
- child, cr, x, y, width, height);
+ g_sequence_insert_sorted(items, child, item_layer_cmp, NULL);
}
}
}
+
+ for (GSequenceIter* i = g_sequence_get_begin_iter(items);
+ !g_sequence_iter_is_end(i);
+ i = g_sequence_iter_next(i)) {
+ child = (GanvItem*)g_sequence_get(i);
+ (*GANV_ITEM_GET_CLASS(child)->draw)(
+ child, cr, x, y, width, height);
+ }
+
+ g_sequence_free(items);
}
static double
diff --git a/src/module.c b/src/module.c
index 98e7272..654038a 100644
--- a/src/module.c
+++ b/src/module.c
@@ -798,7 +798,6 @@ ganv_module_embed(GanvModule* module,
on_embed_size_request(widget, &r, module);
ganv_item_show(impl->embed_item);
- ganv_item_raise_to_top(impl->embed_item);
g_signal_connect(widget, "size-request",
G_CALLBACK(on_embed_size_request), module);
diff --git a/src/node.c b/src/node.c
index f49f688..8bafbde 100644
--- a/src/node.c
+++ b/src/node.c
@@ -426,11 +426,13 @@ ganv_node_default_event(GanvItem* item,
switch (event->type) {
case GDK_ENTER_NOTIFY:
+ ganv_item_raise(GANV_ITEM(node));
ganv_item_set(GANV_ITEM(node),
"highlighted", TRUE, NULL);
return TRUE;
case GDK_LEAVE_NOTIFY:
+ ganv_item_lower(GANV_ITEM(node));
ganv_item_set(GANV_ITEM(node),
"highlighted", FALSE, NULL);
return TRUE;