summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-03-09 22:31:06 +0000
committerDavid Robillard <d@drobilla.net>2012-03-09 22:31:06 +0000
commita4811c2f8ca7d8e32d1230b58e8140b60fcee2a3 (patch)
treeb7b4966f5f4200bcc4e5d2fd02bf50629f63bf3c
parentef767283f7afc77c61961007e97474694160f7c3 (diff)
downloadganv-a4811c2f8ca7d8e32d1230b58e8140b60fcee2a3.tar.gz
ganv-a4811c2f8ca7d8e32d1230b58e8140b60fcee2a3.tar.bz2
ganv-a4811c2f8ca7d8e32d1230b58e8140b60fcee2a3.zip
Fix "disconnect all".
git-svn-id: http://svn.drobilla.net/lad/trunk/ganv@4036 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--ganv/Edge.hpp8
-rw-r--r--ganv/canvas.h9
-rw-r--r--ganv/edge.h14
-rw-r--r--src/Canvas.cpp39
-rw-r--r--src/edge.c11
-rw-r--r--src/ganv_test.c39
-rw-r--r--src/node.c2
7 files changed, 108 insertions, 14 deletions
diff --git a/ganv/Edge.hpp b/ganv/Edge.hpp
index ee2423c..6912eb2 100644
--- a/ganv/Edge.hpp
+++ b/ganv/Edge.hpp
@@ -46,7 +46,6 @@ public:
bool show_arrowhead = false,
bool curved = true)
: Item(GANV_ITEM(
- g_object_ref(
ganv_edge_new(
canvas.gobj(),
tail->gobj(),
@@ -54,11 +53,12 @@ public:
"color", color,
"curved", (gboolean)curved,
"arrowhead", (gboolean)show_arrowhead,
- NULL))))
- {}
+ NULL)))
+ {
+ }
Edge(GanvEdge* gobj)
- : Item(GANV_ITEM(g_object_ref(gobj)))
+ : Item(GANV_ITEM(gobj))
{}
virtual ~Edge() {
diff --git a/ganv/canvas.h b/ganv/canvas.h
index ddd420b..bbf6b97 100644
--- a/ganv/canvas.h
+++ b/ganv/canvas.h
@@ -77,6 +77,15 @@ void
ganv_canvas_add_node(GanvCanvas* canvas,
GanvNode* node);
+void
+ganv_canvas_disconnect_edge(GanvCanvas* canvas,
+ GanvEdge* edge);
+
+void
+ganv_canvas_remove_edge_between(GanvCanvas* canvas,
+ GanvNode* tail,
+ GanvNode* head);
+
/** Get the default font size in points. */
double
ganv_canvas_get_default_font_size(const GanvCanvas* canvas);
diff --git a/ganv/edge.h b/ganv/edge.h
index 9a409b2..2d51c89 100644
--- a/ganv/edge.h
+++ b/ganv/edge.h
@@ -71,6 +71,20 @@ ganv_edge_highlight(GanvEdge* edge);
void
ganv_edge_unhighlight(GanvEdge* edge);
+/**
+ * ganv_edge_disconnect:
+ * Disconnect the edge. This will disconnect the edge just as if it had been
+ * disconnected by the user via the canvas. The canvas disconnect signal will
+ * be emitted, allowing the application to control disconnect logic.
+ */
+void
+ganv_edge_disconnect(GanvEdge* edge);
+
+/**
+ * ganv_edge_remove:
+ * Remove the edge from the canvas. This will only remove the edge visually,
+ * it will not emit the canvas disconnect signal to notify the application.
+ */
void
ganv_edge_remove(GanvEdge* edge);
diff --git a/src/Canvas.cpp b/src/Canvas.cpp
index 15dedef..e353945 100644
--- a/src/Canvas.cpp
+++ b/src/Canvas.cpp
@@ -188,6 +188,9 @@ struct GanvCanvasImpl {
void remove_edge(GanvEdge* c);
bool are_connected(const GanvNode* tail,
const GanvNode* head);
+ GanvEdge*
+ get_edge_between(const GanvNode* tail,
+ const GanvNode* head);
typedef std::set<GanvEdge*, TailHeadOrder> Edges;
typedef std::set<GanvEdge*, HeadTailOrder> DstEdges;
@@ -598,9 +601,20 @@ GanvCanvasImpl::remove_edge(GanvEdge* edge)
_selected_edges.erase(edge);
_edges.erase(edge);
_dst_edges.erase(edge);
+ gtk_object_destroy(GTK_OBJECT(edge));
}
}
+GanvEdge*
+GanvCanvasImpl::get_edge_between(const GanvNode* tail,
+ const GanvNode* head)
+{
+ GanvEdgeKey key;
+ make_edge_search_key(&key, tail, head);
+ Edges::const_iterator i = _edges.find((GanvEdge*)&key);
+ return (i != _edges.end()) ? *i : NULL;
+}
+
/** Return whether there is a edge between item1 and item2.
*
* Note that edges are directed, so this may return false when there
@@ -610,9 +624,7 @@ bool
GanvCanvasImpl::are_connected(const GanvNode* tail,
const GanvNode* head)
{
- GanvEdgeKey key;
- make_edge_search_key(&key, tail, head);
- return (_edges.find((GanvEdge*)&key) != _edges.end());
+ return get_edge_between(tail, head) != NULL;
}
void
@@ -1500,12 +1512,11 @@ Canvas::set_default_placement(Node* i)
}
void
-Canvas::remove_edge(Node* item1,
- Node* item2)
+Canvas::remove_edge(Node* item1, Node* item2)
{
Edge* edge = get_edge(item1, item2);
if (edge) {
- gtk_object_destroy(GTK_OBJECT(edge->gobj()));
+ impl()->remove_edge(edge->gobj());
}
}
@@ -1953,6 +1964,22 @@ ganv_canvas_add_node(GanvCanvas* canvas,
}
void
+ganv_canvas_remove_edge_between(GanvCanvas* canvas,
+ GanvNode* tail,
+ GanvNode* head)
+{
+ canvas->impl->remove_edge(canvas->impl->get_edge_between(tail, head));
+}
+
+void
+ganv_canvas_disconnect_edge(GanvCanvas* canvas,
+ GanvEdge* edge)
+{
+ g_signal_emit(canvas, signal_disconnect, 0,
+ edge->impl->tail, edge->impl->head, NULL);
+}
+
+void
ganv_canvas_remove_node(GanvCanvas* canvas,
GanvNode* node)
{
diff --git a/src/edge.c b/src/edge.c
index 8d43f46..65690cd 100644
--- a/src/edge.c
+++ b/src/edge.c
@@ -88,7 +88,6 @@ ganv_edge_destroy(GtkObject* object)
GanvEdge* edge = GANV_EDGE(object);
GanvCanvas* canvas = GANV_CANVAS(edge->item.canvas);
if (canvas && !edge->impl->ghost) {
- ganv_canvas_remove_edge(canvas, edge);
edge->item.canvas = NULL;
}
edge->item.parent = NULL;
@@ -642,6 +641,16 @@ ganv_edge_tick(GanvEdge* edge,
}
void
+ganv_edge_disconnect(GanvEdge* edge)
+{
+ if (!edge->impl->ghost) {
+ ganv_canvas_disconnect_edge(
+ GANV_CANVAS(edge->item.canvas),
+ edge);
+ }
+}
+
+void
ganv_edge_remove(GanvEdge* edge)
{
if (!edge->impl->ghost) {
diff --git a/src/ganv_test.c b/src/ganv_test.c
index a1fba2a..fce3ede 100644
--- a/src/ganv_test.c
+++ b/src/ganv_test.c
@@ -18,12 +18,23 @@
#include "ganv/ganv.h"
static void
-on_window_destroy(GtkWidget* widget,
- gpointer data)
+on_window_destroy(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
}
+static void
+on_connect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
+{
+ ganv_edge_new(canvas, tail, head, "color", 0xFFFFFFFF, NULL);
+}
+
+static void
+on_disconnect(GanvCanvas* canvas, GanvNode* tail, GanvNode* head, void* data)
+{
+ ganv_canvas_remove_edge_between(canvas, tail, head);
+}
+
int
main(int argc, char** argv)
{
@@ -44,6 +55,10 @@ main(int argc, char** argv)
"label", "test",
NULL);
+ GanvPort* port = ganv_port_new(module, FALSE,
+ "label", "Signal",
+ NULL);
+
GanvPort* cport = ganv_port_new(module, TRUE,
"label", "Control",
NULL);
@@ -61,6 +76,26 @@ main(int argc, char** argv)
ganv_item_show(GANV_ITEM(module));
ganv_item_raise_to_top(GANV_ITEM(module));
+ GanvModule* module2 = ganv_module_new(canvas,
+ "x", 200.0,
+ "y", 10.0,
+ "draggable", TRUE,
+ "label", "test2",
+ NULL);
+
+ GanvPort* port2 = ganv_port_new(module2, TRUE,
+ "label", "Signal",
+ NULL);
+
+ g_signal_connect(canvas, "connect",
+ G_CALLBACK(on_connect), canvas);
+
+ g_signal_connect(canvas, "disconnect",
+ 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);
gtk_main();
diff --git a/src/node.c b/src/node.c
index a59bde3..e2b6213 100644
--- a/src/node.c
+++ b/src/node.c
@@ -299,7 +299,7 @@ ganv_node_default_disconnect(GanvNode* node)
{
GanvCanvas* canvas = GANV_CANVAS(GANV_ITEM(node)->canvas);
if (canvas) {
- ganv_canvas_for_each_edge_on(canvas, node, ganv_edge_remove);
+ ganv_canvas_for_each_edge_on(canvas, node, ganv_edge_disconnect);
}
}