gimp r24809 - in trunk: . app/tools app/widgets



Author: mitch
Date: Tue Feb  5 13:20:11 2008
New Revision: 24809
URL: http://svn.gnome.org/viewvc/gimp?rev=24809&view=rev

Log:
2008-02-05  Michael Natterer  <mitch gimp org>

	* app/widgets/gimppropwidgets.[ch] (gimp_prop_table_new): new
	function which creates a table of prop widgets for all properties
	of an object (pretty incomplete, does exactly what's needed in
	GimpGeglTool, or even less).

	* app/tools/gimpgegltool.c: create a proxy config class for each
	GegÄOperation and create a prop table on the config class'
	properties as GUI for the GEGL operation. Write the proxy object's
	properties back to the GeglNode in map().



Modified:
   trunk/ChangeLog
   trunk/app/tools/gimpgegltool.c
   trunk/app/widgets/gimppropwidgets.c
   trunk/app/widgets/gimppropwidgets.h

Modified: trunk/app/tools/gimpgegltool.c
==============================================================================
--- trunk/app/tools/gimpgegltool.c	(original)
+++ trunk/app/tools/gimpgegltool.c	Tue Feb  5 13:20:11 2008
@@ -18,9 +18,13 @@
 
 #include "config.h"
 
+#include <string.h>
+
 #include <gegl.h>
+#include <gegl-plugin.h> /* temp hack for color pspec */
 #include <gtk/gtk.h>
 
+#include "libgimpcolor/gimpcolor.h"
 #include "libgimpconfig/gimpconfig.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
@@ -29,6 +33,8 @@
 #include "core/gimpdrawable.h"
 #include "core/gimpimage.h"
 
+#include "widgets/gimppropwidgets.h"
+
 #include "display/gimpdisplay.h"
 
 #include "gimpgegltool.h"
@@ -172,15 +178,42 @@
 
   for (i = 0; i < n_pspecs; i++)
     {
-      GParamSpec *pspec = pspecs[i];
-      GValue      value = { 0, };
+      GParamSpec *gegl_pspec = pspecs[i];
+      GParamSpec *gimp_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (tool->config),
+                                                             gegl_pspec->name);
+
+      if (gimp_pspec)
+        {
+          GValue value = { 0, };
+
+          g_value_init (&value, gimp_pspec->value_type);
+
+          g_object_get_property (G_OBJECT (tool->config), gimp_pspec->name,
+                                 &value);
+
+          if (GIMP_IS_PARAM_SPEC_RGB (gimp_pspec))
+            {
+              GeglColor *gegl_color = gegl_color_new (NULL);
+              GimpRGB    gimp_color;
+
+              gimp_value_get_rgb (&value, &gimp_color);
+              g_value_unset (&value);
+
+              gegl_color_set_rgba (gegl_color,
+                                   gimp_color.r,
+                                   gimp_color.g,
+                                   gimp_color.b,
+                                   gimp_color.a);
+
+              g_value_init (&value, gegl_pspec->value_type);
+              g_value_take_object (&value, gegl_color);
+            }
 
-      g_value_init (&value, pspec->value_type);
+          gegl_node_set_property (image_map_tool->operation, gegl_pspec->name,
+                                  &value);
 
-      g_object_get_property (G_OBJECT (tool->config), pspec->name, &value);
-      gegl_node_set_property (image_map_tool->operation, pspec->name, &value);
-
-      g_value_unset (&value);
+          g_value_unset (&value);
+        }
     }
 
   g_free (pspecs);
@@ -267,23 +300,278 @@
   gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 }
 
-static GimpObject *
-gimp_gegl_tool_get_config (GimpGeglTool *tool)
+static GParamSpec *
+gimp_param_spec_duplicate (GParamSpec *pspec)
+{
+  if (G_IS_PARAM_SPEC_STRING (pspec))
+    {
+      GParamSpecString *spec = G_PARAM_SPEC_STRING (pspec);
+
+      return g_param_spec_string (pspec->name,
+                                  g_param_spec_get_nick (pspec),
+                                  g_param_spec_get_blurb (pspec),
+                                  spec->default_value,
+                                  pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
+    {
+      GParamSpecBoolean *spec = G_PARAM_SPEC_BOOLEAN (pspec);
+
+      return g_param_spec_boolean (pspec->name,
+                                   g_param_spec_get_nick (pspec),
+                                   g_param_spec_get_blurb (pspec),
+                                   spec->default_value,
+                                   pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_DOUBLE (pspec))
+    {
+      GParamSpecDouble *spec = G_PARAM_SPEC_DOUBLE (pspec);
+
+      return g_param_spec_double (pspec->name,
+                                  g_param_spec_get_nick (pspec),
+                                  g_param_spec_get_blurb (pspec),
+                                  spec->minimum,
+                                  spec->maximum,
+                                  spec->default_value,
+                                  pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_FLOAT (pspec))
+    {
+      GParamSpecFloat *spec = G_PARAM_SPEC_FLOAT (pspec);
+
+      return g_param_spec_float (pspec->name,
+                                 g_param_spec_get_nick (pspec),
+                                 g_param_spec_get_blurb (pspec),
+                                 spec->minimum,
+                                 spec->maximum,
+                                 spec->default_value,
+                                 pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_INT (pspec))
+    {
+      GParamSpecInt *spec = G_PARAM_SPEC_INT (pspec);
+
+      return g_param_spec_int (pspec->name,
+                               g_param_spec_get_nick (pspec),
+                               g_param_spec_get_blurb (pspec),
+                               spec->minimum,
+                               spec->maximum,
+                               spec->default_value,
+                               pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_UINT (pspec))
+    {
+      GParamSpecUInt *spec = G_PARAM_SPEC_UINT (pspec);
+
+      return g_param_spec_uint (pspec->name,
+                                g_param_spec_get_nick (pspec),
+                                g_param_spec_get_blurb (pspec),
+                                spec->minimum,
+                                spec->maximum,
+                                spec->default_value,
+                                pspec->flags);
+    }
+  else if (GEGL_IS_PARAM_SPEC_COLOR (pspec))
+    {
+      GeglColor *gegl_color;
+      GimpRGB    gimp_color;
+      gfloat     r = 0.0;
+      gfloat     g = 0.0;
+      gfloat     b = 0.0;
+      gfloat     a = 1.0;
+      GValue     value = { 0, };
+
+      g_value_init (&value, GEGL_TYPE_COLOR);
+      g_param_value_set_default (pspec, &value);
+
+      gegl_color = g_value_get_object (&value);
+      if (gegl_color)
+        gegl_color_get_rgba (gegl_color, &r, &g, &b, &a);
+
+      gimp_rgba_set (&gimp_color, r, g, b, a);
+
+      g_value_unset (&value);
+
+      return gimp_param_spec_rgb (pspec->name,
+                                  g_param_spec_get_nick (pspec),
+                                  g_param_spec_get_blurb (pspec),
+                                  TRUE,
+                                  &gimp_color,
+                                  pspec->flags);
+    }
+  else if (G_IS_PARAM_SPEC_OBJECT (pspec) ||
+           G_IS_PARAM_SPEC_POINTER (pspec))
+    {
+      /*  ignore object properties  */
+      return NULL;
+    }
+
+  g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
+             g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
+
+  return NULL;
+}
+
+static void
+gimp_gegl_tool_config_value_free (GValue *value)
+{
+  g_value_unset (value);
+  g_free (value);
+}
+
+static GHashTable *
+gimp_gegl_tool_config_get_properties (GObject *object)
+{
+  GHashTable *properties = g_object_get_data (object, "properties");
+
+  if (! properties)
+    {
+      properties = g_hash_table_new_full (g_str_hash,
+                                          g_str_equal,
+                                          (GDestroyNotify) g_free,
+                                          (GDestroyNotify) gimp_gegl_tool_config_value_free);
+
+      g_object_set_data_full (object, "properties", properties,
+                              (GDestroyNotify) g_hash_table_unref);
+    }
+
+  return properties;
+}
+
+static void
+gimp_gegl_tool_config_set_property (GObject      *object,
+                                    guint         property_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GHashTable *properties = gimp_gegl_tool_config_get_properties (object);
+  GValue     *val;
+
+  val = g_hash_table_lookup (properties, pspec->name);
+
+  if (! val)
+    {
+      val = g_new0 (GValue, 1);
+      g_hash_table_insert (properties, g_strdup (pspec->name), val);
+
+      g_value_init (val, pspec->value_type);
+    }
+
+  g_value_copy (value, val);
+}
+
+static void
+gimp_gegl_tool_config_get_property (GObject    *object,
+                                    guint       property_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  GHashTable *properties = gimp_gegl_tool_config_get_properties (object);
+  GValue     *val;
+
+  val = g_hash_table_lookup (properties, pspec->name);
+
+  if (! val)
+    {
+      val = g_new0 (GValue, 1);
+      g_hash_table_insert (properties, g_strdup (pspec->name), val);
+
+      g_value_init (val, pspec->value_type);
+      g_param_value_set_default (pspec, val);
+    }
+
+  g_value_copy (val, value);
+}
+
+static void
+gimp_gegl_tool_config_class_init (GObjectClass *klass,
+                                  const gchar  *operation)
 {
   GParamSpec **pspecs;
   guint        n_pspecs;
   gint         i;
 
-  pspecs = gegl_list_properties (tool->operation, &n_pspecs);
+  klass->set_property = gimp_gegl_tool_config_set_property;
+  klass->get_property = gimp_gegl_tool_config_get_property;
+
+  pspecs = gegl_list_properties (operation, &n_pspecs);
 
   for (i = 0; i < n_pspecs; i++)
     {
-      g_print ("property: %s\n", pspecs[i]->name);
+      GParamSpec *pspec = pspecs[i];
+
+      if ((pspec->flags & G_PARAM_READABLE) &&
+          (pspec->flags & G_PARAM_WRITABLE) &&
+          strcmp (pspec->name, "input")     &&
+          strcmp (pspec->name, "output"))
+        {
+          GParamSpec *copy = gimp_param_spec_duplicate (pspec);
+
+          if (copy)
+            {
+              g_print ("installing property: %s\n", copy->name);
+
+              g_object_class_install_property (klass, i + 1, copy);
+            }
+        }
     }
 
   g_free (pspecs);
+}
 
-  return NULL;
+static GimpObject *
+gimp_gegl_tool_get_config (GimpGeglTool *tool)
+{
+  static GHashTable *config_types = NULL;
+  GType              config_type;
+
+  if (! config_types)
+    config_types = g_hash_table_new_full (g_str_hash,
+                                          g_str_equal,
+                                          (GDestroyNotify) g_free,
+                                          NULL);
+
+  config_type = (GType) g_hash_table_lookup (config_types, tool->operation);
+
+  if (! config_type)
+    {
+      const GTypeInfo info =
+      {
+        sizeof (GimpObjectClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gimp_gegl_tool_config_class_init,
+        NULL,           /* class_finalize */
+        tool->operation,
+        sizeof (GimpObject),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) NULL,
+      };
+
+      const GInterfaceInfo config_info =
+      {
+        NULL, /* interface_init     */
+        NULL, /* interface_finalize */
+        NULL  /* interface_data     */
+      };
+
+      gchar *type_name = g_strdup_printf ("GimpGeglTool-%s-config",
+                                          tool->operation);
+
+      config_type = g_type_register_static (GIMP_TYPE_OBJECT, type_name,
+                                            &info, 0);
+
+      g_free (type_name);
+
+      g_type_add_interface_static (config_type, GIMP_TYPE_CONFIG,
+                                   &config_info);
+
+      g_hash_table_insert (config_types,
+                           g_strdup (tool->operation),
+                           (gpointer) config_type);
+    }
+
+  return g_object_new (config_type, NULL);
 }
 
 static void
@@ -323,10 +611,27 @@
 
   tool->config = gimp_gegl_tool_get_config (tool);
 
+  if (tool->options_table)
+    {
+      gtk_container_remove (GTK_CONTAINER (tool->options_box),
+                            tool->options_table);
+      tool->options_table = NULL;
+    }
+
   if (tool->config)
-    g_signal_connect_object (tool->config, "notify",
-                             G_CALLBACK (gimp_gegl_tool_config_notify),
-                             G_OBJECT (tool), 0);
+    {
+      g_signal_connect_object (tool->config, "notify",
+                               G_CALLBACK (gimp_gegl_tool_config_notify),
+                               G_OBJECT (tool), 0);
+
+      tool->options_table =
+        gimp_prop_table_new (G_OBJECT (tool->config),
+                             G_TYPE_FROM_INSTANCE (tool->config),
+                             GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (tool)));
+      gtk_box_pack_start (GTK_BOX (tool->options_box), tool->options_table,
+                          FALSE, FALSE, 0);
+      gtk_widget_show (tool->options_table);
+    }
 
   gimp_image_map_tool_preview (GIMP_IMAGE_MAP_TOOL (tool));
 }

Modified: trunk/app/widgets/gimppropwidgets.c
==============================================================================
--- trunk/app/widgets/gimppropwidgets.c	(original)
+++ trunk/app/widgets/gimppropwidgets.c	Tue Feb  5 13:20:11 2008
@@ -35,6 +35,7 @@
 
 #include "widgets-types.h"
 
+#include "core/gimpcontext.h"
 #include "core/gimpviewable.h"
 
 #include "gimpcolorpanel.h"
@@ -713,6 +714,100 @@
 }
 
 
+/***********/
+/*  table  */
+/***********/
+
+GtkWidget *
+gimp_prop_table_new (GObject     *config,
+                     GType        owner_type,
+                     GimpContext *context)
+{
+  GtkWidget     *table;
+  GtkSizeGroup  *size_group;
+  GParamSpec   **param_specs;
+  guint          n_param_specs;
+  gint           i;
+  gint           row = 0;
+
+  g_return_val_if_fail (G_IS_OBJECT (config), NULL);
+  g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
+
+  param_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config),
+                                                &n_param_specs);
+
+  size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+  table = gtk_table_new (3, 1, FALSE);
+  gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+  gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+
+  for (i = 0; i < n_param_specs; i++)
+    {
+      GParamSpec  *pspec  = param_specs[i];
+      GtkWidget   *widget = NULL;
+      const gchar *label  = NULL;
+
+      /*  ignore properties of parent classes of owner_type  */
+      if (! g_type_is_a (pspec->owner_type, owner_type))
+        continue;
+
+      if (G_IS_PARAM_SPEC_STRING (pspec))
+        {
+          widget = gimp_prop_entry_new (config, pspec->name, -1);
+        }
+      else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
+        {
+          widget = gimp_prop_check_button_new (config, pspec->name,
+                                               g_param_spec_get_nick (pspec));
+        }
+      else if (G_IS_PARAM_SPEC_INT (pspec)   ||
+               G_IS_PARAM_SPEC_UINT (pspec)  ||
+               G_IS_PARAM_SPEC_FLOAT (pspec) ||
+               G_IS_PARAM_SPEC_DOUBLE (pspec))
+        {
+          GtkObject *adj;
+          gint       digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
+                               G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;
+
+          adj = gimp_prop_scale_entry_new (config, pspec->name,
+                                           GTK_TABLE (table), 0, row++,
+                                           g_param_spec_get_nick (pspec),
+                                           1.0, 1.0, digits,
+                                           FALSE, 0.0, 0.0);
+
+          gtk_size_group_add_widget (size_group,
+                                     GIMP_SCALE_ENTRY_SPINBUTTON (adj));
+        }
+      else if (GIMP_IS_PARAM_SPEC_RGB (pspec))
+        {
+          widget = gimp_prop_color_button_new (config, pspec->name,
+                                               g_param_spec_get_nick (pspec),
+                                               128, 24,
+                                               GIMP_COLOR_AREA_SMALL_CHECKS);
+          gimp_color_panel_set_context (GIMP_COLOR_PANEL (widget), context);
+          label = g_param_spec_get_nick (pspec);
+        }
+      else
+        {
+          g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
+                     g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
+        }
+
+      if (widget)
+        gimp_table_attach_aligned (GTK_TABLE (table), 0, row++,
+                                   label, 0.0, 0.5,
+                                   widget, 2, FALSE);
+    }
+
+  g_object_unref (size_group);
+
+  g_free (param_specs);
+
+  return table;
+}
+
+
 /*******************************/
 /*  private utility functions  */
 /*******************************/

Modified: trunk/app/widgets/gimppropwidgets.h
==============================================================================
--- trunk/app/widgets/gimppropwidgets.h	(original)
+++ trunk/app/widgets/gimppropwidgets.h	Tue Feb  5 13:20:11 2008
@@ -57,6 +57,7 @@
                                            GimpContext *context,
                                            gint         size);
 
+
 /*  GParamDouble, GParamDouble, GParamDouble, GParamDouble, GParamBoolean  */
 
 GtkWidget * gimp_prop_number_pair_entry_new
@@ -74,4 +75,11 @@
                                            gdouble      max_valid_value);
 
 
+/*  A view on all of an object's properties  */
+
+GtkWidget * gimp_prop_table_new           (GObject     *config,
+                                           GType        owner_type,
+                                           GimpContext *context);
+
+
 #endif /* __GIMP_APP_PROP_WIDGETS_H__ */



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