added GIMP_TYPE_COLOR as boxed type encapsulating GimpRGB.

2002-05-21  Michael Natterer  <mitch@gimp.org>

	* app/config/gimpconfig-types.[ch]: added GIMP_TYPE_COLOR as boxed
	type encapsulating GimpRGB.

	* app/config/gimpconfig-params.[ch]: added GimpParamSpecColor
	which is derived from GParamSpecBoxed and adds a default value.

	* app/config/gimpconfig-deserialize.c
	* app/config/gimpconfig-serialize.c: added generic
	(de)serialization of the new property type.

	* app/core/gimpcontext.c: implement the config interface, changed
	signal parameters and property types to use the new
	GIMP_TYPE_COLOR.

	* app/core/gimpmarshal.list: added a VOID__BOXED marshaller.

	* app/gui/menus.c
	* app/gui/test-commands.[ch]: some test code which (de)serializes
	the user context.
This commit is contained in:
Michael Natterer 2002-05-21 15:01:57 +00:00 committed by Michael Natterer
parent 16c289ea95
commit 292ec087eb
16 changed files with 656 additions and 35 deletions

View File

@ -1,3 +1,25 @@
2002-05-21 Michael Natterer <mitch@gimp.org>
* app/config/gimpconfig-types.[ch]: added GIMP_TYPE_COLOR as boxed
type encapsulating GimpRGB.
* app/config/gimpconfig-params.[ch]: added GimpParamSpecColor
which is derived from GParamSpecBoxed and adds a default value.
* app/config/gimpconfig-deserialize.c
* app/config/gimpconfig-serialize.c: added generic
(de)serialization of the new property type.
* app/core/gimpcontext.c: implement the config interface, changed
signal parameters and property types to use the new
GIMP_TYPE_COLOR.
* app/core/gimpmarshal.list: added a VOID__BOXED marshaller.
* app/gui/menus.c
* app/gui/test-commands.[ch]: some test code which (de)serializes
the user context.
2002-05-21 Sven Neumann <sven@gimp.org>
* app/core/gimplayer.[ch] (gimp_layer_new_from_tiles): added a

View File

@ -31,6 +31,8 @@
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-substitute.h"
@ -63,6 +65,9 @@ static GTokenType gimp_config_deserialize_path (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_any (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
@ -229,6 +234,10 @@ gimp_config_deserialize_property (GObject *object,
token = gimp_config_deserialize_path (&value,
object, prop_spec, scanner);
}
else if (prop_spec->value_type == GIMP_TYPE_COLOR)
{
token = gimp_config_deserialize_color (&value, prop_spec, scanner);
}
else /* This fallback will only work for value_types that */
{ /* can be transformed from a string value. */
token = gimp_config_deserialize_any (&value, prop_spec, scanner);
@ -432,6 +441,125 @@ gimp_config_deserialize_path (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
static GTokenType
gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
scope_id = g_quark_from_static_string ("gimp_config_deserialize_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
token = G_TOKEN_LEFT_PAREN;
do
{
if (g_scanner_peek_next_token (scanner) != token)
break;
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (g_scanner_peek_next_token (scanner) != token)
goto finish;
token = g_scanner_get_next_token (scanner);
col[i] = scanner->value.v_float;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
g_value_set_boxed (value, &color);
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
while (token != G_TOKEN_EOF);
finish:
g_scanner_set_scope (scanner, old_scope_id);
return token;
}
static GTokenType
gimp_config_deserialize_any (GValue *value,
GParamSpec *prop_spec,

View File

@ -24,11 +24,165 @@
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig-params.h"
#include "gimpconfig-types.h"
#define GIMP_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_COLOR, GimpParamSpecColor))
static void gimp_param_color_class_init (GParamSpecClass *class);
static void gimp_param_color_init (GParamSpec *pspec);
static void gimp_param_color_set_default (GParamSpec *pspec,
GValue *value);
static gboolean gimp_param_color_validate (GParamSpec *pspec,
GValue *value);
static gint gimp_param_color_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
typedef struct _GimpParamSpecColor GimpParamSpecColor;
struct _GimpParamSpecColor
{
GParamSpecBoxed parent_instance;
GimpRGB default_value;
};
GType
gimp_param_color_get_type (void)
{
static GType spec_type = 0;
if (!spec_type)
{
static const GTypeInfo type_info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_color_class_init,
NULL, NULL,
sizeof (GimpParamSpecColor),
0,
(GInstanceInitFunc) gimp_param_color_init
};
spec_type = g_type_register_static (G_TYPE_PARAM_BOXED,
"GimpParamColor",
&type_info, 0);
}
return spec_type;
}
static void
gimp_param_color_class_init (GParamSpecClass *class)
{
class->value_type = GIMP_TYPE_COLOR;
class->value_set_default = gimp_param_color_set_default;
class->value_validate = gimp_param_color_validate;
class->values_cmp = gimp_param_color_values_cmp;
}
static void
gimp_param_color_init (GParamSpec *pspec)
{
GimpParamSpecColor *cspec = GIMP_PARAM_SPEC_COLOR (pspec);
gimp_rgba_set (&cspec->default_value, 0.0, 0.0, 0.0, 0.0);
}
static void
gimp_param_color_set_default (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecColor *cspec = GIMP_PARAM_SPEC_COLOR (pspec);
GimpRGB *color;
color = value->data[0].v_pointer;
if (color)
*color = cspec->default_value;
}
static gboolean
gimp_param_color_validate (GParamSpec *pspec,
GValue *value)
{
GimpRGB *color;
color = value->data[0].v_pointer;
if (color)
{
GimpRGB oval;
oval = *color;
gimp_rgb_clamp (color);
return (oval.r != color->r ||
oval.g != color->g ||
oval.b != color->b ||
oval.a != color->a);
}
return FALSE;
}
static gint
gimp_param_color_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
GimpRGB *color1;
GimpRGB *color2;
color1 = value1->data[0].v_pointer;
color2 = value2->data[0].v_pointer;
/* try to return at least *something*, it's useless anyway... */
if (! color1)
return color2 != NULL ? -1 : 0;
else if (! color2)
return color1 != NULL;
else
{
gdouble intensity1 = gimp_rgb_intensity (color1);
gdouble intensity2 = gimp_rgb_intensity (color2);
if (intensity1 < intensity2)
return -1;
else
return intensity1 > intensity2;
}
}
GParamSpec *
gimp_param_spec_color (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GimpRGB *default_value,
GParamFlags flags)
{
GimpParamSpecColor *cspec;
g_return_val_if_fail (default_value != NULL, NULL);
cspec = g_param_spec_internal (GIMP_TYPE_PARAM_COLOR,
name, nick, blurb, flags);
cspec->default_value = *default_value;
G_PARAM_SPEC (cspec)->value_type = GIMP_TYPE_COLOR;
return G_PARAM_SPEC (cspec);
}
static void gimp_param_memsize_class_init (GParamSpecClass *class);
GType

View File

@ -23,6 +23,18 @@
#define __GIMP_CONFIG_PARAMS_H__
#define GIMP_TYPE_PARAM_COLOR (gimp_param_color_get_type ())
#define GIMP_IS_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_SPEC_COLOR))
GType gimp_param_color_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_color (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GimpRGB *default_value,
GParamFlags flags);
#define GIMP_TYPE_PARAM_MEMSIZE (gimp_param_memsize_get_type ())
#define GIMP_IS_PARAM_SPEC_MEMSIZE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_SPEC_MEMSIZE))

View File

@ -33,6 +33,8 @@
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-types.h"
@ -278,6 +280,19 @@ gimp_config_serialize_value (const GValue *value,
return TRUE;
}
if (GIMP_VALUE_HOLDS_COLOR (value))
{
GimpRGB *color;
color = g_value_get_boxed (value);
g_string_append_printf (str, "(color-rgba %f %f %f %f)",
color->r,
color->g,
color->b,
color->a);
return TRUE;
}
if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
{
GValue tmp_value = { 0, };

View File

@ -32,6 +32,9 @@
#include "gimpconfig-types.h"
static GimpRGB * color_copy (const GimpRGB *color);
static void color_free (GimpRGB *color);
static void memsize_to_string (const GValue *src_value,
GValue *dest_value);
static void string_to_memsize (const GValue *src_value,
@ -43,6 +46,19 @@ static void string_to_unit (const GValue *src_value,
GValue *dest_value);
GType
gimp_color_get_type (void)
{
static GType color_type = 0;
if (!color_type)
color_type = g_boxed_type_register_static ("GimpColor",
(GBoxedCopyFunc) color_copy,
(GBoxedFreeFunc) color_free);
return color_type;
}
GType
gimp_memsize_get_type (void)
{
@ -101,6 +117,20 @@ gimp_unit_get_type (void)
return unit_type;
}
static GimpRGB *
color_copy (const GimpRGB *color)
{
return (GimpRGB *) g_memdup (color, sizeof (GimpRGB));
}
static void
color_free (GimpRGB *color)
{
g_free (color);
}
static void
memsize_to_string (const GValue *src_value,
GValue *dest_value)
@ -122,7 +152,6 @@ memsize_to_string (const GValue *src_value,
g_value_set_string_take_ownership (dest_value, str);
};
static void
string_to_memsize (const GValue *src_value,
GValue *dest_value)
@ -173,6 +202,7 @@ string_to_memsize (const GValue *src_value,
g_warning ("Can't convert string to GimpMemsize.");
};
static void
unit_to_string (const GValue *src_value,
GValue *dest_value)

View File

@ -23,6 +23,12 @@
#define __GIMP_CONFIG_TYPES_H__
#define GIMP_TYPE_COLOR (gimp_color_get_type ())
#define GIMP_VALUE_HOLDS_COLOR(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_COLOR))
GType gimp_color_get_type (void) G_GNUC_CONST;
#define GIMP_TYPE_MEMSIZE (gimp_memsize_get_type ())
#define GIMP_VALUE_HOLDS_MEMSIZE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_MEMSIZE))

View File

@ -47,6 +47,10 @@
#include "gimppattern.h"
#include "gimptoolinfo.h"
#include "config/gimpconfig.h"
#include "config/gimpconfig-types.h"
#include "config/gimpconfig-params.h"
#include "libgimp/gimpintl.h"
@ -77,7 +81,6 @@ static void gimp_context_get_property (GObject *object,
static gsize gimp_context_get_memsize (GimpObject *object);
/* image */
static void gimp_context_image_removed (GimpContainer *container,
GimpImage *image,
@ -362,10 +365,20 @@ gimp_context_get_type (void)
0, /* n_preallocs */
(GInstanceInitFunc) gimp_context_init,
};
static const GInterfaceInfo config_iface_info =
{
NULL, /* iface_init */
NULL, /* iface_finalize */
NULL /* iface_data */
};
context_type = g_type_register_static (GIMP_TYPE_OBJECT,
"GimpContext",
&context_info, 0);
g_type_add_interface_static (context_type,
GIMP_TYPE_CONFIG_INTERFACE,
&config_iface_info);
}
return context_type;
@ -376,6 +389,11 @@ gimp_context_class_init (GimpContextClass *klass)
{
GObjectClass *object_class;
GimpObjectClass *gimp_object_class;
GimpRGB black;
GimpRGB white;
gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
gimp_rgba_set (&white, 1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
object_class = G_OBJECT_CLASS (klass);
gimp_object_class = GIMP_OBJECT_CLASS (klass);
@ -418,9 +436,9 @@ gimp_context_class_init (GimpContextClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpContextClass, foreground_changed),
NULL, NULL,
gimp_marshal_VOID__POINTER,
gimp_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
GIMP_TYPE_COLOR);
gimp_context_signals[BACKGROUND_CHANGED] =
g_signal_new (gimp_context_signal_names[BACKGROUND_CHANGED],
@ -428,9 +446,9 @@ gimp_context_class_init (GimpContextClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpContextClass, background_changed),
NULL, NULL,
gimp_marshal_VOID__POINTER,
gimp_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
GIMP_TYPE_COLOR);
gimp_context_signals[OPACITY_CHANGED] =
g_signal_new (gimp_context_signal_names[OPACITY_CHANGED],
@ -448,9 +466,9 @@ gimp_context_class_init (GimpContextClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpContextClass, paint_mode_changed),
NULL, NULL,
gimp_marshal_VOID__INT,
gimp_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
G_TYPE_INT);
GIMP_TYPE_LAYER_MODE_EFFECTS);
gimp_context_signals[BRUSH_CHANGED] =
g_signal_new (gimp_context_signal_names[BRUSH_CHANGED],
@ -573,14 +591,16 @@ gimp_context_class_init (GimpContextClass *klass)
g_object_class_install_property (object_class,
PROP_FOREGROUND,
g_param_spec_pointer (gimp_context_prop_names[FOREGROUND_CHANGED],
gimp_param_spec_color (gimp_context_prop_names[FOREGROUND_CHANGED],
NULL, NULL,
&black,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_BACKGROUND,
g_param_spec_pointer (gimp_context_prop_names[BACKGROUND_CHANGED],
gimp_param_spec_color (gimp_context_prop_names[BACKGROUND_CHANGED],
NULL, NULL,
&white,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
@ -592,13 +612,11 @@ gimp_context_class_init (GimpContextClass *klass)
1.0,
G_PARAM_READWRITE));
/* FIXME: convert to enum property */
g_object_class_install_property (object_class,
PROP_PAINT_MODE,
g_param_spec_int (gimp_context_prop_names[PAINT_MODE_CHANGED],
g_param_spec_enum (gimp_context_prop_names[PAINT_MODE_CHANGED],
NULL, NULL,
GIMP_NORMAL_MODE,
GIMP_ANTI_ERASE_MODE,
GIMP_TYPE_LAYER_MODE_EFFECTS,
GIMP_NORMAL_MODE,
G_PARAM_READWRITE));
@ -809,16 +827,16 @@ gimp_context_set_property (GObject *object,
gimp_context_set_tool (context, g_value_get_object (value));
break;
case PROP_FOREGROUND:
gimp_context_set_foreground (context, g_value_get_pointer (value));
gimp_context_set_foreground (context, g_value_get_boxed (value));
break;
case PROP_BACKGROUND:
gimp_context_set_background (context, g_value_get_pointer (value));
gimp_context_set_background (context, g_value_get_boxed (value));
break;
case PROP_OPACITY:
gimp_context_set_opacity (context, g_value_get_double (value));
break;
case PROP_PAINT_MODE:
gimp_context_set_paint_mode (context, g_value_get_int (value));
gimp_context_set_paint_mode (context, g_value_get_enum (value));
break;
case PROP_BRUSH:
gimp_context_set_brush (context, g_value_get_object (value));
@ -869,16 +887,26 @@ gimp_context_get_property (GObject *object,
g_value_set_object (value, gimp_context_get_tool (context));
break;
case PROP_FOREGROUND:
gimp_context_get_foreground (context, g_value_get_pointer (value));
{
GimpRGB color;
gimp_context_get_foreground (context, &color);
g_value_set_boxed (value, &color);
}
break;
case PROP_BACKGROUND:
gimp_context_get_background (context, g_value_get_pointer (value));
{
GimpRGB color;
gimp_context_get_background (context, &color);
g_value_set_boxed (value, &color);
}
break;
case PROP_OPACITY:
g_value_set_double (value, gimp_context_get_opacity (context));
break;
case PROP_PAINT_MODE:
g_value_set_int (value, gimp_context_get_paint_mode (context));
g_value_set_enum (value, gimp_context_get_paint_mode (context));
break;
case PROP_BRUSH:
g_value_set_object (value, gimp_context_get_brush (context));

View File

@ -40,6 +40,7 @@ POINTER: POINTER, INT
POINTER: POINTER, INT, INT
POINTER: VOID
VOID: BOXED
VOID: DOUBLE
VOID: ENUM
VOID: INT

View File

@ -234,6 +234,12 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { "/File/Debug/Dump Items", NULL,
menus_debug_cmd_callback, 0 },
NULL, NULL, NULL },
{ { "/File/Debug/Serialize User Context", NULL,
test_serialize_context_cmd_callback, 0 },
NULL, NULL, NULL },
{ { "/File/Debug/Deserialize User Context", NULL,
test_deserialize_context_cmd_callback, 0 },
NULL, NULL, NULL },
#endif
SEPARATOR ("/File/---"),

View File

@ -20,6 +20,7 @@
#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"
#include "libgimpwidgets/gimpwidgets.h"
@ -33,6 +34,8 @@
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "config/gimpconfig.h"
#include "widgets/gimpcontainerlistview.h"
#include "widgets/gimpcontainergridview.h"
#include "widgets/gimpcontainermenuimpl.h"
@ -286,3 +289,53 @@ test_multi_container_grid_view_cmd_callback (GtkWidget *widget,
gimp_get_user_context (gimp),
32);
}
void
test_serialize_context_cmd_callback (GtkWidget *widget,
gpointer data)
{
Gimp *gimp;
gchar *filename;
GError *error = NULL;
gimp = GIMP (data);
filename = gimp_personal_rc_file ("test-context");
if (! gimp_config_serialize (G_OBJECT (gimp_get_user_context (gimp)),
filename,
"# foo\n\n",
"\n# bar\n",
NULL,
&error))
{
g_message ("Serializing Context failed:\n%s", error->message);
g_clear_error (&error);
}
g_free (filename);
}
void
test_deserialize_context_cmd_callback (GtkWidget *widget,
gpointer data)
{
Gimp *gimp;
gchar *filename;
GError *error = NULL;
gimp = GIMP (data);
filename = gimp_personal_rc_file ("test-context");
if (! gimp_config_deserialize (G_OBJECT (gimp_get_user_context (gimp)),
filename,
NULL,
&error))
{
g_message ("Deserializing Context failed:\n%s", error->message);
g_clear_error (&error);
}
g_free (filename);
}

View File

@ -25,5 +25,10 @@ void test_multi_container_list_view_cmd_callback (GtkWidget *widget,
void test_multi_container_grid_view_cmd_callback (GtkWidget *widget,
gpointer data);
void test_serialize_context_cmd_callback (GtkWidget *widget,
gpointer data);
void test_deserialize_context_cmd_callback (GtkWidget *widget,
gpointer data);
#endif /* __TEST_COMMANDS_H__ */

View File

@ -234,6 +234,12 @@ static GimpItemFactoryEntry toolbox_entries[] =
{ { "/File/Debug/Dump Items", NULL,
menus_debug_cmd_callback, 0 },
NULL, NULL, NULL },
{ { "/File/Debug/Serialize User Context", NULL,
test_serialize_context_cmd_callback, 0 },
NULL, NULL, NULL },
{ { "/File/Debug/Deserialize User Context", NULL,
test_deserialize_context_cmd_callback, 0 },
NULL, NULL, NULL },
#endif
SEPARATOR ("/File/---"),

View File

@ -31,6 +31,8 @@
#include <glib-object.h>
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-deserialize.h"
#include "gimpconfig-substitute.h"
@ -63,6 +65,9 @@ static GTokenType gimp_config_deserialize_path (GValue *value,
GObject *object,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
static GTokenType gimp_config_deserialize_any (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner);
@ -229,6 +234,10 @@ gimp_config_deserialize_property (GObject *object,
token = gimp_config_deserialize_path (&value,
object, prop_spec, scanner);
}
else if (prop_spec->value_type == GIMP_TYPE_COLOR)
{
token = gimp_config_deserialize_color (&value, prop_spec, scanner);
}
else /* This fallback will only work for value_types that */
{ /* can be transformed from a string value. */
token = gimp_config_deserialize_any (&value, prop_spec, scanner);
@ -432,6 +441,125 @@ gimp_config_deserialize_path (GValue *value,
return G_TOKEN_RIGHT_PAREN;
}
enum
{
COLOR_RGB = 1,
COLOR_RGBA,
COLOR_HSV,
COLOR_HSVA
};
static GTokenType
gimp_config_deserialize_color (GValue *value,
GParamSpec *prop_spec,
GScanner *scanner)
{
guint scope_id;
guint old_scope_id;
GTokenType token;
scope_id = g_quark_from_static_string ("gimp_config_deserialize_color");
old_scope_id = g_scanner_set_scope (scanner, scope_id);
if (! g_scanner_scope_lookup_symbol (scanner, scope_id, "color-rgb"))
{
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgb", GINT_TO_POINTER (COLOR_RGB));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-rgba", GINT_TO_POINTER (COLOR_RGBA));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsv", GINT_TO_POINTER (COLOR_HSV));
g_scanner_scope_add_symbol (scanner, scope_id,
"color-hsva", GINT_TO_POINTER (COLOR_HSVA));
}
token = G_TOKEN_LEFT_PAREN;
do
{
if (g_scanner_peek_next_token (scanner) != token)
break;
token = g_scanner_get_next_token (scanner);
switch (token)
{
case G_TOKEN_LEFT_PAREN:
token = G_TOKEN_SYMBOL;
break;
case G_TOKEN_SYMBOL:
{
gdouble col[4] = { 0.0, 0.0, 0.0, 1.0 };
GimpRGB color;
gint n_channels = 4;
gboolean is_hsv = FALSE;
gint i;
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
{
case COLOR_RGB:
n_channels = 3;
/* fallthrough */
case COLOR_RGBA:
break;
case COLOR_HSV:
n_channels = 3;
/* fallthrough */
case COLOR_HSVA:
is_hsv = TRUE;
break;
}
token = G_TOKEN_FLOAT;
for (i = 0; i < n_channels; i++)
{
if (g_scanner_peek_next_token (scanner) != token)
goto finish;
token = g_scanner_get_next_token (scanner);
col[i] = scanner->value.v_float;
}
if (is_hsv)
{
GimpHSV hsv;
gimp_hsva_set (&hsv, col[0], col[1], col[2], col[3]);
gimp_hsv_clamp (&hsv);
gimp_hsv_to_rgb (&hsv, &color);
}
else
{
gimp_rgba_set (&color, col[0], col[1], col[2], col[3]);
gimp_rgb_clamp (&color);
}
g_value_set_boxed (value, &color);
}
token = G_TOKEN_RIGHT_PAREN;
break;
case G_TOKEN_RIGHT_PAREN:
goto finish;
default: /* do nothing */
break;
}
}
while (token != G_TOKEN_EOF);
finish:
g_scanner_set_scope (scanner, old_scope_id);
return token;
}
static GTokenType
gimp_config_deserialize_any (GValue *value,
GParamSpec *prop_spec,

View File

@ -23,6 +23,18 @@
#define __GIMP_CONFIG_PARAMS_H__
#define GIMP_TYPE_PARAM_COLOR (gimp_param_color_get_type ())
#define GIMP_IS_PARAM_SPEC_COLOR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_SPEC_COLOR))
GType gimp_param_color_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_color (const gchar *name,
const gchar *nick,
const gchar *blurb,
const GimpRGB *default_value,
GParamFlags flags);
#define GIMP_TYPE_PARAM_MEMSIZE (gimp_param_memsize_get_type ())
#define GIMP_IS_PARAM_SPEC_MEMSIZE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_SPEC_MEMSIZE))

View File

@ -33,6 +33,8 @@
#include <io.h>
#endif
#include "libgimpcolor/gimpcolor.h"
#include "gimpconfig.h"
#include "gimpconfig-serialize.h"
#include "gimpconfig-types.h"
@ -278,6 +280,19 @@ gimp_config_serialize_value (const GValue *value,
return TRUE;
}
if (GIMP_VALUE_HOLDS_COLOR (value))
{
GimpRGB *color;
color = g_value_get_boxed (value);
g_string_append_printf (str, "(color-rgba %f %f %f %f)",
color->r,
color->g,
color->b,
color->a);
return TRUE;
}
if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
{
GValue tmp_value = { 0, };