summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-02-09 19:48:01 +0000
committerDavid Robillard <d@drobilla.net>2013-02-09 19:48:01 +0000
commit9e7fc19585462932e4cca91538a1078b1f0e300d (patch)
tree1247517822b6d9c06e39e226932a1a9d55839e57
parent6ddaa0260c4749aa6c0395000381d7df0bd3feb1 (diff)
downloadganv-9e7fc19585462932e4cca91538a1078b1f0e300d.tar.gz
ganv-9e7fc19585462932e4cca91538a1078b1f0e300d.tar.bz2
ganv-9e7fc19585462932e4cca91538a1078b1f0e300d.zip
Fix crash when making a connection from a node that is destroyed (#884).
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@5049 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/Canvas.cpp72
1 files changed, 40 insertions, 32 deletions
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index f55d1d8..209391c 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -132,6 +132,8 @@ struct GanvCanvasImpl {
, _layout(GTK_LAYOUT(_gcanvas))
, _connect_port(NULL)
, _last_selected_port(NULL)
+ , _drag_edge(NULL)
+ , _drag_node(NULL)
, _select_rect(NULL)
, _zoom(1.0)
, _font_size(0.0)
@@ -216,6 +218,7 @@ struct GanvCanvasImpl {
bool scroll_drag_handler(GdkEvent* event);
bool select_drag_handler(GdkEvent* event);
bool connect_drag_handler(GdkEvent* event);
+ void end_connect_drag();
/**
Event handler for ports.
@@ -243,6 +246,8 @@ struct GanvCanvasImpl {
SelectedPorts _selected_ports; ///< Selected ports (hilited red)
GanvPort* _connect_port; ///< Port for which a edge is being made
GanvPort* _last_selected_port;
+ GanvEdge* _drag_edge;
+ GanvNode* _drag_node;
GanvBox* _select_rect; ///< Rectangle for drag selection
@@ -385,6 +390,14 @@ GanvCanvasImpl::remove_item(GanvNode* item)
{
bool ret = false;
+ if (item == (GanvNode*)_connect_port) {
+ if (_drag_state == EDGE) {
+ ganv_item_ungrab(GANV_ITEM(root()), 0);
+ end_connect_drag();
+ }
+ _connect_port = NULL;
+ }
+
// Remove from selection
_selected_items.erase(item);
@@ -1041,9 +1054,7 @@ GanvCanvasImpl::select_drag_handler(GdkEvent* event)
bool
GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
{
- static GanvEdge* drag_edge = NULL;
- static GanvNode* drag_node = NULL;
- static bool snapped = false;
+ static bool snapped = false;
if (_drag_state != EDGE) {
return false;
@@ -1053,12 +1064,12 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
double x, y;
get_motion_coords(&event->motion, &x, &y);
- if (!drag_edge) {
+ if (!_drag_edge) {
// Create drag edge
- assert(!drag_node);
+ assert(!_drag_node);
assert(_connect_port);
- drag_node = GANV_NODE(
+ _drag_node = GANV_NODE(
ganv_item_new(
GANV_ITEM(ganv_canvas_base_root(GANV_CANVAS_BASE(_gcanvas))),
ganv_node_get_type(),
@@ -1066,10 +1077,10 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
"y", y,
NULL));
- drag_edge = ganv_edge_new(
+ _drag_edge = ganv_edge_new(
_gcanvas,
GANV_NODE(_connect_port),
- drag_node,
+ _drag_node,
"color", GANV_NODE(_connect_port)->impl->fill_color,
"curved", TRUE,
"ghost", TRUE,
@@ -1077,24 +1088,20 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
}
GanvNode* joinee = get_node_at(x, y);
- if (joinee && ganv_node_can_head(joinee) && joinee != drag_node) {
+ if (joinee && ganv_node_can_head(joinee) && joinee != _drag_node) {
// Snap to item
snapped = true;
- ganv_item_set(&drag_edge->item,
- "head", joinee,
- NULL);
+ ganv_item_set(&_drag_edge->item, "head", joinee, NULL);
} else if (snapped) {
// Unsnap from item
snapped = false;
- ganv_item_set(&drag_edge->item,
- "head", drag_node,
- NULL);
+ ganv_item_set(&_drag_edge->item, "head", _drag_node, NULL);
}
// Update drag edge for pointer position
- ganv_node_move_to(drag_node, x, y);
- ganv_item_request_update(GANV_ITEM(drag_node));
- ganv_item_request_update(GANV_ITEM(drag_edge));
+ ganv_node_move_to(_drag_node, x, y);
+ ganv_item_request_update(GANV_ITEM(_drag_node));
+ ganv_item_request_update(GANV_ITEM(_drag_edge));
return true;
@@ -1125,27 +1132,28 @@ GanvCanvasImpl::connect_drag_handler(GdkEvent* event)
}
}
- // Clean up dragging stuff
-
- if (_connect_port) {
- g_object_set(G_OBJECT(_connect_port), "highlighted", FALSE, NULL);
- }
-
unselect_ports();
- _drag_state = NOT_DRAGGING;
- _connect_port = NULL;
-
- gtk_object_destroy(GTK_OBJECT(drag_edge));
- gtk_object_destroy(GTK_OBJECT(drag_node));
- drag_edge = NULL;
- drag_node = NULL;
-
+ end_connect_drag();
return true;
}
return false;
}
+void
+GanvCanvasImpl::end_connect_drag()
+{
+ if (_connect_port) {
+ g_object_set(G_OBJECT(_connect_port), "highlighted", FALSE, NULL);
+ }
+ gtk_object_destroy(GTK_OBJECT(_drag_edge));
+ gtk_object_destroy(GTK_OBJECT(_drag_node));
+ _drag_state = NOT_DRAGGING;
+ _connect_port = NULL;
+ _drag_edge = NULL;
+ _drag_node = NULL;
+}
+
bool
GanvCanvasImpl::port_event(GdkEvent* event, GanvPort* port)
{