Rework the way the color scheme setting is inherited. Now the overriding

2005-12-16  Matthias Clasen  <mclasen@redhat.com>

	* gtk/gtksettings.[hc]: Rework the way the color scheme setting
	is inherited. Now the overriding is done on a per-color basis,
	rather than for the setting as a whole. This has the effect
	that themes can declare defaults for all the symbolic colors they
	use by specifying a value for the gtk-color-scheme setting in
	their rc file, while still allowing the XSetting to override
	"standard" symbolic colors. The hash table is now available
	through the color-hash property.

	* gtk/gtkrc.c: Use the new color-hash property.
This commit is contained in:
Matthias Clasen 2005-12-16 18:45:31 +00:00 committed by Matthias Clasen
parent 9abfb245c5
commit bc190f2a70
5 changed files with 221 additions and 83 deletions

View File

@ -1,3 +1,16 @@
2005-12-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtksettings.[hc]: Rework the way the color scheme setting
is inherited. Now the overriding is done on a per-color basis,
rather than for the setting as a whole. This has the effect
that themes can declare defaults for all the symbolic colors they
use by specifying a value for the gtk-color-scheme setting in
their rc file, while still allowing the XSetting to override
"standard" symbolic colors. The hash table is now available
through the color-hash property.
* gtk/gtkrc.c: Use the new color-hash property.
2005-12-14 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized

View File

@ -1,3 +1,16 @@
2005-12-16 Matthias Clasen <mclasen@redhat.com>
* gtk/gtksettings.[hc]: Rework the way the color scheme setting
is inherited. Now the overriding is done on a per-color basis,
rather than for the setting as a whole. This has the effect
that themes can declare defaults for all the symbolic colors they
use by specifying a value for the gtk-color-scheme setting in
their rc file, while still allowing the XSetting to override
"standard" symbolic colors. The hash table is now available
through the color-hash property.
* gtk/gtkrc.c: Use the new color-hash property.
2005-12-14 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcontainer.c (_gtk_container_focus_sort): Skip unrealized

View File

@ -105,7 +105,6 @@ struct _GtkRcContext
gint default_priority;
GtkStyle *default_style;
gchar *colors;
GHashTable *color_hash;
};
@ -574,36 +573,19 @@ gtk_rc_font_name_changed (GtkSettings *settings,
}
static void
gtk_rc_color_scheme_changed (GtkSettings *settings,
GParamSpec *pspec,
GtkRcContext *context)
gtk_rc_color_hash_changed (GtkSettings *settings,
GParamSpec *pspec,
GtkRcContext *context)
{
gchar *colors;
if (context->color_hash)
g_hash_table_unref (context->color_hash);
g_object_get (settings,
"gtk-color-scheme", &colors,
NULL);
g_object_get (settings, "color-hash", &context->color_hash, NULL);
if (!colors && !context->colors)
return;
if (context->color_hash)
g_hash_table_ref (context->color_hash);
if (!colors || !context->colors ||
strcmp (colors, context->colors) != 0)
{
g_free (context->colors);
context->colors = g_strdup (colors);
if (context->color_hash)
g_hash_table_unref (context->color_hash);
context->color_hash = _gtk_settings_get_color_hash (settings);
if (context->color_hash)
g_hash_table_ref (context->color_hash);
gtk_rc_reparse_all_for_settings (settings, TRUE);
}
g_free (colors);
gtk_rc_reparse_all_for_settings (settings, TRUE);
}
static GtkRcContext *
@ -625,10 +607,9 @@ gtk_rc_context_get (GtkSettings *settings)
"gtk-theme-name", &context->theme_name,
"gtk-key-theme-name", &context->key_theme_name,
"gtk-font-name", &context->font_name,
"gtk-color-scheme", &context->colors,
"color-hash", &context->color_hash,
NULL);
context->color_hash = _gtk_settings_get_color_hash (settings);
if (context->color_hash)
g_hash_table_ref (context->color_hash);
@ -645,8 +626,8 @@ gtk_rc_context_get (GtkSettings *settings)
G_CALLBACK (gtk_rc_font_name_changed),
context);
g_signal_connect (settings,
"notify::gtk-color-scheme",
G_CALLBACK (gtk_rc_color_scheme_changed),
"notify::color-hash",
G_CALLBACK (gtk_rc_color_hash_changed),
context);
context->pixmap_path[0] = NULL;

View File

@ -41,6 +41,7 @@ typedef enum
{
GTK_SETTINGS_SOURCE_DEFAULT,
GTK_SETTINGS_SOURCE_RC_FILE,
GTK_SETTINGS_SOURCE_XSETTING,
GTK_SETTINGS_SOURCE_APPLICATION
} GtkSettingsSource;
@ -86,7 +87,8 @@ enum {
PROP_TIMEOUT_INITIAL,
PROP_TIMEOUT_REPEAT,
PROP_COLOR_SCHEME,
PROP_ENABLE_ANIMATIONS
PROP_ENABLE_ANIMATIONS,
PROP_COLOR_HASH
};
@ -109,14 +111,19 @@ static guint settings_install_property_parser (GtkSettingsClass *class,
GtkRcPropertyParser parser);
static void settings_update_double_click (GtkSettings *settings);
static void settings_update_modules (GtkSettings *settings);
static void settings_update_color_scheme (GtkSettings *settings);
#ifdef GDK_WINDOWING_X11
static void settings_update_cursor_theme (GtkSettings *settings);
static void settings_update_resolution (GtkSettings *settings);
static void settings_update_font_options (GtkSettings *settings);
#endif
static void settings_update_color_scheme (GtkSettings *settings);
static void merge_color_scheme (GtkSettings *settings,
GValue *value,
GtkSettingsSource source);
static gchar *get_color_scheme (GtkSettings *settings);
static GHashTable *get_color_hash (GtkSettings *settings);
/* --- variables --- */
@ -448,6 +455,10 @@ gtk_settings_class_init (GtkSettingsClass *class)
* color specifications must be in the format accepted by
* gdk_color_parse().
*
* Note that due to the way the color tables from different sources are
* merged, color specifications will be converted to hexadecimal form
* when getting this property.
*
* Since: 2.10
*/
result = settings_install_property_parser (class,
@ -469,6 +480,22 @@ gtk_settings_class_init (GtkSettingsClass *class)
NULL);
g_assert (result == PROP_ENABLE_ANIMATIONS);
/**
* GtkSettings:color-hash:
*
* Holds a hash table representation of the gtk-color-scheme setting,
* mapping color names to #GdkColor<!-- -->s.
*
* Since: 2.10
*/
g_object_class_install_property (gobject_class,
PROP_COLOR_HASH,
g_param_spec_boxed ("color-hash",
P_("Color Hash"),
P_("A hash table resentation of the color scheme."),
G_TYPE_HASH_TABLE,
GTK_PARAM_READABLE));
}
static void
@ -519,6 +546,7 @@ gtk_settings_get_for_screen (GdkScreen *screen)
settings_update_resolution (settings);
settings_update_font_options (settings);
#endif
settings_update_color_scheme (settings);
}
return settings;
@ -566,6 +594,12 @@ gtk_settings_get_property (GObject *object,
GType value_type = G_VALUE_TYPE (value);
GType fundamental_type = G_TYPE_FUNDAMENTAL (value_type);
if (property_id == PROP_COLOR_HASH)
{
g_value_set_boxed (value, get_color_hash (settings));
return;
}
/* For enums and strings, we need to get the value as a string,
* not as an int, since we support using names/nicks as the setting
* value.
@ -579,7 +613,15 @@ gtk_settings_get_property (GObject *object,
!gdk_screen_get_setting (settings->screen, pspec->name, value))
g_value_copy (&settings->property_values[property_id - 1].value, value);
else
g_param_value_validate (pspec, value);
{
if (pspec->param_id == PROP_COLOR_SCHEME)
{
merge_color_scheme (settings, value, GTK_SETTINGS_SOURCE_XSETTING);
g_value_set_string (value, get_color_scheme (settings));
}
g_param_value_validate (pspec, value);
}
}
else
{
@ -601,7 +643,6 @@ gtk_settings_get_property (GObject *object,
GtkRcPropertyParser parser = (GtkRcPropertyParser) g_param_spec_get_qdata (pspec, quark_property_parser);
g_value_init (&gstring_value, G_TYPE_GSTRING);
g_value_take_boxed (&gstring_value,
g_string_new (g_value_get_string (&val)));
@ -641,13 +682,13 @@ gtk_settings_notify (GObject *object,
case PROP_MODULES:
settings_update_modules (settings);
break;
case PROP_COLOR_SCHEME:
settings_update_color_scheme (settings);
break;
case PROP_DOUBLE_CLICK_TIME:
case PROP_DOUBLE_CLICK_DISTANCE:
settings_update_double_click (settings);
break;
case PROP_COLOR_SCHEME:
settings_update_color_scheme (settings);
break;
#ifdef GDK_WINDOWING_X11
case PROP_XFT_DPI:
settings_update_resolution (settings);
@ -751,7 +792,14 @@ apply_queued_setting (GtkSettings *data,
if (_gtk_settings_parse_convert (parser, &qvalue->public.value,
pspec, &tmp_value))
{
if (data->property_values[pspec->param_id - 1].source <= qvalue->source)
if (pspec->param_id == PROP_COLOR_SCHEME)
{
merge_color_scheme (data, &tmp_value, qvalue->source);
g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
data->property_values[pspec->param_id - 1].source = GTK_SETTINGS_SOURCE_DEFAULT;
}
else if (data->property_values[pspec->param_id - 1].source <= qvalue->source)
{
g_object_set_property (G_OBJECT (data), pspec->name, &tmp_value);
data->property_values[pspec->param_id - 1].source = qvalue->source;
@ -1557,15 +1605,45 @@ settings_update_resolution (GtkSettings *settings)
}
#endif
static GHashTable *
gtk_color_table_from_string (const gchar *str)
static void
settings_update_color_scheme (GtkSettings *settings)
{
gchar *dummy;
g_object_get (settings, "gtk-color-scheme", &dummy, NULL);
/* nothing to do here, the color hash is updated as a
* side effect of getting the color scheme
*/
g_free (dummy);
}
typedef struct {
GHashTable *color_hash;
gchar *tables[GTK_SETTINGS_SOURCE_APPLICATION + 1];
} ColorSchemeData;
static gboolean
update_color_hash (ColorSchemeData *data,
const gchar *str,
GtkSettingsSource source)
{
gchar *copy, *s, *p, *name;
GdkColor color;
GHashTable *colors;
gboolean changed = FALSE;
colors = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gdk_color_free);
if (data->tables[source] == NULL && str == NULL)
return FALSE;
if (data->tables[source] != NULL && str != NULL &&
strcmp (data->tables[source], str) == 0)
return FALSE;
g_free (data->tables[source]);
data->tables[source] = g_strdup (str);
copy = g_strdup (str);
@ -1580,12 +1658,7 @@ gtk_color_table_from_string (const gchar *str)
p++;
}
else
{
g_hash_table_destroy (colors);
colors = NULL;
break;
}
break;
while (*p == ' ')
p++;
@ -1602,51 +1675,110 @@ gtk_color_table_from_string (const gchar *str)
s++;
}
if (!gdk_color_parse (p, &color))
{
g_hash_table_destroy (colors);
colors = NULL;
if (gdk_color_parse (p, &color))
{
GdkColor *old;
break;
}
old = g_hash_table_lookup (data->color_hash, name);
if (!old ||
(old->pixel <= source && !gdk_color_equal (old, &color)))
{
GdkColor *new;
g_hash_table_insert (colors,
g_strdup (name),
gdk_color_copy (&color));
new = gdk_color_copy (&color);
new->pixel = source;
g_hash_table_insert (data->color_hash, g_strdup (name), new);
changed = TRUE;
}
}
}
g_free (copy);
return colors;
return changed;
}
static void
settings_update_color_scheme (GtkSettings *settings)
color_scheme_data_free (ColorSchemeData *data)
{
gchar *colors;
GHashTable *color_hash;
gint i;
g_object_get (settings,
"gtk-color-scheme", &colors,
NULL);
g_hash_table_unref (data->color_hash);
color_hash = gtk_color_table_from_string (colors);
for (i = 0; i <= GTK_SETTINGS_SOURCE_APPLICATION; i++)
g_free (data->tables[i]);
g_object_set_data_full (G_OBJECT (settings), "gtk-color-scheme",
color_hash, (GDestroyNotify) g_hash_table_unref);
g_free (colors);
g_free (data);
}
GHashTable *
_gtk_settings_get_color_hash (GtkSettings *settings)
static void
merge_color_scheme (GtkSettings *settings,
GValue *value,
GtkSettingsSource source)
{
if (g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme") == NULL)
ColorSchemeData *data;
const gchar *colors;
colors = g_value_get_string (value);
data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
if (!data)
{
data = g_new0 (ColorSchemeData, 1);
data->color_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gdk_color_free);
g_object_set_data_full (G_OBJECT (settings), "gtk-color-scheme",
data, (GDestroyNotify) color_scheme_data_free);
}
if (update_color_hash (data, colors, source))
g_object_notify (G_OBJECT (settings), "color-hash");
}
static GHashTable *
get_color_hash (GtkSettings *settings)
{
ColorSchemeData *data;
if (!g_object_get_data (G_OBJECT (settings), "gtk-color-scheme"))
settings_update_color_scheme (settings);
return (GHashTable *) g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
data = (ColorSchemeData *)g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
return data->color_hash;
}
static void
append_color_scheme (gpointer key,
gpointer value,
gpointer data)
{
gchar *name = (gchar *)key;
GdkColor *color = (GdkColor *)value;
GString *string = (GString *)data;
g_string_append_printf (string, "%s: #%04x%04x%04x\n",
name, color->red, color->green, color->blue);
}
static gchar *
get_color_scheme (GtkSettings *settings)
{
ColorSchemeData *data;
GString *string;
data = (ColorSchemeData *) g_object_get_data (G_OBJECT (settings),
"gtk-color-scheme");
string = g_string_new ("");
g_hash_table_foreach (data->color_hash, append_color_scheme, string);
return g_string_free (string, FALSE);
}

View File

@ -126,7 +126,6 @@ gboolean _gtk_settings_parse_convert (GtkRcPropertyParser parser,
const GValue *src_value,
GParamSpec *pspec,
GValue *dest_value);
GHashTable* _gtk_settings_get_color_hash (GtkSettings *settings);
G_END_DECLS