X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkcssstyleproperty.c;h=0b7491524e421174e64c9185dfbc85e64e601ffb;hb=aaedf5a35219b034a244730564b8fdf2b7d32540;hp=cc08e188f82d01479f8bfb9dc90dd1fba1021ff4;hpb=a7f238138ec567b14293e728222147e326ff7154;p=~andy%2Fgtk diff --git a/gtk/gtkcssstyleproperty.c b/gtk/gtkcssstyleproperty.c index cc08e188f..0b7491524 100644 --- a/gtk/gtkcssstyleproperty.c +++ b/gtk/gtkcssstyleproperty.c @@ -21,6 +21,7 @@ #include "gtkcssstylepropertyprivate.h" +#include "gtkcssenumvalueprivate.h" #include "gtkcssinheritvalueprivate.h" #include "gtkcssinitialvalueprivate.h" #include "gtkcssstylefuncsprivate.h" @@ -37,6 +38,8 @@ enum { PROP_0, PROP_ANIMATED, + PROP_AFFECTS_SIZE, + PROP_AFFECTS_FONT, PROP_ID, PROP_INHERIT, PROP_INITIAL @@ -44,6 +47,11 @@ enum { G_DEFINE_TYPE (GtkCssStyleProperty, _gtk_css_style_property, GTK_TYPE_STYLE_PROPERTY) +static GtkBitmask *_properties_affecting_size = NULL; +static GtkBitmask *_properties_affecting_font = NULL; + +static GtkCssStylePropertyClass *gtk_css_style_property_class = NULL; + static void gtk_css_style_property_constructed (GObject *object) { @@ -53,6 +61,12 @@ gtk_css_style_property_constructed (GObject *object) property->id = klass->style_properties->len; g_ptr_array_add (klass->style_properties, property); + if (property->affects_size) + _properties_affecting_size = _gtk_bitmask_set (_properties_affecting_size, property->id, TRUE); + + if (property->affects_font) + _properties_affecting_font = _gtk_bitmask_set (_properties_affecting_font, property->id, TRUE); + G_OBJECT_CLASS (_gtk_css_style_property_parent_class)->constructed (object); } @@ -69,6 +83,12 @@ gtk_css_style_property_set_property (GObject *object, case PROP_ANIMATED: property->animated = g_value_get_boolean (value); break; + case PROP_AFFECTS_SIZE: + property->affects_size = g_value_get_boolean (value); + break; + case PROP_AFFECTS_FONT: + property->affects_font = g_value_get_boolean (value); + break; case PROP_INHERIT: property->inherit = g_value_get_boolean (value); break; @@ -95,6 +115,12 @@ gtk_css_style_property_get_property (GObject *object, case PROP_ANIMATED: g_value_set_boolean (value, property->animated); break; + case PROP_AFFECTS_SIZE: + g_value_set_boolean (value, property->affects_size); + break; + case PROP_AFFECTS_FONT: + g_value_set_boolean (value, property->affects_font); + break; case PROP_ID: g_value_set_boolean (value, property->id); break; @@ -129,6 +155,63 @@ _gtk_css_style_property_assign (GtkStyleProperty *property, _gtk_css_value_unref (css_value); } +static gboolean +_gtk_css_style_property_query_special_case (GtkCssStyleProperty *property, + GValue *value, + GtkStyleQueryFunc query_func, + gpointer query_data) +{ + GtkBorderStyle border_style; + + switch (property->id) + { + case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH: + border_style = _gtk_css_border_style_value_get (query_func (GTK_CSS_PROPERTY_BORDER_TOP_STYLE, query_data)); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + g_value_init (value, G_TYPE_INT); + return TRUE; + } + break; + case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH: + border_style = _gtk_css_border_style_value_get (query_func (GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE, query_data)); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + g_value_init (value, G_TYPE_INT); + return TRUE; + } + break; + case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH: + border_style = _gtk_css_border_style_value_get (query_func (GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE, query_data)); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + g_value_init (value, G_TYPE_INT); + return TRUE; + } + break; + case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH: + border_style = _gtk_css_border_style_value_get (query_func (GTK_CSS_PROPERTY_BORDER_LEFT_STYLE, query_data)); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + g_value_init (value, G_TYPE_INT); + return TRUE; + } + break; + case GTK_CSS_PROPERTY_OUTLINE_WIDTH: + border_style = _gtk_css_border_style_value_get (query_func (GTK_CSS_PROPERTY_OUTLINE_STYLE, query_data)); + if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN) + { + g_value_init (value, G_TYPE_INT); + return TRUE; + } + break; + default: + break; + } + + return FALSE; +} + static void _gtk_css_style_property_query (GtkStyleProperty *property, GValue *value, @@ -138,6 +221,10 @@ _gtk_css_style_property_query (GtkStyleProperty *property, GtkCssStyleProperty *style_property = GTK_CSS_STYLE_PROPERTY (property); GtkCssValue *css_value; + /* I don't like this special case being here in this generic code path, but no idea where else to put it. */ + if (_gtk_css_style_property_query_special_case (style_property, value, query_func, query_data)) + return; + css_value = (* query_func) (GTK_CSS_STYLE_PROPERTY (property)->id, query_data); if (css_value == NULL) css_value =_gtk_css_style_property_get_initial_value (style_property); @@ -189,6 +276,20 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass) P_("Set if the value can be animated"), FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_AFFECTS_SIZE, + g_param_spec_boolean ("affects-size", + P_("Affects size"), + P_("Set if the value affects the sizing of elements"), + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_AFFECTS_FONT, + g_param_spec_boolean ("affects-font", + P_("Affects font"), + P_("Set if the value affects the font"), + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_ID, g_param_spec_uint ("id", @@ -216,6 +317,11 @@ _gtk_css_style_property_class_init (GtkCssStylePropertyClass *klass) property_class->parse_value = gtk_css_style_property_parse_value; klass->style_properties = g_ptr_array_new (); + + _properties_affecting_size = _gtk_bitmask_new (); + _properties_affecting_font = _gtk_bitmask_new (); + + gtk_css_style_property_class = klass; } static GtkCssValue * @@ -226,28 +332,10 @@ gtk_css_style_property_real_parse_value (GtkCssStyleProperty *property, return NULL; } -static void -gtk_css_style_property_real_print_value (GtkCssStyleProperty *property, - const GtkCssValue *value, - GString *string) -{ - _gtk_css_value_print (value, string); -} - -static GtkCssValue * -gtk_css_style_property_real_compute_value (GtkCssStyleProperty *property, - GtkStyleContext *context, - GtkCssValue *specified) -{ - return _gtk_css_value_ref (specified); -} - static void _gtk_css_style_property_init (GtkCssStyleProperty *property) { property->parse_value = gtk_css_style_property_real_parse_value; - property->print_value = gtk_css_style_property_real_print_value; - property->compute_value = gtk_css_style_property_real_compute_value; } /** @@ -261,17 +349,13 @@ _gtk_css_style_property_init (GtkCssStyleProperty *property) guint _gtk_css_style_property_get_n_properties (void) { - GtkCssStylePropertyClass *klass; - - klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY); - if (G_UNLIKELY (klass == NULL)) + if (G_UNLIKELY (gtk_css_style_property_class == NULL)) { _gtk_style_property_init_properties (); - klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY); - g_assert (klass); + g_assert (gtk_css_style_property_class); } - return klass->style_properties->len; + return gtk_css_style_property_class->style_properties->len; } /** @@ -287,18 +371,16 @@ _gtk_css_style_property_get_n_properties (void) GtkCssStyleProperty * _gtk_css_style_property_lookup_by_id (guint id) { - GtkCssStylePropertyClass *klass; - klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY); - if (G_UNLIKELY (klass == NULL)) + if (G_UNLIKELY (gtk_css_style_property_class == NULL)) { _gtk_style_property_init_properties (); - klass = g_type_class_peek (GTK_TYPE_CSS_STYLE_PROPERTY); - g_assert (klass); + g_assert (gtk_css_style_property_class); } - g_return_val_if_fail (id < klass->style_properties->len, NULL); - return g_ptr_array_index (klass->style_properties, id); + g_return_val_if_fail (id < gtk_css_style_property_class->style_properties->len, NULL); + + return g_ptr_array_index (gtk_css_style_property_class->style_properties, id); } /** @@ -337,6 +419,42 @@ _gtk_css_style_property_is_animated (GtkCssStyleProperty *property) return property->animated; } +/** + * _gtk_css_style_property_affects_size: + * @property: the property + * + * Queries if the given @property affects the size of elements. This is + * used for optimizations inside GTK, where a gtk_widget_queue_resize() + * can be avoided if the property does not affect size. + * + * Returns: %TRUE if the property affects sizing of elements. + **/ +gboolean +_gtk_css_style_property_affects_size (GtkCssStyleProperty *property) +{ + g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), FALSE); + + return property->affects_size; +} + +/** + * _gtk_css_style_property_affects_font: + * @property: the property + * + * Queries if the given @property affects the default font. This is + * used for optimizations inside GTK, where clearing pango + * layouts can be avoided if the font doesn't change. + * + * Returns: %TRUE if the property affects the font. + **/ +gboolean +_gtk_css_style_property_affects_font (GtkCssStyleProperty *property) +{ + g_return_val_if_fail (GTK_IS_CSS_STYLE_PROPERTY (property), FALSE); + + return property->affects_font; +} + /** * _gtk_css_style_property_get_id: * @property: the property @@ -372,51 +490,14 @@ _gtk_css_style_property_get_initial_value (GtkCssStyleProperty *property) return property->initial_value; } -/** - * _gtk_css_style_property_compute_value: - * @property: the property - * @computed: (out): an uninitialized value to be filled with the result - * @context: the context to use for resolving - * @specified: the value to compute from - * - * Converts the @specified value into the @computed value using the - * information in @context. This step is explained in detail in - *