[gimp] libgimp: new gimp_procedure_dialog_set_sensitive().



commit 3f09030b0370ef3edaf790066f97746ce1fcd6b3
Author: Jehan <jehan girinstud io>
Date:   Tue Apr 6 20:10:46 2021 +0200

    libgimp: new gimp_procedure_dialog_set_sensitive().
    
    New function to set some procedure dialog's widget sensitive, either
    with a constant value, or by binding it to a boolean property (or its
    inverse) of a config object.

 libgimp/gimpproceduredialog.c | 148 ++++++++++++++++++++++++++++++++++++++++--
 libgimp/gimpproceduredialog.h |   7 ++
 libgimp/gimpui.def            |   1 +
 3 files changed, 150 insertions(+), 6 deletions(-)
---
diff --git a/libgimp/gimpproceduredialog.c b/libgimp/gimpproceduredialog.c
index 3e64384bf1..45f2926d24 100644
--- a/libgimp/gimpproceduredialog.c
+++ b/libgimp/gimpproceduredialog.c
@@ -58,8 +58,19 @@ struct _GimpProcedureDialogPrivate
   GHashTable          *mnemonics;
   GHashTable          *core_mnemonics;
   GtkSizeGroup        *label_group;
+
+  GHashTable          *sensitive_data;
 };
 
+typedef struct GimpProcedureDialogSensitiveData
+{
+  gboolean  sensitive;
+
+  GObject  *config;
+  gchar    *config_property;
+  gboolean  config_invert;
+} GimpProcedureDialogSensitiveData;
+
 
 static void   gimp_procedure_dialog_constructed   (GObject      *object);
 static void   gimp_procedure_dialog_dispose       (GObject      *object);
@@ -96,6 +107,9 @@ static GtkWidget *
                                                          GtkContainer        *container,
                                                          GList               *properties);
 
+static void   gimp_procedure_dialog_sensitive_data_free (GimpProcedureDialogSensitiveData *data);
+
+
 G_DEFINE_TYPE_WITH_PRIVATE (GimpProcedureDialog, gimp_procedure_dialog,
                             GIMP_TYPE_DIALOG)
 
@@ -140,10 +154,12 @@ gimp_procedure_dialog_init (GimpProcedureDialog *dialog)
 {
   dialog->priv = gimp_procedure_dialog_get_instance_private (dialog);
 
-  dialog->priv->widgets     = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-  dialog->priv->mnemonics   = g_hash_table_new_full (g_direct_hash, NULL, NULL, g_free);
+  dialog->priv->widgets        = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+  dialog->priv->mnemonics      = g_hash_table_new_full (g_direct_hash, NULL, NULL, g_free);
   dialog->priv->core_mnemonics = g_hash_table_new_full (g_direct_hash, NULL, NULL, g_free);
-  dialog->priv->label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  dialog->priv->label_group    = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+  dialog->priv->sensitive_data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+                                                        (GDestroyNotify) 
gimp_procedure_dialog_sensitive_data_free);
 }
 
 static void
@@ -274,6 +290,8 @@ gimp_procedure_dialog_dispose (GObject *object)
   g_clear_pointer (&dialog->priv->mnemonics, g_hash_table_destroy);
   g_clear_pointer (&dialog->priv->core_mnemonics, g_hash_table_destroy);
 
+  g_clear_pointer (&dialog->priv->sensitive_data, g_hash_table_destroy);
+
   g_clear_object (&dialog->priv->label_group);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
@@ -458,9 +476,10 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
                                   const gchar         *property,
                                   GType                widget_type)
 {
-  GtkWidget  *widget = NULL;
-  GtkWidget  *label  = NULL;
-  GParamSpec *pspec;
+  GtkWidget                        *widget = NULL;
+  GtkWidget                        *label  = NULL;
+  GimpProcedureDialogSensitiveData *binding;
+  GParamSpec                       *pspec;
 
   g_return_val_if_fail (property != NULL, NULL);
 
@@ -583,6 +602,23 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
       gtk_size_group_add_widget (dialog->priv->label_group, label);
     }
 
+  if ((binding = g_hash_table_lookup (dialog->priv->sensitive_data, property)))
+    {
+      if (binding->config)
+        {
+          g_object_bind_property (binding->config, binding->config_property,
+                                  widget, "sensitive",
+                                  G_BINDING_SYNC_CREATE |
+                                  (binding->config_invert ? G_BINDING_INVERT_BOOLEAN : 0));
+        }
+      else
+        {
+          gtk_widget_set_sensitive (widget, binding->sensitive);
+        }
+
+      g_hash_table_remove (dialog->priv->sensitive_data, property);
+    }
+
   gimp_procedure_dialog_check_mnemonic (dialog, widget, property, NULL);
   g_hash_table_insert (dialog->priv->widgets, g_strdup (property), widget);
 
@@ -1181,6 +1217,97 @@ gimp_procedure_dialog_fill_frame (GimpProcedureDialog *dialog,
   return frame;
 }
 
+
+/**
+ * gimp_procedure_dialog_set_sensitive:
+ * @dialog:          the #GimpProcedureDialog.
+ * @property:        name of a property of the #GimpProcedure @dialog
+ *                   has been created for.
+ * @sensitive:       whether the widget associated to @property should
+ *                   be sensitive.
+ * @config:          (nullable): an optional config object.
+ * @config_property: (nullable): name of a property of @config.
+ * @config_invert:   whether to negate the value of @config_property.
+ *
+ * Sets sensitivity of the widget associated to @property in @dialog. If
+ * @config is %NULL, then it is set to the value of @sensitive.
+ * Otherwise @sensitive is ignored and sensitivity is bound to the value
+ * of @config_property of @config (or the negation of this value
+ * if @config_reverse is %TRUE).
+ */
+void
+gimp_procedure_dialog_set_sensitive (GimpProcedureDialog *dialog,
+                                     const gchar         *property,
+                                     gboolean             sensitive,
+                                     GObject             *config,
+                                     const gchar         *config_property,
+                                     gboolean             config_invert)
+{
+  GtkWidget  *widget = NULL;
+  GParamSpec *pspec;
+
+  g_return_if_fail (GIMP_IS_PROCEDURE_DIALOG (dialog));
+  g_return_if_fail (property != NULL);
+  g_return_if_fail (config == NULL || config_property != NULL);
+
+  widget = g_hash_table_lookup (dialog->priv->widgets, property);
+
+  if (! widget)
+    {
+      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (dialog->priv->config),
+                                            property);
+      if (! pspec)
+        {
+          g_warning ("%s: parameter %s does not exist on the GimpProcedure.",
+                     G_STRFUNC, property);
+          return;
+        }
+    }
+
+  if (config)
+    {
+      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
+                                            config_property);
+      if (! pspec)
+        {
+          g_warning ("%s: parameter %s does not exist on the config object.",
+                     G_STRFUNC, config_property);
+          return;
+        }
+    }
+
+  if (widget)
+    {
+      if (config)
+        {
+          g_object_bind_property (config, config_property,
+                                  widget, "sensitive",
+                                  G_BINDING_SYNC_CREATE | (config_invert ? G_BINDING_INVERT_BOOLEAN : 0));
+        }
+      else
+        {
+          gtk_widget_set_sensitive (widget, sensitive);
+        }
+    }
+  else
+    {
+      /* Set for later creation. */
+      GimpProcedureDialogSensitiveData *data;
+
+      data = g_slice_new0 (GimpProcedureDialogSensitiveData);
+
+      data->sensitive = sensitive;
+      if (config)
+        {
+          data->config          = g_object_ref (config);
+          data->config_property = g_strdup (config_property);
+          data->config_invert   = config_invert;
+        }
+
+      g_hash_table_insert (dialog->priv->sensitive_data, g_strdup (property), data);
+    }
+}
+
 /**
  * gimp_procedure_dialog_run:
  * @dialog: the #GimpProcedureDialog.
@@ -1484,3 +1611,12 @@ gimp_procedure_dialog_fill_container_list (GimpProcedureDialog *dialog,
 
   return GTK_WIDGET (container);
 }
+
+static void
+gimp_procedure_dialog_sensitive_data_free (GimpProcedureDialogSensitiveData *data)
+{
+  g_free (data->config_property);
+  g_clear_object (&data->config);
+
+  g_slice_free (GimpProcedureDialogSensitiveData, data);
+}
diff --git a/libgimp/gimpproceduredialog.h b/libgimp/gimpproceduredialog.h
index c0e6b996df..45253fab39 100644
--- a/libgimp/gimpproceduredialog.h
+++ b/libgimp/gimpproceduredialog.h
@@ -114,6 +114,13 @@ void        gimp_procedure_dialog_fill              (GimpProcedureDialog *dialog
 void        gimp_procedure_dialog_fill_list         (GimpProcedureDialog *dialog,
                                                      GList               *properties);
 
+void        gimp_procedure_dialog_set_sensitive     (GimpProcedureDialog *dialog,
+                                                     const gchar         *property,
+                                                     gboolean             sensitive,
+                                                     GObject             *config,
+                                                     const gchar         *config_property,
+                                                     gboolean             config_invert);
+
 gboolean    gimp_procedure_dialog_run               (GimpProcedureDialog *dialog);
 
 
diff --git a/libgimp/gimpui.def b/libgimp/gimpui.def
index bda7bb9104..ad280c4ee3 100644
--- a/libgimp/gimpui.def
+++ b/libgimp/gimpui.def
@@ -53,6 +53,7 @@ EXPORTS
        gimp_procedure_dialog_get_widget
        gimp_procedure_dialog_new
        gimp_procedure_dialog_run
+       gimp_procedure_dialog_set_sensitive
        gimp_progress_bar_get_type
        gimp_progress_bar_new
        gimp_save_procedure_dialog_add_metadata


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