static GtkBitmask * gtk_css_transition_set_values (GtkStyleAnimation *animation, GtkBitmask *changed, gint64 for_time_us, GtkCssComputedValues *values) { GtkCssTransition *transition = GTK_CSS_TRANSITION (animation); GtkCssValue *value; double progress; if (transition->start_time >= for_time_us) value = _gtk_css_value_ref (transition->start); else if (transition->end_time <= for_time_us) value = _gtk_css_value_ref (transition->end); else { progress = (double) (for_time_us - transition->start_time) / (transition->end_time - transition->start_time); progress = _gtk_css_ease_value_transform (transition->ease, progress); value = _gtk_css_value_transition (transition->start, transition->end, progress); if (value == NULL) value = _gtk_css_value_ref (transition->end); } _gtk_css_computed_values_set_value (values, transition->property, value, NULL); _gtk_css_value_unref (value); return _gtk_bitmask_set (changed, transition->property, TRUE); }
void _gtk_css_computed_values_set_value (GtkCssComputedValues *values, guint id, GtkCssValue *value, GtkCssDependencies dependencies, GtkCssSection *section) { gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values)); if (values->values == NULL) values->values = g_ptr_array_new_full (_gtk_css_style_property_get_n_properties (), (GDestroyNotify)_gtk_css_value_unref); if (id >= values->values->len) g_ptr_array_set_size (values->values, id + 1); if (g_ptr_array_index (values->values, id)) _gtk_css_value_unref (g_ptr_array_index (values->values, id)); g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value); if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT)) values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE); if (dependencies & (GTK_CSS_EQUALS_PARENT)) values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE); if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR)) values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE); if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE)) values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE); if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id)) { gtk_css_section_unref (g_ptr_array_index (values->sections, id)); g_ptr_array_index (values->sections, id) = NULL; } if (section) { if (values->sections == NULL) values->sections = g_ptr_array_new_with_free_func (maybe_unref_section); if (values->sections->len <= id) g_ptr_array_set_size (values->sections, id + 1); g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section); } }
GtkBitmask * _gtk_css_computed_values_advance (GtkCssComputedValues *values, gint64 timestamp) { GtkBitmask *changed; GPtrArray *old_computed_values; GSList *list; guint i; gtk_internal_return_val_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values), NULL); gtk_internal_return_val_if_fail (timestamp >= values->current_time, NULL); values->current_time = timestamp; old_computed_values = values->animated_values; values->animated_values = NULL; list = values->animations; while (list) { GtkStyleAnimation *animation = list->data; list = list->next; _gtk_style_animation_set_values (animation, timestamp, GTK_CSS_COMPUTED_VALUES (values)); if (_gtk_style_animation_is_finished (animation, timestamp)) { values->animations = g_slist_remove (values->animations, animation); g_object_unref (animation); } } /* figure out changes */ changed = _gtk_bitmask_new (); for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++) { GtkCssValue *old_animated, *new_animated; old_animated = old_computed_values && i < old_computed_values->len ? g_ptr_array_index (old_computed_values, i) : NULL; new_animated = values->animated_values && i < values->animated_values->len ? g_ptr_array_index (values->animated_values, i) : NULL; if (!_gtk_css_value_equal0 (old_animated, new_animated)) changed = _gtk_bitmask_set (changed, i, TRUE); } if (old_computed_values) g_ptr_array_unref (old_computed_values); return changed; }
/** * _gtk_css_lookup_set: * @lookup: the lookup * @id: id of the property to set, see _gtk_style_property_get_id() * @section: (allow-none): The @section the value was defined in or %NULL * @value: the “cascading value” to use * * Sets the @value for a given @id. No value may have been set for @id * before. See _gtk_css_lookup_is_missing(). This function is used to * set the “winning declaration” of a lookup. Note that for performance * reasons @value and @section are not copied. It is your responsibility * to ensure they are kept alive until _gtk_css_lookup_free() is called. **/ void _gtk_css_lookup_set (GtkCssLookup *lookup, guint id, GtkCssSection *section, GtkCssValue *value) { gtk_internal_return_if_fail (lookup != NULL); gtk_internal_return_if_fail (_gtk_bitmask_get (lookup->missing, id)); gtk_internal_return_if_fail (value != NULL); lookup->missing = _gtk_bitmask_set (lookup->missing, id, FALSE); lookup->values[id].value = value; lookup->values[id].section = section; }
/** * _gtk_css_style_property_get_mask_affecting: * @flags: the flags that are affected * * Computes a bitmask for all properties that have at least one of @flags * set. * * Returns: (transfer full): A #GtkBitmask with the bit set for every * property that has at least one of @flags set. */ GtkBitmask * _gtk_css_style_property_get_mask_affecting (GtkCssAffects affects) { GtkBitmask *result; guint i; result = _gtk_bitmask_new (); for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++) { GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (i); if (_gtk_css_style_property_get_affects (prop) & affects) result = _gtk_bitmask_set (result, i, TRUE); } return result; }
GtkBitmask * gtk_css_style_get_difference (GtkCssStyle *style, GtkCssStyle *other) { GtkBitmask *result; guint i, len; if (style == other) return _gtk_bitmask_new (); result = _gtk_bitmask_new (); len = _gtk_css_style_property_get_n_properties (); for (i = 0; i < len; i++) { if (!_gtk_css_value_equal (gtk_css_style_get_value (style, i), gtk_css_style_get_value (other, i))) result = _gtk_bitmask_set (result, i, TRUE); } return result; }
GtkBitmask * _gtk_css_computed_values_get_difference (GtkCssComputedValues *values, GtkCssComputedValues *other) { GtkBitmask *result; guint i, len; len = MIN (values->values->len, other->values->len); result = _gtk_bitmask_new (); if (values->values->len != other->values->len) result = _gtk_bitmask_invert_range (result, len, MAX (values->values->len, other->values->len)); for (i = 0; i < len; i++) { if (!_gtk_css_value_equal (g_ptr_array_index (values->values, i), g_ptr_array_index (other->values, i))) result = _gtk_bitmask_set (result, i, TRUE); } return result; }
GtkBitmask * gtk_css_style_add_difference (GtkBitmask *accumulated, GtkCssStyle *style, GtkCssStyle *other) { gint len, i; if (style == other) return accumulated; len = _gtk_css_style_property_get_n_properties (); for (i = 0; i < len; i++) { if (_gtk_bitmask_get (accumulated, i)) continue; if (!_gtk_css_value_equal (gtk_css_style_get_value (style, i), gtk_css_style_get_value (other, i))) accumulated = _gtk_bitmask_set (accumulated, i, TRUE); } return accumulated; }
void _gtk_css_computed_values_compute_value (GtkCssComputedValues *values, GtkStyleProviderPrivate *provider, int scale, GtkCssComputedValues *parent_values, guint id, GtkCssValue *specified, GtkCssSection *section) { GtkCssDependencies dependencies; GtkCssValue *value; gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values)); gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER_PRIVATE (provider)); gtk_internal_return_if_fail (parent_values == NULL || GTK_IS_CSS_COMPUTED_VALUES (parent_values)); /* http://www.w3.org/TR/css3-cascade/#cascade * Then, for every element, the value for each property can be found * by following this pseudo-algorithm: * 1) Identify all declarations that apply to the element */ if (specified == NULL) { GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (id); if (_gtk_css_style_property_is_inherit (prop)) specified = _gtk_css_inherit_value_new (); else specified = _gtk_css_initial_value_new (); } else _gtk_css_value_ref (specified); value = _gtk_css_value_compute (specified, id, provider, scale, values, parent_values, &dependencies); if (values->values == NULL) values->values = g_ptr_array_new_full (_gtk_css_style_property_get_n_properties (), (GDestroyNotify)_gtk_css_value_unref); if (id >= values->values->len) g_ptr_array_set_size (values->values, id + 1); if (g_ptr_array_index (values->values, id)) _gtk_css_value_unref (g_ptr_array_index (values->values, id)); g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value); if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT)) values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE); if (dependencies & (GTK_CSS_EQUALS_PARENT)) values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE); if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR)) values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE); if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE)) values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE); if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id)) { gtk_css_section_unref (g_ptr_array_index (values->sections, id)); g_ptr_array_index (values->sections, id) = NULL; } if (section) { if (values->sections == NULL) values->sections = g_ptr_array_new_with_free_func (maybe_unref_section); if (values->sections->len <= id) g_ptr_array_set_size (values->sections, id + 1); g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section); } _gtk_css_value_unref (value); _gtk_css_value_unref (specified); }