[gtk/wip/otte/listview: 111/169] bindings: Add gtk_binding_entry_add_callback()



commit a1a70a1130a45a00767bddb000d550eca23ec3c4
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 15 05:50:52 2019 +0200

    bindings: Add gtk_binding_entry_add_callback()
    
    This allows bindings that have no public API.

 docs/reference/gtk/gtk4-sections.txt |   1 +
 gtk/gtkbindings.c                    | 133 ++++++++++++++++++++++++++---------
 gtk/gtkbindings.h                    |   9 +++
 3 files changed, 109 insertions(+), 34 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 2ad5b92fcc..faf10c5525 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -5249,6 +5249,7 @@ gtk_bindings_activate_event
 gtk_binding_set_activate
 gtk_binding_entry_add_action
 gtk_binding_entry_add_action_variant
+gtk_binding_entry_add_callback
 gtk_binding_entry_add_signal
 gtk_binding_entry_add_signal_from_string
 gtk_binding_entry_skip
diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c
index 59c1815772..49acdc661d 100644
--- a/gtk/gtkbindings.c
+++ b/gtk/gtkbindings.c
@@ -141,7 +141,8 @@ struct _GtkBindingArg
 typedef enum 
 {
   GTK_BINDING_SIGNAL,
-  GTK_BINDING_ACTION
+  GTK_BINDING_ACTION,
+  GTK_BINDING_CALLBACK
 } GtkBindingActionType;
 
 /**
@@ -166,6 +167,11 @@ struct _GtkBindingSignal
       GtkBindingArg    *args;
     };
     GVariant           *variant;
+    struct {
+      GtkCallback       callback;
+      gpointer          user_data;
+      GDestroyNotify    user_destroy;
+    } callback;
   };
 };
 
@@ -212,6 +218,23 @@ binding_signal_new_action (const gchar *signal_name,
   return signal;
 }
 
+static GtkBindingSignal *
+binding_signal_new_callback (GtkCallback    callback,
+                             gpointer       user_data,
+                             GDestroyNotify user_destroy)
+{
+  GtkBindingSignal *signal;
+
+  signal = g_slice_new0 (GtkBindingSignal);
+  signal->next = NULL;
+  signal->action_type = GTK_BINDING_CALLBACK;
+  signal->callback.callback = callback;
+  signal->callback.user_data = user_data;
+  signal->callback.user_destroy = user_destroy;
+
+  return signal;
+}
+
 static void
 binding_signal_free (GtkBindingSignal *sig)
 {
@@ -233,6 +256,12 @@ binding_signal_free (GtkBindingSignal *sig)
       g_slice_free (GtkBindingSignal, sig);
       break;
 
+    case GTK_BINDING_CALLBACK:
+      if (sig->callback.user_destroy)
+        sig->callback.user_destroy (sig->callback.user_data);
+      g_slice_free (GtkBindingSignal, sig);
+      break;
+
     default:
       g_assert_not_reached ();
       break;
@@ -694,6 +723,23 @@ binding_signal_activate_action (GtkBindingSignal *sig,
   return TRUE;
 }
 
+static gboolean
+binding_signal_activate_callback (GtkBindingSignal *sig,
+                                  GObject          *object)
+{
+  if (!GTK_IS_WIDGET (object))
+    {
+      g_warning ("gtk_binding_entry_activate(): "
+                 "callbacks must be run on GtkWidget subtypes, %s is not supported",
+                 G_OBJECT_TYPE_NAME (object));
+      return FALSE;
+    }
+
+  sig->callback.callback (GTK_WIDGET (object), sig->callback.user_data);
+
+  return TRUE;
+}
+
 static gboolean
 gtk_binding_entry_activate (GtkBindingEntry *entry,
                             GObject         *object)
@@ -719,6 +765,10 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
           handled = binding_signal_activate_action (sig, object);
           break;
 
+        case GTK_BINDING_CALLBACK:
+          handled = binding_signal_activate_callback (sig, object);
+          break;
+
         default:
           g_assert_not_reached ();
           break;
@@ -938,6 +988,30 @@ gtk_binding_entry_remove (GtkBindingSet  *binding_set,
     binding_entry_destroy (entry);
 }
 
+static void
+gtk_binding_entry_add_binding_signal (GtkBindingSet    *binding_set,
+                                      guint             keyval,
+                                      GdkModifierType   modifiers,
+                                      GtkBindingSignal *signal)
+{
+  GtkBindingEntry *entry;
+  GtkBindingSignal **signal_p;
+
+  keyval = gdk_keyval_to_lower (keyval);
+  modifiers = modifiers & BINDING_MOD_MASK ();
+
+  entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
+  if (!entry)
+    {
+      gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
+      entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
+    }
+  signal_p = &entry->signals;
+  while (*signal_p)
+    signal_p = &(*signal_p)->next;
+  *signal_p = signal;
+}
+
 /*
  * gtk_binding_entry_add_signall:
  * @binding_set:  a #GtkBindingSet to add a signal to
@@ -957,8 +1031,7 @@ gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
                                const gchar    *signal_name,
                                GSList         *binding_args)
 {
-  GtkBindingEntry *entry;
-  GtkBindingSignal *signal, **signal_p;
+  GtkBindingSignal *signal;
   GSList *slist;
   guint n = 0;
   GtkBindingArg *arg;
@@ -966,9 +1039,6 @@ gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
   g_return_if_fail (binding_set != NULL);
   g_return_if_fail (signal_name != NULL);
 
-  keyval = gdk_keyval_to_lower (keyval);
-  modifiers = modifiers & BINDING_MOD_MASK ();
-
   signal = binding_signal_new_signal (signal_name, g_slist_length (binding_args));
 
   arg = signal->args;
@@ -1013,16 +1083,7 @@ gtk_binding_entry_add_signall (GtkBindingSet  *binding_set,
       n++;
     }
 
-  entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
-  if (!entry)
-    {
-      gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
-      entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
-    }
-  signal_p = &entry->signals;
-  while (*signal_p)
-    signal_p = &(*signal_p)->next;
-  *signal_p = signal;
+  gtk_binding_entry_add_binding_signal (binding_set, keyval, modifiers, signal);
 }
 
 /**
@@ -1159,27 +1220,13 @@ gtk_binding_entry_add_action_variant (GtkBindingSet  *binding_set,
                                       const gchar    *action_name,
                                       GVariant       *args)
 {
-  GtkBindingEntry *entry;
-  GtkBindingSignal *signal, **signal_p;
-
   g_return_if_fail (binding_set != NULL);
   g_return_if_fail (action_name != NULL);
 
-  keyval = gdk_keyval_to_lower (keyval);
-  modifiers = modifiers & BINDING_MOD_MASK ();
-
-  signal = binding_signal_new_action (action_name, args);
-
-  entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
-  if (!entry)
-    {
-      gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
-      entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
-    }
-  signal_p = &entry->signals;
-  while (*signal_p)
-    signal_p = &(*signal_p)->next;
-  *signal_p = signal;
+  gtk_binding_entry_add_binding_signal (binding_set,
+                                        keyval,
+                                        modifiers,
+                                        binding_signal_new_action (action_name, args));
 }
 
 /**
@@ -1226,6 +1273,24 @@ gtk_binding_entry_add_action (GtkBindingSet  *binding_set,
   g_clear_pointer (&parameters, g_variant_unref);
 }
 
+void
+gtk_binding_entry_add_callback (GtkBindingSet   *binding_set,
+                                guint            keyval,
+                                GdkModifierType  modifiers,
+                                GtkCallback      callback,
+                                gpointer         user_data,
+                                GDestroyNotify   user_destroy)
+{
+  g_return_if_fail (binding_set != NULL);
+  g_return_if_fail (callback != NULL);
+
+  gtk_binding_entry_add_binding_signal (binding_set,
+                                        keyval,
+                                        modifiers,
+                                        binding_signal_new_callback (callback, user_data, user_destroy));
+
+}
+
 static guint
 gtk_binding_parse_signal (GScanner       *scanner,
                           GtkBindingSet  *binding_set,
diff --git a/gtk/gtkbindings.h b/gtk/gtkbindings.h
index 5f2b019006..9d68ce301e 100644
--- a/gtk/gtkbindings.h
+++ b/gtk/gtkbindings.h
@@ -35,6 +35,7 @@
 
 #include <gdk/gdk.h>
 #include <gtk/gtkenums.h>
+#include <gtk/gtkwidget.h>
 
 G_BEGIN_DECLS
 
@@ -91,6 +92,14 @@ void           gtk_binding_entry_add_action  (GtkBindingSet       *binding_set,
                                               const char          *format_string,
                                               ...);
 
+GDK_AVAILABLE_IN_ALL
+void           gtk_binding_entry_add_callback(GtkBindingSet       *binding_set,
+                                              guint                keyval,
+                                              GdkModifierType      modifiers,
+                                              GtkCallback          callback,
+                                              gpointer             user_data,
+                                              GDestroyNotify       user_destroy);
+
 GDK_AVAILABLE_IN_ALL
 void           gtk_binding_entry_remove      (GtkBindingSet       *binding_set,
                                               guint                keyval,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]