diff --git a/rtbuf_gtk.c b/rtbuf_gtk.c
index 396e49f..a28f4bf 100644
--- a/rtbuf_gtk.c
+++ b/rtbuf_gtk.c
@@ -39,6 +39,42 @@ gint rtbuf_x = 100;
gint rtbuf_y = 100;
s_rtbuf_gtk_connection *modular_connections = NULL;
+s_rtbuf_gtk_connection *drag_connection = NULL;
+
+void rtbuf_gtk_drag_connection_end (RtbufInputWidget *input_widget)
+{
+ if (drag_connection) {
+ if (input_widget) {
+ printf("rtbuf-gtk drag connection connected to input\n");
+ drag_connection->input_widget = input_widget;
+ }
+ else {
+ printf("rtbuf-gtk drag connection abort\n");
+ rtbuf_gtk_connection_remove_one(&modular_connections,
+ drag_connection);
+ drag_connection = NULL;
+ gtk_widget_queue_draw(GTK_WIDGET(modular_layout));
+ }
+ }
+}
+
+gboolean rtbuf_gtk_input_motion (RtbufInputWidget *widget,
+ GdkEventMotion *event)
+{
+ printf("rtbuf-gtk input motion\n");
+ if (drag_connection) {
+ if (!(event->state & GDK_BUTTON1_MASK)) {
+ rtbuf_gtk_drag_connection_end(widget);
+ return TRUE;
+ }
+ else {
+ drag_connection->input_widget = widget;
+ gtk_widget_queue_draw(GTK_WIDGET(modular_layout));
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
RtbufWidget * rtbuf_gtk_modular_layout_new (s_rtbuf *rtbuf,
const gint x, const gint y)
@@ -57,6 +93,9 @@ RtbufWidget * rtbuf_gtk_modular_layout_new (s_rtbuf *rtbuf,
g_signal_connect_swapped(G_OBJECT(event_box), "button-press-event",
G_CALLBACK(rtbuf_gtk_rtbuf_button_press),
widget);
+ rtbuf_widget_connect_inputs
+ (widget, "motion-notify-event",
+ G_CALLBACK(rtbuf_gtk_input_motion));
rtbuf_widget_connect_input_checks
(widget, "button-press-event",
G_CALLBACK(rtbuf_gtk_input_check_button_press));
@@ -154,8 +193,6 @@ void rtbuf_gtk_modular_draw_arrow (cairo_t *cr, int x1, int y1,
{
const int arrow_size = 4;
int mx = (x2 - x1) / 3;
- printf("rtbuf-gtk modular draw arrow (%i,%i) -> (%i,%i)\n",
- x1, y1, x2, y2);
if (mx < 0) {
mx = -mx;
mx += mx / 2;
@@ -248,7 +285,7 @@ gboolean rtbuf_gtk_modular_motion (GtkWidget *widget,
{
if (drag_widget) {
if (!(event->state & GDK_BUTTON1_MASK)) {
- printf("rtbuf-gtk modular drop\n");
+ printf("rtbuf-gtk modular drop widget\n");
drag_widget = NULL;
return TRUE;
}
@@ -265,15 +302,21 @@ gboolean rtbuf_gtk_modular_motion (GtkWidget *widget,
return TRUE;
}
}
- /*
else if (drag_connection) {
- GdkWindow *window =
- gtk_widget_get_window(GTK_WIDGET(modular_layout));
- gdk_window_get_device_position(window, event->device,
- &drag_x, &drag_y, NULL);
- gtk_widget_queue_draw(GTK_WIDGET(modular_layout));
+ if (!(event->state & GDK_BUTTON1_MASK)) {
+ rtbuf_gtk_drag_connection_end(NULL);
+ return TRUE;
+ }
+ else {
+ GdkWindow *window =
+ gtk_widget_get_window(GTK_WIDGET(modular_layout));
+ gdk_window_get_device_position(window, event->device,
+ &drag_x, &drag_y, NULL);
+ drag_connection->input_widget = NULL;
+ gtk_widget_queue_draw(GTK_WIDGET(modular_layout));
+ return TRUE;
+ }
}
- */
return FALSE;
}
diff --git a/rtbuf_gtk.h b/rtbuf_gtk.h
index 2abbaa1..9fb0b87 100644
--- a/rtbuf_gtk.h
+++ b/rtbuf_gtk.h
@@ -38,9 +38,10 @@ s_rtbuf_gtk_connection *modular_connections;
GtkTargetList *rtbuf_move_target_list;
-GtkWidget *drag_widget;
-gint drag_x;
-gint drag_y;
+GtkWidget *drag_widget;
+s_rtbuf_gtk_connection *drag_connection;
+gint drag_x;
+gint drag_y;
gboolean rtbuf_gtk_rtbuf_button_press (GtkWidget *widget,
GdkEvent *event,
diff --git a/rtbuf_gtk_connection.c b/rtbuf_gtk_connection.c
index d8288e7..28dfea0 100644
--- a/rtbuf_gtk_connection.c
+++ b/rtbuf_gtk_connection.c
@@ -14,6 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <assert.h>
#include "data.h"
#include "rtbuf_gtk.h"
@@ -40,3 +41,24 @@ void rtbuf_gtk_connection_delete (s_rtbuf_gtk_connection *connection)
{
data_delete(&g_rtbuf_gtk_connection_alloc, connection);
}
+
+void rtbuf_gtk_connection_push (s_rtbuf_gtk_connection **head,
+ s_rtbuf_gtk_connection *item)
+{
+ assert(!item->next);
+ item->next = *head;
+ *head = item;
+}
+
+int rtbuf_gtk_connection_remove_one (s_rtbuf_gtk_connection **head,
+ s_rtbuf_gtk_connection *item)
+{
+ s_rtbuf_gtk_connection **next = head;
+ while (*next && *next != item)
+ next = &(*next)->next;
+ if (*next == item) {
+ *next = item->next;
+ return 1;
+ }
+ return 0;
+}
diff --git a/rtbuf_gtk_connection.h b/rtbuf_gtk_connection.h
index ea348b5..b2856d1 100644
--- a/rtbuf_gtk_connection.h
+++ b/rtbuf_gtk_connection.h
@@ -16,4 +16,9 @@ void rtbuf_gtk_connection_init ();
s_rtbuf_gtk_connection * rtbuf_gtk_connection_new ();
void rtbuf_gtk_connection_delete (s_rtbuf_gtk_connection *connection);
+void rtbuf_gtk_connection_push (s_rtbuf_gtk_connection **head,
+ s_rtbuf_gtk_connection *item);
+int rtbuf_gtk_connection_remove_one (s_rtbuf_gtk_connection **head,
+ s_rtbuf_gtk_connection *item);
+
#endif
diff --git a/rtbuf_gtk_output.c b/rtbuf_gtk_output.c
index 6250c0a..9dac2fd 100644
--- a/rtbuf_gtk_output.c
+++ b/rtbuf_gtk_output.c
@@ -79,14 +79,8 @@ void rtbuf_gtk_output_drag (RtbufOutputWidget *widget,
return;
}
connection->output_widget = widget;
- connection->next = modular_connections;
- modular_connections = connection;
- gtk_drag_begin_with_coordinates(GTK_WIDGET(widget),
- rtbuf_gtk_output_target_list,
- GDK_ACTION_DEFAULT,
- event->button,
- (GdkEvent*) event,
- -1, -1);
+ rtbuf_gtk_connection_push(&modular_connections, connection);
+ drag_connection = connection;
}
gboolean rtbuf_gtk_output_check_button_press (RtbufOutputWidget *widget,
diff --git a/rtbuf_input_widget.c b/rtbuf_input_widget.c
index 88cd869..990ea02 100644
--- a/rtbuf_input_widget.c
+++ b/rtbuf_input_widget.c
@@ -208,6 +208,14 @@ rtbuf_input_widget_update (RtbufInputWidget *widget)
}
}
+void rtbuf_input_widget_connect (GtkWidget *widget,
+ gpointer data)
+{
+ s_signal_binding *sb = (s_signal_binding*) data;
+ g_signal_connect(G_OBJECT(widget), sb->signal,
+ sb->callback, NULL);
+}
+
void rtbuf_input_widget_connect_check (GtkWidget *input,
gpointer data)
{
diff --git a/rtbuf_input_widget.h b/rtbuf_input_widget.h
index 83cbd76..887fba7 100644
--- a/rtbuf_input_widget.h
+++ b/rtbuf_input_widget.h
@@ -59,6 +59,8 @@ s_rtbuf * rtbuf_input_widget_get_rtbuf (RtbufInputWidget *widget);
unsigned int rtbuf_input_widget_get_in (RtbufInputWidget *widget);
GtkWidget * rtbuf_input_widget_get_check (RtbufInputWidget *widget);
void rtbuf_input_widget_update (RtbufInputWidget *widget);
+void rtbuf_input_widget_connect (GtkWidget *input,
+ gpointer data);
void rtbuf_input_widget_connect_check (GtkWidget *input,
gpointer data);
diff --git a/rtbuf_input_widget.ui b/rtbuf_input_widget.ui
index fbc2558..e667276 100644
--- a/rtbuf_input_widget.ui
+++ b/rtbuf_input_widget.ui
@@ -5,6 +5,7 @@
<template class="RtbufInputWidget" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK</property>
<child>
<object class="GtkCheckButton" id="check">
<property name="visible">True</property>
diff --git a/rtbuf_widget.c b/rtbuf_widget.c
index bf8b091..9b2629d 100644
--- a/rtbuf_widget.c
+++ b/rtbuf_widget.c
@@ -252,6 +252,18 @@ rtbuf_widget_get_rtbuf (RtbufWidget *widget)
return NULL;
}
+void rtbuf_widget_connect_inputs (RtbufWidget *widget,
+ const char *signal,
+ GCallback callback)
+{
+ RtbufWidgetPrivate *priv =
+ rtbuf_widget_get_instance_private(widget);
+ s_signal_binding sb = { signal, callback };
+ gtk_container_foreach(GTK_CONTAINER(priv->inputs),
+ rtbuf_input_widget_connect,
+ &sb);
+}
+
void rtbuf_widget_connect_input_checks (RtbufWidget *widget,
const char *signal,
GCallback callback)
diff --git a/rtbuf_widget.h b/rtbuf_widget.h
index bd02d82..2e36a7d 100644
--- a/rtbuf_widget.h
+++ b/rtbuf_widget.h
@@ -61,6 +61,9 @@ void rtbuf_widget_set_label (RtbufWidget *widget,
const gchar * rtbuf_widget_get_label (RtbufWidget *widget);
GtkWidget * rtbuf_widget_get_event_box (RtbufWidget *widget);
s_rtbuf * rtbuf_widget_get_rtbuf (RtbufWidget *widget);
+void rtbuf_widget_connect_inputs (RtbufWidget *widget,
+ const char *signal,
+ GCallback callback);
void rtbuf_widget_connect_input_checks (RtbufWidget *widget,
const char *signal,
GCallback callback);