summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-01-11 03:49:32 +0000
committerDavid Robillard <d@drobilla.net>2012-01-11 03:49:32 +0000
commit5efc7ae9c304d7e01cc00291e0857ced7d3582ba (patch)
tree95952f5f1e49a3c6190291add106e96d90a11c86
parentb666782d06fc2cd9fe810b3fdbf13cc3949f6927 (diff)
downloadganv-5efc7ae9c304d7e01cc00291e0857ced7d3582ba.tar.gz
ganv-5efc7ae9c304d7e01cc00291e0857ced7d3582ba.tar.bz2
ganv-5efc7ae9c304d7e01cc00291e0857ced7d3582ba.zip
Fix crash on shutdown and item deletion.
Use Item add and remove virtual methods for adding/removing ports instead of special explicit functions. git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@3933 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ganv/Item.hpp5
-rw-r--r--ganv/module.h4
-rw-r--r--src/canvas-base.c6
-rw-r--r--src/module.c237
-rw-r--r--src/node.c2
-rw-r--r--src/port.c5
6 files changed, 141 insertions, 118 deletions
diff --git a/ganv/Item.hpp b/ganv/Item.hpp
index 7dacf01..e4f2c52 100644
--- a/ganv/Item.hpp
+++ b/ganv/Item.hpp
@@ -46,7 +46,10 @@ public:
}
}
- virtual ~Item() {}
+ virtual ~Item() {
+ gtk_object_destroy(GTK_OBJECT(_gobj));
+ }
+
RW_PROPERTY(double, x)
RW_PROPERTY(double, y)
diff --git a/ganv/module.h b/ganv/module.h
index 7520722..16c5258 100644
--- a/ganv/module.h
+++ b/ganv/module.h
@@ -61,10 +61,6 @@ GanvPort*
ganv_module_get_port(GanvModule* module,
guint index);
-void
-ganv_module_add_port(GanvModule* module,
- GanvPort* port);
-
double
ganv_module_get_empty_port_breadth(const GanvModule* module);
diff --git a/src/canvas-base.c b/src/canvas-base.c
index 50a1027..04dfaa3 100644
--- a/src/canvas-base.c
+++ b/src/canvas-base.c
@@ -269,7 +269,11 @@ ganv_item_dispose(GObject* object)
}
if (item->parent) {
- GANV_ITEM_GET_CLASS(item->parent)->remove(item->parent, item);
+ if (GANV_ITEM_GET_CLASS(item->parent)->remove) {
+ GANV_ITEM_GET_CLASS(item->parent)->remove(item->parent, item);
+ } else {
+ fprintf(stderr, "warning: Item parent has no remove method\n");
+ }
}
G_OBJECT_CLASS(item_parent_class)->dispose(object);
diff --git a/src/module.c b/src/module.c
index 8ca3d72..ff85c6f 100644
--- a/src/module.c
+++ b/src/module.c
@@ -79,8 +79,8 @@ ganv_module_destroy(GtkObject* object)
GanvModuleImpl* impl = module->impl;
if (impl->ports) {
- FOREACH_PORT(impl->ports, p) {
- gtk_object_destroy(GTK_OBJECT(*p));
+ FOREACH_PORT(impl->ports, p) {
+ g_object_unref(GTK_OBJECT(*p));
}
g_ptr_array_free(impl->ports, TRUE);
impl->ports = NULL;
@@ -508,6 +508,131 @@ ganv_module_resize(GanvNode* self)
}
static void
+ganv_module_add_port(GanvModule* module,
+ GanvPort* port)
+{
+ GanvModuleImpl* impl = module->impl;
+
+ const double width = ganv_port_get_natural_width(port);
+ if (port->impl->is_input && width > impl->widest_input) {
+ impl->widest_input = width;
+ impl->must_resize = TRUE;
+ } else if (!port->impl->is_input && width > impl->widest_output) {
+ impl->widest_output = width;
+ impl->must_resize = TRUE;
+ }
+
+#if 0
+
+ double port_x, port_y;
+
+ // Place vertically
+ if (canvas()->direction() == Canvas::HORIZONTAL) {
+ if (gobj()->ports->len != 0) {
+ const Port* const last_port = *back();
+ port_y = last_port->get_y() + last_port->get_height() + 1;
+ } else {
+ port_y = 2.0 + title_height();
+ }
+ } else {
+ if (p->is_input()) {
+ port_y = 0.0;
+ } else {
+ port_y = get_height() - get_empty_port_depth();
+ }
+ }
+
+ // Place horizontally
+ Metrics m;
+ calculate_metrics(m);
+
+ set_width(m.width);
+ if (p->is_input()) {
+ p->set_width(m.input_width);
+ port_x = 0;
+ } else {
+ p->set_width(m.output_width);
+ port_x = m.width - p->get_width();
+ }
+
+ p->move_to(port_x, port_y);
+
+ g_ptr_array_add(gobj()->ports, p->gobj());
+ if (canvas()->direction() == Canvas::HORIZONTAL) {
+ set_height(p->get_y() + p->get_height() + 1);
+ }
+
+ place_title();
+#endif
+ impl->must_resize = TRUE;
+
+ g_ptr_array_add(impl->ports, port);
+ //if (canvas()->direction() == Canvas::HORIZONTAL) {
+ // set_height(p->get_y() + p->get_height() + 1);
+ //}
+
+ GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(module)->canvas);
+
+ place_title(module, canvas->direction);
+ ganv_item_request_update(GANV_ITEM(module));
+}
+
+static void
+ganv_module_remove_port(GanvModule* module,
+ GanvPort* port)
+{
+ gboolean removed = g_ptr_array_remove(module->impl->ports, port);
+ if (removed) {
+ const double width = ganv_box_get_width(GANV_BOX(port));
+ // Find new widest input or output, if necessary
+ if (port->impl->is_input && width >= module->impl->widest_input) {
+ module->impl->widest_input = 0;
+ FOREACH_PORT_CONST(module->impl->ports, i) {
+ const GanvPort* const p = (*i);
+ const double w = ganv_box_get_width(GANV_BOX(p));
+ if (p->impl->is_input && w >= module->impl->widest_input) {
+ module->impl->widest_input = w;
+ }
+ }
+ } else if (!port->impl->is_input && width >= module->impl->widest_output) {
+ module->impl->widest_output = 0;
+ FOREACH_PORT_CONST(module->impl->ports, i) {
+ const GanvPort* const p = (*i);
+ const double w = ganv_box_get_width(GANV_BOX(p));
+ if (!p->impl->is_input && w >= module->impl->widest_output) {
+ module->impl->widest_output = w;
+ }
+ }
+ }
+
+ module->impl->must_resize = TRUE;
+ ganv_item_request_update(GANV_ITEM(module));
+ } else {
+ fprintf(stderr, "Failed to find port to remove\n");
+ }
+}
+
+static void
+ganv_module_add(GanvItem* item, GanvItem* child)
+{
+ if (GANV_IS_PORT(child)) {
+ ganv_module_add_port(GANV_MODULE(item), GANV_PORT(child));
+ } else {
+ fprintf(stderr, "warning: Non-port item added to module.\n");
+ }
+}
+
+static void
+ganv_module_remove(GanvItem* item, GanvItem* child)
+{
+ if (GANV_IS_PORT(child)) {
+ ganv_module_remove_port(GANV_MODULE(item), GANV_PORT(child));
+ } else {
+ fprintf(stderr, "warning: Non-port item removed from module.\n");
+ }
+}
+
+static void
ganv_module_update(GanvItem* item, int flags)
{
GanvNode* node = GANV_NODE(item);
@@ -623,6 +748,8 @@ ganv_module_class_init(GanvModuleClass* class)
object_class->destroy = ganv_module_destroy;
+ item_class->add = ganv_module_add;
+ item_class->remove = ganv_module_remove;
item_class->update = ganv_module_update;
item_class->draw = ganv_module_draw;
item_class->point = ganv_module_point;
@@ -660,112 +787,6 @@ ganv_module_get_port(GanvModule* module,
return g_ptr_array_index(module->impl->ports, index);
}
-void
-ganv_module_add_port(GanvModule* module,
- GanvPort* port)
-{
- GanvModuleImpl* impl = module->impl;
-
- const double width = ganv_port_get_natural_width(port);
- if (port->impl->is_input && width > impl->widest_input) {
- impl->widest_input = width;
- impl->must_resize = TRUE;
- } else if (!port->impl->is_input && width > impl->widest_output) {
- impl->widest_output = width;
- impl->must_resize = TRUE;
- }
-
-#if 0
-
- double port_x, port_y;
-
- // Place vertically
- if (canvas()->direction() == Canvas::HORIZONTAL) {
- if (gobj()->ports->len != 0) {
- const Port* const last_port = *back();
- port_y = last_port->get_y() + last_port->get_height() + 1;
- } else {
- port_y = 2.0 + title_height();
- }
- } else {
- if (p->is_input()) {
- port_y = 0.0;
- } else {
- port_y = get_height() - get_empty_port_depth();
- }
- }
-
- // Place horizontally
- Metrics m;
- calculate_metrics(m);
-
- set_width(m.width);
- if (p->is_input()) {
- p->set_width(m.input_width);
- port_x = 0;
- } else {
- p->set_width(m.output_width);
- port_x = m.width - p->get_width();
- }
-
- p->move_to(port_x, port_y);
-
- g_ptr_array_add(gobj()->ports, p->gobj());
- if (canvas()->direction() == Canvas::HORIZONTAL) {
- set_height(p->get_y() + p->get_height() + 1);
- }
-
- place_title();
-#endif
- impl->must_resize = TRUE;
-
- g_ptr_array_add(impl->ports, port);
- //if (canvas()->direction() == Canvas::HORIZONTAL) {
- // set_height(p->get_y() + p->get_height() + 1);
- //}
-
- GanvCanvas* canvas = GANV_CANVAS(
- GANV_ITEM(module)->canvas);
-
- place_title(module, canvas->direction);
- ganv_item_request_update(GANV_ITEM(module));
-}
-
-void
-ganv_module_remove_port(GanvModule* module,
- GanvPort* port)
-{
- printf("FIXME: remove port\n");
-#if 0
- gboolean removed = g_ptr_array_remove(gobj()->ports, port->gobj());
- if (removed) {
- // Find new widest input or output, if necessary
- if (port->is_input() && port->get_width() >= _widest_input) {
- _widest_input = 0;
- FOREACH_PORT_CONST(gobj()->ports, i) {
- const Port* const p = (*i);
- if (p->is_input() && p->get_width() >= _widest_input) {
- _widest_input = p->get_width();
- }
- }
- } else if (port->is_output() && port->get_width() >= _widest_output) {
- _widest_output = 0;
- FOREACH_PORT_CONST(gobj()->ports, i) {
- const Port* const p = (*i);
- if (p->is_output() && p->get_width() >= _widest_output) {
- _widest_output = p->get_width();
- }
- }
- }
-
- _must_resize = true;
- ganv_item_request_update(GANV_ITEM(_gobj));
- } else {
- std::cerr << "Failed to find port to remove" << std::endl;
- }
-#endif
-}
-
double
ganv_module_get_empty_port_breadth(const GanvModule* module)
{
diff --git a/src/node.c b/src/node.c
index e162e04..a59bde3 100644
--- a/src/node.c
+++ b/src/node.c
@@ -85,7 +85,7 @@ ganv_node_destroy(GtkObject* object)
GanvNode* node = GANV_NODE(object);
GanvNodeImpl* impl = node->impl;
if (impl->label) {
- gtk_object_destroy(GTK_OBJECT(impl->label));
+ g_object_unref(impl->label);
impl->label = NULL;
}
diff --git a/src/port.c b/src/port.c
index d220601..e8e6754 100644
--- a/src/port.c
+++ b/src/port.c
@@ -273,6 +273,8 @@ ganv_port_new(GanvModule* module,
GanvPort* port = GANV_PORT(
g_object_new(ganv_port_get_type(), NULL));
+ port->impl->is_input = is_input;
+
GanvItem* item = GANV_ITEM(port);
va_list args;
va_start(args, first_prop_name);
@@ -281,8 +283,6 @@ ganv_port_new(GanvModule* module,
first_prop_name, args);
va_end(args);
- port->impl->is_input = is_input;
-
GanvBox* box = GANV_BOX(port);
box->impl->radius_tl = (is_input ? 0.0 : 4.0);
box->impl->radius_tr = (is_input ? 4.0 : 0.0);
@@ -309,7 +309,6 @@ ganv_port_new(GanvModule* module,
}
}
- ganv_module_add_port(module, port);
return port;
}