new function which creates a table of prop widgets for all properties of
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(). svn path=/trunk/; revision=24809
This commit is contained in:

committed by
Michael Natterer

parent
ed6d75cb52
commit
b4255ae3cd
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
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().
|
||||
|
||||
2008-02-05 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/display/gimpdisplayshell-transform.c: changed coordinate
|
||||
|
@ -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 @@ gimp_gegl_tool_map (GimpImageMapTool *image_map_tool)
|
||||
|
||||
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);
|
||||
|
||||
g_value_init (&value, pspec->value_type);
|
||||
if (gimp_pspec)
|
||||
{
|
||||
GValue value = { 0, };
|
||||
|
||||
g_object_get_property (G_OBJECT (tool->config), pspec->name, &value);
|
||||
gegl_node_set_property (image_map_tool->operation, pspec->name, &value);
|
||||
g_value_init (&value, gimp_pspec->value_type);
|
||||
|
||||
g_value_unset (&value);
|
||||
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);
|
||||
}
|
||||
|
||||
gegl_node_set_property (image_map_tool->operation, gegl_pspec->name,
|
||||
&value);
|
||||
|
||||
g_value_unset (&value);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (pspecs);
|
||||
@ -267,23 +300,278 @@ gimp_gegl_tool_config_notify (GObject *object,
|
||||
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 @@ gimp_gegl_tool_operation_changed (GtkWidget *widget,
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpviewable.h"
|
||||
|
||||
#include "gimpcolorpanel.h"
|
||||
@ -713,6 +714,100 @@ gimp_prop_number_pair_entry_number_pair_user_override_notify (GtkWidget
|
||||
}
|
||||
|
||||
|
||||
/***********/
|
||||
/* 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 */
|
||||
/*******************************/
|
||||
|
@ -57,6 +57,7 @@ GtkWidget * gimp_prop_view_new (GObject *config,
|
||||
GimpContext *context,
|
||||
gint size);
|
||||
|
||||
|
||||
/* GParamDouble, GParamDouble, GParamDouble, GParamDouble, GParamBoolean */
|
||||
|
||||
GtkWidget * gimp_prop_number_pair_entry_new
|
||||
@ -74,4 +75,11 @@ GtkWidget * gimp_prop_number_pair_entry_new
|
||||
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__ */
|
||||
|
Reference in New Issue
Block a user