[gtk/shortcuts-rebased-again: 111/171] Add gtk_widget_class_bind_action



commit 79c539869096c68100178fc92f647bf3ef473113
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jun 19 01:32:05 2019 +0000

    Add gtk_widget_class_bind_action
    
    Similar to gtk_widget_class_add_binding_signal,
    but triggers an action.

 docs/reference/gtk/gtk4-sections.txt |  1 +
 gtk/gtkwidget.c                      | 97 ++++++++++++++++++++++++++++++++++++
 gtk/gtkwidget.h                      |  8 +++
 3 files changed, 106 insertions(+)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 82e15bb6a3..4058f9a787 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4369,6 +4369,7 @@ gtk_widget_allocate
 gtk_widget_class_add_shortcut
 gtk_widget_class_add_binding
 gtk_widget_class_add_binding_signal
+gtk_widget_class_bind_action
 gtk_widget_can_activate_accel
 gtk_widget_event
 gtk_widget_activate
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 5e0af7b417..bf8724976a 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4916,6 +4916,103 @@ gtk_widget_class_add_binding_signal (GtkWidgetClass  *widget_class,
   g_object_unref (shortcut);
 }
 
+/**
+ * gtk_widget_class_bind_action: (skip)
+ * @widget_class: the class to add the binding to
+ * @keyval: key value of binding to install
+ * @mods: key modifier of binding to install
+ * @action_name: the name of the action to activate
+ * @format_string: GVariant format string for arguments or %NULL for
+ *     no arguments
+ * @...: arguments, as given by format string.
+ *
+ * Creates a new shortcut for @widget_class that activates the
+ * given action @action_name with arguments read according to
+ * @format_string. The arguments and format string must be provided
+ * in the same way as with g_variant_new().
+ *
+ * This function is a convenience wrapper around
+ * gtk_widget_class_add_shortcut() and must be called during class
+ * initialization.
+ **/
+void
+gtk_widget_class_bind_action (GtkWidgetClass  *widget_class,
+                              guint            keyval,
+                              GdkModifierType  mods,
+                              const gchar     *action_name,
+                              const gchar     *format_string,
+                              ...)
+{
+  GtkWidgetClassPrivate *priv = widget_class->priv;
+  gboolean found = FALSE;
+  GVariantType *type = NULL;
+  GVariant *parameters = NULL;
+  GtkShortcut *shortcut;
+
+  g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
+
+  if (priv->actions)
+    {
+      int i;
+      for (i = 0; i < priv->actions->len; i++)
+        {
+          GtkWidgetAction *action = g_ptr_array_index (priv->actions, i);
+          if (strcmp (action->name, action_name) == 0)
+            {
+              type = action->parameter_type;
+              found = TRUE;
+              break;
+            }
+        }
+    }
+
+  /* We don't error out if !found here, since it makes
+   * sense to install shortcuts for actions that you
+   * expect on your parent. We just can't verify the
+   * parameters in this case.
+   */
+
+  if (format_string != NULL)
+    {
+      va_list args;
+
+      va_start (args, format_string);
+      parameters = g_variant_new_va (format_string, NULL, &args);
+      va_end (args);
+    }
+
+  if (found && parameters != NULL)
+    {
+      if (type == NULL)
+        {
+          g_warning ("Widget action %s does not accept parameters", action_name);
+          g_variant_unref (parameters);
+          return;
+        }
+      else if (!g_variant_is_of_type (parameters, type))
+        {
+          g_warning ("Parameters don't match expected type for widget action %s", action_name);
+          g_variant_unref (parameters);
+          return;
+        }
+    }
+  else if (type != NULL)
+    {
+      g_warning ("Widget action %s requires parameters", action_name);
+      return;
+    }
+
+  shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (keyval, mods),
+                               gtk_action_action_new (action_name));
+
+  if (parameters)
+    gtk_shortcut_set_arguments (shortcut, parameters);
+
+  gtk_widget_class_add_shortcut (widget_class, shortcut);
+
+  g_object_unref (shortcut);
+}
+
 /**
  * gtk_widget_class_add_shortcut:
  * @widget_class: the class to add the shortcut to
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 05be13b42c..8651001b0f 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -438,6 +438,14 @@ void       gtk_widget_class_add_binding_signal
                                            const gchar         *format_string,
                                            ...);
 
+GDK_AVAILABLE_IN_ALL
+void       gtk_widget_class_bind_action   (GtkWidgetClass      *widget_class,
+                                           guint                keyval,
+                                           GdkModifierType      mods,
+                                           const gchar         *action_name,
+                                           const gchar         *format_string,
+                                           ...);
+
 GDK_AVAILABLE_IN_ALL
 void       gtk_widget_class_add_shortcut  (GtkWidgetClass      *widget_class,
                                            GtkShortcut         *shortcut);


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