Merge branch 'wip/baedert/for-master' into 'master'

Wip/baedert/for master

See merge request GNOME/gtk!1867
This commit is contained in:
Matthias Clasen 2020-05-11 14:24:45 +00:00
commit 329994291a
33 changed files with 977 additions and 1173 deletions

View File

@ -2573,7 +2573,7 @@ gsk_gl_renderer_programs_unref (GskGLRendererPrograms *programs)
{
for (i = 0; i < GL_N_PROGRAMS; i ++)
{
if (programs->programs[i].id != 0)
if (programs->programs[i].id > 0)
glDeleteProgram (programs->programs[i].id);
gsk_transform_unref (programs->state[i].modelview);
}

View File

@ -32,12 +32,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
vec2 frag = get_frag_coord();
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), frag),
0.0, 1.0);
setOutputColor(final_color * alpha);

View File

@ -33,13 +33,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
vec2 frag = get_frag_coord();
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), frag),
0.0, 1.0);
setOutputColor(final_color * alpha);

View File

@ -47,17 +47,9 @@ _IN_ float gradientLength;
_IN_ vec4 color_stops[8];
_IN_ float color_offsets[8];
vec4 fragCoord() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
return f;
}
void main() {
// Position relative to startPoint
vec2 pos = fragCoord().xy - startPoint;
vec2 pos = get_frag_coord() - startPoint;
// Current pixel, projected onto the line between the start point and the end point
// The projection will be relative to the start point!

View File

@ -25,13 +25,10 @@ _IN_ vec4 final_color;
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outline;
void main() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
vec2 frag = get_frag_coord();
float alpha = Texture(u_source, vUv).a;
alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), f.xy), 0.0, 1.0));
alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), frag), 0.0, 1.0));
vec4 color = final_color * alpha;

View File

@ -84,19 +84,32 @@ vec4 Texture(sampler2D sampler, vec2 texCoords) {
#endif
}
#ifdef GSK_GL3
layout(origin_upper_left) in vec4 gl_FragCoord;
#endif
vec2 get_frag_coord() {
vec2 fc = gl_FragCoord.xy;
#ifdef GSK_GL3
fc += u_viewport.xy;
#else
fc.x += u_viewport.x;
fc.y = (u_viewport.y + u_viewport.w) - fc.y;
#endif
return fc;
}
void setOutputColor(vec4 color) {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
vec2 f = get_frag_coord();
// We do *NOT* transform the clip rect here since we already
// need to do that on the CPU.
#if defined(GSK_GLES) || defined(GSK_LEGACY)
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f);
#else
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f);
#endif
/*outputColor = color;*/
}

View File

@ -33,13 +33,10 @@ _IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
vec2 frag = get_frag_coord();
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), frag) -
rounded_rect_coverage(decode_rect(transformed_inside_outline), frag),
0.0, 1.0);
setOutputColor(final_color * alpha);

View File

@ -4,7 +4,7 @@
/* This is a dumbed-down GPtrArray, which takes some stack
* space to use. When using this, the general case should always
* be that the number of elements is lower than reversed_size.
* be that the number of elements is lower than reserved_size.
* The GPtrArray should only be used in extreme cases.
*/
@ -55,13 +55,9 @@ gtk_array_add (GtkArray *self,
/* Need to fall back to the GPtrArray */
if (G_UNLIKELY (!self->ptr_array))
{
guint i;
self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL);
/* Copy elements from stack space to GPtrArray */
for (i = 0; i < self->len; i++)
g_ptr_array_add (self->ptr_array, self->stack_space[i]);
self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL);
memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len);
self->ptr_array->len = self->len;
}
g_ptr_array_add (self->ptr_array, element);
@ -88,6 +84,13 @@ gtk_array_insert (GtkArray *self,
return;
}
if (G_UNLIKELY (!self->ptr_array))
{
self->ptr_array = g_ptr_array_new_full (self->len + 1, NULL);
memcpy (self->ptr_array->pdata, self->stack_space, sizeof (void *) * self->len);
self->ptr_array->len = self->len;
}
g_assert (self->ptr_array);
g_ptr_array_insert (self->ptr_array, index, element);
self->len++;

View File

@ -26,6 +26,7 @@
#include "gtkrendericonprivate.h"
#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
#include "gtktreeprivate.h"
#include "a11y/gtkbooleancellaccessible.h"
@ -111,6 +112,7 @@ struct _GtkCellRendererTogglePrivate
guint activatable : 1;
guint inconsistent : 1;
guint radio : 1;
GtkCssNode *cssnode;
};
@ -126,12 +128,26 @@ gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle)
priv->active = FALSE;
priv->radio = FALSE;
priv->cssnode = gtk_css_node_new ();
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check"));
g_object_set (celltoggle, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (celltoggle), 2, 2);
priv->inconsistent = FALSE;
}
static void
gtk_cell_renderer_toggle_dispose (GObject *object)
{
GtkCellRendererToggle *celltoggle = GTK_CELL_RENDERER_TOGGLE (object);
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (celltoggle);
g_clear_object (&priv->cssnode);
G_OBJECT_CLASS (gtk_cell_renderer_toggle_parent_class)->dispose (object);
}
static void
gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
{
@ -140,6 +156,7 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
object_class->get_property = gtk_cell_renderer_toggle_get_property;
object_class->set_property = gtk_cell_renderer_toggle_set_property;
object_class->dispose = gtk_cell_renderer_toggle_dispose;
cell_class->get_size = gtk_cell_renderer_toggle_get_size;
cell_class->snapshot = gtk_cell_renderer_toggle_snapshot;
@ -268,7 +285,7 @@ gtk_cell_renderer_toggle_set_property (GObject *object,
case PROP_RADIO:
if (priv->radio != g_value_get_boolean (value))
{
priv->radio = g_value_get_boolean (value);
gtk_cell_renderer_toggle_set_radio (celltoggle, g_value_get_boolean (value));
g_object_notify_by_pspec (object, pspec);
}
break;
@ -298,23 +315,32 @@ gtk_cell_renderer_toggle_new (void)
}
static GtkStyleContext *
gtk_cell_renderer_toggle_save_context (GtkCellRenderer *cell,
GtkWidget *widget)
gtk_cell_renderer_toggle_save_context (GtkCellRendererToggle *cell,
GtkWidget *widget)
{
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (GTK_CELL_RENDERER_TOGGLE (cell));
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell);
GtkStyleContext *context;
context = gtk_widget_get_style_context (widget);
if (priv->radio)
gtk_style_context_save_named (context, "radio");
else
gtk_style_context_save_named (context, "check");
gtk_css_node_set_parent (priv->cssnode, gtk_widget_get_css_node (widget));
gtk_style_context_save_to_node (context, priv->cssnode);
return context;
}
static GtkStyleContext *
gtk_cell_renderer_toggle_restore_context (GtkCellRendererToggle *cell,
GtkStyleContext *context)
{
GtkCellRendererTogglePrivate *priv = gtk_cell_renderer_toggle_get_instance_private (cell);
gtk_style_context_restore (context);
gtk_css_node_set_parent (priv->cssnode, NULL);
return context;
}
static int
calc_indicator_size (GtkStyleContext *context)
{
@ -339,7 +365,7 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
context = gtk_cell_renderer_toggle_save_context (cell, widget);
context = gtk_cell_renderer_toggle_save_context (GTK_CELL_RENDERER_TOGGLE (cell), widget);
gtk_style_context_get_padding (context, &padding);
gtk_style_context_get_border (context, &border);
@ -347,7 +373,7 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
calc_width += xpad * 2 + padding.left + padding.right + border.left + border.right;
calc_height += ypad * 2 + padding.top + padding.bottom + border.top + border.bottom;
gtk_style_context_restore (context);
gtk_cell_renderer_toggle_restore_context (GTK_CELL_RENDERER_TOGGLE (cell), context);
if (width)
*width = calc_width;
@ -426,7 +452,7 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
cell_area->width, cell_area->height
));
context = gtk_cell_renderer_toggle_save_context (cell, widget);
context = gtk_cell_renderer_toggle_save_context (celltoggle, widget);
gtk_style_context_set_state (context, state);
gtk_snapshot_render_background (snapshot, context,
@ -448,7 +474,7 @@ gtk_cell_renderer_toggle_snapshot (GtkCellRenderer *cell,
width - padding.left - padding.right - border.left - border.right,
height - padding.top - padding.bottom - border.top - border.bottom);
gtk_style_context_restore (context);
gtk_cell_renderer_toggle_restore_context (celltoggle, context);
gtk_snapshot_pop (snapshot);
}
@ -495,6 +521,10 @@ gtk_cell_renderer_toggle_set_radio (GtkCellRendererToggle *toggle,
g_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (toggle));
priv->radio = radio;
if (radio)
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("radio"));
else
gtk_css_node_set_name (priv->cssnode, g_quark_from_static_string ("check"));
}
/**

View File

@ -53,7 +53,7 @@ gtk_css_animated_style_get_section (GtkCssStyle *style,
static gboolean
gtk_css_animated_style_is_static (GtkCssStyle *style)
{
GtkCssAnimatedStyle *animated = GTK_CSS_ANIMATED_STYLE (style);
GtkCssAnimatedStyle *animated = (GtkCssAnimatedStyle *)style;
guint i;
for (i = 0; i < animated->n_animations; i ++)
@ -81,7 +81,7 @@ gtk_css_animated_style_dispose (GObject *object)
guint i;
for (i = 0; i < style->n_animations; i ++)
g_object_unref (style->animations[i]);
gtk_style_animation_unref (style->animations[i]);
style->n_animations = 0;
g_free (style->animations);
@ -646,7 +646,7 @@ gtk_css_animated_style_find_transition (GtkCssAnimatedStyle *style,
{
GtkStyleAnimation *animation = style->animations[i];
if (!GTK_IS_CSS_TRANSITION (animation))
if (!_gtk_css_transition_is_transition (animation))
continue;
if (_gtk_css_transition_get_property ((GtkCssTransition *)animation) == property_id)
@ -745,7 +745,7 @@ gtk_css_animated_style_find_animation (GtkStyleAnimation **animations,
{
GtkStyleAnimation *animation = animations[i];
if (!GTK_IS_CSS_ANIMATION (animation))
if (!_gtk_css_animation_is_animation (animation))
continue;
if (g_str_equal (_gtk_css_animation_get_name ((GtkCssAnimation *)animation), name))
@ -765,9 +765,19 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations,
{
GtkCssValue *durations, *delays, *timing_functions, *animation_names;
GtkCssValue *iteration_counts, *directions, *play_states, *fill_modes;
gboolean source_is_animated;
guint i;
animation_names = base_style->animation->animation_name;
if (_gtk_css_array_value_get_n_values (animation_names) == 1)
{
const char *name = _gtk_css_ident_value_get (_gtk_css_array_value_get_nth (animation_names, 0));
if (g_ascii_strcasecmp (name, "none") == 0)
return animations;
}
durations = base_style->animation->animation_duration;
delays = base_style->animation->animation_delay;
timing_functions = base_style->animation->animation_timing_function;
@ -775,6 +785,7 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations,
directions = base_style->animation->animation_direction;
play_states = base_style->animation->animation_play_state;
fill_modes = base_style->animation->animation_fill_mode;
source_is_animated = GTK_IS_CSS_ANIMATED_STYLE (source);
for (i = 0; i < _gtk_css_array_value_get_n_values (animation_names); i++)
{
@ -792,14 +803,14 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations,
if (animation)
continue;
if (GTK_IS_CSS_ANIMATED_STYLE (source))
if (source_is_animated)
animation = gtk_css_animated_style_find_animation ((GtkStyleAnimation **)GTK_CSS_ANIMATED_STYLE (source)->animations,
GTK_CSS_ANIMATED_STYLE (source)->n_animations,
name);
if (animation)
{
animation = _gtk_css_animation_advance_with_play_state (GTK_CSS_ANIMATION (animation),
animation = _gtk_css_animation_advance_with_play_state ((GtkCssAnimation *)animation,
timestamp,
_gtk_css_play_state_value_get (_gtk_css_array_value_get_nth (play_states, i)));
}
@ -825,7 +836,7 @@ gtk_css_animated_style_create_css_animations (GPtrArray *animations,
}
if (!animations)
animations = g_ptr_array_new ();
animations = g_ptr_array_sized_new (16);
g_ptr_array_add (animations, animation);
}
@ -928,7 +939,7 @@ gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source,
continue;
if (!animations)
animations = g_ptr_array_new ();
animations = g_ptr_array_sized_new (16);
animation = _gtk_style_animation_advance (animation, timestamp);
g_ptr_array_add (animations, animation);

View File

@ -26,8 +26,6 @@
#include <math.h>
G_DEFINE_TYPE (GtkCssAnimation, _gtk_css_animation, GTK_TYPE_STYLE_ANIMATION)
static gboolean
gtk_css_animation_is_executing (GtkCssAnimation *animation)
{
@ -80,7 +78,7 @@ static GtkStyleAnimation *
gtk_css_animation_advance (GtkStyleAnimation *style_animation,
gint64 timestamp)
{
GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
GtkCssAnimation *animation = (GtkCssAnimation *)style_animation;
return _gtk_css_animation_advance_with_play_state (animation,
timestamp,
@ -91,7 +89,7 @@ static void
gtk_css_animation_apply_values (GtkStyleAnimation *style_animation,
GtkCssAnimatedStyle *style)
{
GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
GtkCssAnimation *animation = (GtkCssAnimation *)style_animation;
double progress;
guint i;
@ -125,7 +123,7 @@ gtk_css_animation_is_finished (GtkStyleAnimation *style_animation)
static gboolean
gtk_css_animation_is_static (GtkStyleAnimation *style_animation)
{
GtkCssAnimation *animation = GTK_CSS_ANIMATION (style_animation);
GtkCssAnimation *animation = (GtkCssAnimation *)style_animation;
if (animation->play_state == GTK_CSS_PLAY_STATE_PAUSED)
return TRUE;
@ -134,35 +132,26 @@ gtk_css_animation_is_static (GtkStyleAnimation *style_animation)
}
static void
gtk_css_animation_finalize (GObject *object)
gtk_css_animation_free (GtkStyleAnimation *animation)
{
GtkCssAnimation *animation = GTK_CSS_ANIMATION (object);
GtkCssAnimation *self = (GtkCssAnimation *)animation;
g_free (animation->name);
_gtk_css_keyframes_unref (animation->keyframes);
_gtk_css_value_unref (animation->ease);
g_free (self->name);
_gtk_css_keyframes_unref (self->keyframes);
_gtk_css_value_unref (self->ease);
G_OBJECT_CLASS (_gtk_css_animation_parent_class)->finalize (object);
g_slice_free (GtkCssAnimation, self);
}
static void
_gtk_css_animation_class_init (GtkCssAnimationClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass);
static const GtkStyleAnimationClass GTK_CSS_ANIMATION_CLASS = {
"GtkCssAnimation",
gtk_css_animation_free,
gtk_css_animation_is_finished,
gtk_css_animation_is_static,
gtk_css_animation_apply_values,
gtk_css_animation_advance,
};
object_class->finalize = gtk_css_animation_finalize;
animation_class->advance = gtk_css_animation_advance;
animation_class->apply_values = gtk_css_animation_apply_values;
animation_class->is_finished = gtk_css_animation_is_finished;
animation_class->is_static = gtk_css_animation_is_static;
}
static void
_gtk_css_animation_init (GtkCssAnimation *animation)
{
}
GtkStyleAnimation *
_gtk_css_animation_new (const char *name,
@ -183,7 +172,9 @@ _gtk_css_animation_new (const char *name,
g_return_val_if_fail (ease != NULL, NULL);
g_return_val_if_fail (iteration_count >= 0, NULL);
animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL);
animation = g_slice_alloc (sizeof (GtkCssAnimation));
animation->parent.class = &GTK_CSS_ANIMATION_CLASS;
animation->parent.ref_count = 1;
animation->name = g_strdup (name);
animation->keyframes = _gtk_css_keyframes_ref (keyframes);
@ -198,14 +189,12 @@ _gtk_css_animation_new (const char *name,
else
gtk_progress_tracker_advance_frame (&animation->tracker, timestamp);
return GTK_STYLE_ANIMATION (animation);
return (GtkStyleAnimation *)animation;
}
const char *
_gtk_css_animation_get_name (GtkCssAnimation *animation)
{
g_return_val_if_fail (GTK_IS_CSS_ANIMATION (animation), NULL);
return animation->name;
}
@ -214,11 +203,9 @@ _gtk_css_animation_advance_with_play_state (GtkCssAnimation *source,
gint64 timestamp,
GtkCssPlayState play_state)
{
GtkCssAnimation *animation;
g_return_val_if_fail (GTK_IS_CSS_ANIMATION (source), NULL);
animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL);
GtkCssAnimation *animation = g_slice_alloc (sizeof (GtkCssAnimation));
animation->parent.class = &GTK_CSS_ANIMATION_CLASS;
animation->parent.ref_count = 1;
animation->name = g_strdup (source->name);
animation->keyframes = _gtk_css_keyframes_ref (source->keyframes);
@ -233,5 +220,11 @@ _gtk_css_animation_advance_with_play_state (GtkCssAnimation *source,
else
gtk_progress_tracker_advance_frame (&animation->tracker, timestamp);
return GTK_STYLE_ANIMATION (animation);
return (GtkStyleAnimation *)animation;
}
gboolean
_gtk_css_animation_is_animation (GtkStyleAnimation *animation)
{
return animation->class == &GTK_CSS_ANIMATION_CLASS;
}

View File

@ -27,13 +27,6 @@
G_BEGIN_DECLS
#define GTK_TYPE_CSS_ANIMATION (_gtk_css_animation_get_type ())
#define GTK_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_ANIMATION, GtkCssAnimation))
#define GTK_CSS_ANIMATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass))
#define GTK_IS_CSS_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_ANIMATION))
#define GTK_IS_CSS_ANIMATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_ANIMATION))
#define GTK_CSS_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_ANIMATION, GtkCssAnimationClass))
typedef struct _GtkCssAnimation GtkCssAnimation;
typedef struct _GtkCssAnimationClass GtkCssAnimationClass;
@ -73,6 +66,7 @@ GtkStyleAnimation * _gtk_css_animation_advance_with_play_state (GtkCssAnimat
GtkCssPlayState play_state);
const char * _gtk_css_animation_get_name (GtkCssAnimation *animation);
gboolean _gtk_css_animation_is_animation (GtkStyleAnimation *animation);
G_END_DECLS

View File

@ -21,295 +21,6 @@
#include <string.h>
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
gsize n_terms;
GtkCssValue * terms[1];
};
static gsize
gtk_css_value_calc_get_size (gsize n_terms)
{
g_assert (n_terms > 0);
return sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (n_terms - 1);
}
static void
gtk_css_value_calc_free (GtkCssValue *value)
{
gsize i;
for (i = 0; i < value->n_terms; i++)
{
_gtk_css_value_unref (value->terms[i]);
}
g_slice_free1 (gtk_css_value_calc_get_size (value->n_terms), value);
}
static GtkCssValue *gtk_css_calc_value_new (gsize n_terms);
static GtkCssValue *
gtk_css_value_new_from_array (GPtrArray *array)
{
GtkCssValue *result;
if (array->len > 1)
{
result = gtk_css_calc_value_new (array->len);
memcpy (result->terms, array->pdata, array->len * sizeof (GtkCssValue *));
}
else
{
result = g_ptr_array_index (array, 0);
}
g_ptr_array_free (array, TRUE);
return result;
}
static void
gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value)
{
gsize i;
gint calc_term_order;
calc_term_order = gtk_css_number_value_get_calc_term_order (value);
for (i = 0; i < array->len; i++)
{
GtkCssValue *sum = gtk_css_number_value_try_add (g_ptr_array_index (array, i), value);
if (sum)
{
g_ptr_array_index (array, i) = sum;
_gtk_css_value_unref (value);
return;
}
else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order)
{
g_ptr_array_insert (array, i, value);
return;
}
}
g_ptr_array_add (array, value);
}
static GtkCssValue *
gtk_css_value_calc_compute (GtkCssValue *value,
guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
GtkCssValue *result;
GPtrArray *array;
gboolean changed = FALSE;
gsize i;
array = g_ptr_array_new ();
for (i = 0; i < value->n_terms; i++)
{
GtkCssValue *computed = _gtk_css_value_compute (value->terms[i], property_id, provider, style, parent_style);
changed |= computed != value->terms[i];
gtk_css_calc_array_add (array, computed);
}
if (changed)
{
result = gtk_css_value_new_from_array (array);
}
else
{
g_ptr_array_set_free_func (array, (GDestroyNotify) _gtk_css_value_unref);
g_ptr_array_free (array, TRUE);
result = _gtk_css_value_ref (value);
}
return result;
}
static gboolean
gtk_css_value_calc_equal (const GtkCssValue *value1,
const GtkCssValue *value2)
{
gsize i;
if (value1->n_terms != value2->n_terms)
return FALSE;
for (i = 0; i < value1->n_terms; i++)
{
if (!_gtk_css_value_equal (value1->terms[i], value2->terms[i]))
return FALSE;
}
return TRUE;
}
static void
gtk_css_value_calc_print (const GtkCssValue *value,
GString *string)
{
gsize i;
g_string_append (string, "calc(");
_gtk_css_value_print (value->terms[0], string);
for (i = 1; i < value->n_terms; i++)
{
g_string_append (string, " + ");
_gtk_css_value_print (value->terms[i], string);
}
g_string_append (string, ")");
}
static double
gtk_css_value_calc_get (const GtkCssValue *value,
double one_hundred_percent)
{
double result = 0.0;
gsize i;
for (i = 0; i < value->n_terms; i++)
{
result += _gtk_css_number_value_get (value->terms[i], one_hundred_percent);
}
return result;
}
static GtkCssDimension
gtk_css_value_calc_get_dimension (const GtkCssValue *value)
{
GtkCssDimension dimension = GTK_CSS_DIMENSION_PERCENTAGE;
gsize i;
for (i = 0; i < value->n_terms && dimension == GTK_CSS_DIMENSION_PERCENTAGE; i++)
{
dimension = gtk_css_number_value_get_dimension (value->terms[i]);
}
return dimension;
}
static gboolean
gtk_css_value_calc_has_percent (const GtkCssValue *value)
{
gsize i;
for (i = 0; i < value->n_terms; i++)
{
if (gtk_css_number_value_has_percent (value->terms[i]))
return TRUE;
}
return FALSE;
}
static GtkCssValue *
gtk_css_value_calc_multiply (GtkCssValue *value,
double factor)
{
GtkCssValue *result;
gsize i;
result = gtk_css_calc_value_new (value->n_terms);
for (i = 0; i < value->n_terms; i++)
{
result->terms[i] = gtk_css_number_value_multiply (value->terms[i], factor);
}
return result;
}
static GtkCssValue *
gtk_css_value_calc_try_add (GtkCssValue *value1,
GtkCssValue *value2)
{
return NULL;
}
static gint
gtk_css_value_calc_get_calc_term_order (const GtkCssValue *value)
{
/* This should never be needed because calc() can't contain calc(),
* but eh...
*/
return 0;
}
static const GtkCssNumberValueClass GTK_CSS_VALUE_CALC = {
{
"GtkCssCalcValue",
gtk_css_value_calc_free,
gtk_css_value_calc_compute,
gtk_css_value_calc_equal,
gtk_css_number_value_transition,
NULL,
NULL,
gtk_css_value_calc_print
},
gtk_css_value_calc_get,
gtk_css_value_calc_get_dimension,
gtk_css_value_calc_has_percent,
gtk_css_value_calc_multiply,
gtk_css_value_calc_try_add,
gtk_css_value_calc_get_calc_term_order
};
static GtkCssValue *
gtk_css_calc_value_new (gsize n_terms)
{
GtkCssValue *result;
result = _gtk_css_value_alloc (&GTK_CSS_VALUE_CALC.value_class,
gtk_css_value_calc_get_size (n_terms));
result->n_terms = n_terms;
return result;
}
GtkCssValue *
gtk_css_calc_value_new_sum (GtkCssValue *value1,
GtkCssValue *value2)
{
GPtrArray *array;
gsize i;
array = g_ptr_array_new ();
if (value1->class == &GTK_CSS_VALUE_CALC.value_class)
{
for (i = 0; i < value1->n_terms; i++)
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value1->terms[i]));
}
}
else
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value1));
}
if (value2->class == &GTK_CSS_VALUE_CALC.value_class)
{
for (i = 0; i < value2->n_terms; i++)
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value2->terms[i]));
}
}
else
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value2));
}
return gtk_css_value_new_from_array (array);
}
GtkCssValue * gtk_css_calc_value_parse_sum (GtkCssParser *parser,
GtkCssNumberParseFlags flags);

View File

@ -22,9 +22,6 @@
G_BEGIN_DECLS
GtkCssValue * gtk_css_calc_value_new_sum (GtkCssValue *value1,
GtkCssValue *value2);
GtkCssValue * gtk_css_calc_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);

View File

@ -19,370 +19,6 @@
#include "gtkcssdimensionvalueprivate.h"
#include "gtkcssenumvalueprivate.h"
#include "gtkstylepropertyprivate.h"
#include "fallback-c89.c"
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
GtkCssUnit unit;
double value;
};
static void
gtk_css_value_dimension_free (GtkCssValue *value)
{
g_slice_free (GtkCssValue, value);
}
static double
get_base_font_size_px (guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
{
if (parent_style)
return _gtk_css_number_value_get (parent_style->core->font_size, 100);
else
return gtk_css_font_size_get_default_px (provider, style);
}
return _gtk_css_number_value_get (style->core->font_size, 100);
}
static double
get_dpi (GtkCssStyle *style)
{
return _gtk_css_number_value_get (style->core->dpi, 96);
}
static GtkCssValue *
gtk_css_value_dimension_compute (GtkCssValue *number,
guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
switch (number->unit)
{
case GTK_CSS_PERCENT:
/* percentages for font sizes are computed, other percentages aren't */
if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
return gtk_css_dimension_value_new (number->value / 100.0 *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
G_GNUC_FALLTHROUGH;
case GTK_CSS_NUMBER:
case GTK_CSS_PX:
case GTK_CSS_DEG:
case GTK_CSS_S:
return _gtk_css_value_ref (number);
case GTK_CSS_PT:
return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0,
GTK_CSS_PX);
case GTK_CSS_PC:
return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 * 12.0,
GTK_CSS_PX);
case GTK_CSS_IN:
return gtk_css_dimension_value_new (number->value * get_dpi (style),
GTK_CSS_PX);
case GTK_CSS_CM:
return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.39370078740157477,
GTK_CSS_PX);
case GTK_CSS_MM:
return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.039370078740157477,
GTK_CSS_PX);
case GTK_CSS_EM:
return gtk_css_dimension_value_new (number->value *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
case GTK_CSS_EX:
/* for now we pretend ex is half of em */
return gtk_css_dimension_value_new (number->value * 0.5 *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
case GTK_CSS_REM:
return gtk_css_dimension_value_new (number->value *
gtk_css_font_size_get_default_px (provider, style),
GTK_CSS_PX);
case GTK_CSS_RAD:
return gtk_css_dimension_value_new (number->value * 360.0 / (2 * G_PI),
GTK_CSS_DEG);
case GTK_CSS_GRAD:
return gtk_css_dimension_value_new (number->value * 360.0 / 400.0,
GTK_CSS_DEG);
case GTK_CSS_TURN:
return gtk_css_dimension_value_new (number->value * 360.0,
GTK_CSS_DEG);
case GTK_CSS_MS:
return gtk_css_dimension_value_new (number->value / 1000.0,
GTK_CSS_S);
default:
g_assert_not_reached();
}
}
static gboolean
gtk_css_value_dimension_equal (const GtkCssValue *number1,
const GtkCssValue *number2)
{
return number1->unit == number2->unit &&
number1->value == number2->value;
}
static void
gtk_css_value_dimension_print (const GtkCssValue *number,
GString *string)
{
char buf[G_ASCII_DTOSTR_BUF_SIZE];
const char *names[] = {
/* [GTK_CSS_NUMBER] = */ "",
/* [GTK_CSS_PERCENT] = */ "%",
/* [GTK_CSS_PX] = */ "px",
/* [GTK_CSS_PT] = */ "pt",
/* [GTK_CSS_EM] = */ "em",
/* [GTK_CSS_EX] = */ "ex",
/* [GTK_CSS_REM] = */ "rem",
/* [GTK_CSS_PC] = */ "pc",
/* [GTK_CSS_IN] = */ "in",
/* [GTK_CSS_CM] = */ "cm",
/* [GTK_CSS_MM] = */ "mm",
/* [GTK_CSS_RAD] = */ "rad",
/* [GTK_CSS_DEG] = */ "deg",
/* [GTK_CSS_GRAD] = */ "grad",
/* [GTK_CSS_TURN] = */ "turn",
/* [GTK_CSS_S] = */ "s",
/* [GTK_CSS_MS] = */ "ms",
};
if (isinf (number->value))
g_string_append (string, "infinite");
else
{
g_ascii_dtostr (buf, sizeof (buf), number->value);
g_string_append (string, buf);
if (number->value != 0.0)
g_string_append (string, names[number->unit]);
}
}
static double
gtk_css_value_dimension_get (const GtkCssValue *value,
double one_hundred_percent)
{
if (value->unit == GTK_CSS_PERCENT)
return value->value * one_hundred_percent / 100;
else
return value->value;
}
static GtkCssDimension
gtk_css_value_dimension_get_dimension (const GtkCssValue *value)
{
return gtk_css_unit_get_dimension (value->unit);
}
static gboolean
gtk_css_value_dimension_has_percent (const GtkCssValue *value)
{
return gtk_css_unit_get_dimension (value->unit) == GTK_CSS_DIMENSION_PERCENTAGE;
}
static GtkCssValue *
gtk_css_value_dimension_multiply (GtkCssValue *value,
double factor)
{
return gtk_css_dimension_value_new (value->value * factor, value->unit);
}
static GtkCssValue *
gtk_css_value_dimension_try_add (GtkCssValue *value1,
GtkCssValue *value2)
{
if (value1->unit != value2->unit)
return NULL;
if (value1->value == 0)
return _gtk_css_value_ref (value2);
if (value2->value == 0)
return _gtk_css_value_ref (value1);
return gtk_css_dimension_value_new (value1->value + value2->value, value1->unit);
}
static gint
gtk_css_value_dimension_get_calc_term_order (const GtkCssValue *value)
{
/* note: the order is alphabetic */
guint order_per_unit[] = {
/* [GTK_CSS_NUMBER] = */ 0,
/* [GTK_CSS_PERCENT] = */ 16,
/* [GTK_CSS_PX] = */ 11,
/* [GTK_CSS_PT] = */ 10,
/* [GTK_CSS_EM] = */ 3,
/* [GTK_CSS_EX] = */ 4,
/* [GTK_CSS_REM] = */ 13,
/* [GTK_CSS_PC] = */ 9,
/* [GTK_CSS_IN] = */ 6,
/* [GTK_CSS_CM] = */ 1,
/* [GTK_CSS_MM] = */ 7,
/* [GTK_CSS_RAD] = */ 12,
/* [GTK_CSS_DEG] = */ 2,
/* [GTK_CSS_GRAD] = */ 5,
/* [GTK_CSS_TURN] = */ 15,
/* [GTK_CSS_S] = */ 14,
/* [GTK_CSS_MS] = */ 8
};
return 1000 + order_per_unit[value->unit];
}
static GtkCssValue *
gtk_css_value_dimension_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress)
{
if (start->unit == end->unit)
return gtk_css_dimension_value_new (start->value + (end->value - start->value) * progress, start->unit);
return gtk_css_number_value_transition (start, end, property_id, progress);
}
static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = {
{
"GtkCssDimensionValue",
gtk_css_value_dimension_free,
gtk_css_value_dimension_compute,
gtk_css_value_dimension_equal,
gtk_css_value_dimension_transition,
NULL,
NULL,
gtk_css_value_dimension_print
},
gtk_css_value_dimension_get,
gtk_css_value_dimension_get_dimension,
gtk_css_value_dimension_has_percent,
gtk_css_value_dimension_multiply,
gtk_css_value_dimension_try_add,
gtk_css_value_dimension_get_calc_term_order
};
GtkCssValue *
gtk_css_dimension_value_new (double value,
GtkCssUnit unit)
{
static GtkCssValue number_singletons[] = {
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 0 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 1 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_NUMBER, 96 }, /* DPI default */
};
static GtkCssValue px_singletons[] = {
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 0 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 1 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 2 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 3 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 4 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 8 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 16 }, /* Icon size default */
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 32 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PX, 64 },
};
static GtkCssValue percent_singletons[] = {
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_PERCENT, 0 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 50 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, FALSE, GTK_CSS_PERCENT, 100 },
};
static GtkCssValue second_singletons[] = {
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 0 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_S, 1 },
};
static GtkCssValue deg_singletons[] = {
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 0 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 90 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 180 },
{ &GTK_CSS_VALUE_DIMENSION.value_class, 1, TRUE, GTK_CSS_DEG, 270 },
};
GtkCssValue *result;
switch ((guint)unit)
{
case GTK_CSS_NUMBER:
if (value == 0 || value == 1)
return _gtk_css_value_ref (&number_singletons[(int) value]);
if (value == 96)
return _gtk_css_value_ref (&number_singletons[2]);
break;
case GTK_CSS_PX:
if (value == 0 ||
value == 1 ||
value == 2 ||
value == 3 ||
value == 4)
return _gtk_css_value_ref (&px_singletons[(int) value]);
if (value == 8)
return _gtk_css_value_ref (&px_singletons[5]);
if (value == 16)
return _gtk_css_value_ref (&px_singletons[6]);
if (value == 32)
return _gtk_css_value_ref (&px_singletons[7]);
if (value == 64)
return _gtk_css_value_ref (&px_singletons[8]);
break;
case GTK_CSS_PERCENT:
if (value == 0)
return _gtk_css_value_ref (&percent_singletons[0]);
if (value == 50)
return _gtk_css_value_ref (&percent_singletons[1]);
if (value == 100)
return _gtk_css_value_ref (&percent_singletons[2]);
break;
case GTK_CSS_S:
if (value == 0 || value == 1)
return _gtk_css_value_ref (&second_singletons[(int)value]);
break;
case GTK_CSS_DEG:
if (value == 0)
return _gtk_css_value_ref (&deg_singletons[0]);
if (value == 90)
return _gtk_css_value_ref (&deg_singletons[1]);
if (value == 180)
return _gtk_css_value_ref (&deg_singletons[2]);
if (value == 270)
return _gtk_css_value_ref (&deg_singletons[3]);
break;
default:
;
}
result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_DIMENSION.value_class);
result->unit = unit;
result->value = value;
result->is_computed = value == 0 ||
unit == GTK_CSS_NUMBER ||
unit == GTK_CSS_PX ||
unit == GTK_CSS_DEG ||
unit == GTK_CSS_S;
return result;
}
GtkCssValue *
gtk_css_dimension_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags)
@ -495,15 +131,3 @@ gtk_css_dimension_value_parse (GtkCssParser *parser,
return result;
}
gboolean
gtk_css_dimension_value_is_zero (const GtkCssValue *value)
{
if (!value)
return TRUE;
if (value->class != &GTK_CSS_VALUE_DIMENSION.value_class)
return FALSE;
return value->value == 0;
}

View File

@ -24,14 +24,8 @@
G_BEGIN_DECLS
GtkCssValue * gtk_css_dimension_value_new (double value,
GtkCssUnit unit);
GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE;
G_END_DECLS
#endif /* __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ */

View File

@ -20,10 +20,13 @@
#include "config.h"
#include "gtkcssdynamicprivate.h"
#include "gtkprogresstrackerprivate.h"
G_DEFINE_TYPE (GtkCssDynamic, gtk_css_dynamic, GTK_TYPE_STYLE_ANIMATION)
struct _GtkCssDynamic
{
GtkStyleAnimation parent;
gint64 timestamp;
};
static GtkStyleAnimation *
gtk_css_dynamic_advance (GtkStyleAnimation *style_animation,
@ -36,13 +39,13 @@ static void
gtk_css_dynamic_apply_values (GtkStyleAnimation *style_animation,
GtkCssAnimatedStyle *style)
{
GtkCssDynamic *dynamic = GTK_CSS_DYNAMIC (style_animation);
GtkCssDynamic *dynamic = (GtkCssDynamic *)style_animation;
guint i;
for (i = 0; i < GTK_CSS_PROPERTY_N_PROPERTIES; i++)
{
GtkCssValue *value, *dynamic_value;
value = gtk_css_style_get_value (GTK_CSS_STYLE (style), i);
dynamic_value = gtk_css_value_get_dynamic_value (value, dynamic->timestamp);
if (value != dynamic_value)
@ -65,30 +68,29 @@ gtk_css_dynamic_is_static (GtkStyleAnimation *style_animation)
}
static void
gtk_css_dynamic_class_init (GtkCssDynamicClass *klass)
gtk_css_dynamic_free (GtkStyleAnimation *animation)
{
GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass);
animation_class->advance = gtk_css_dynamic_advance;
animation_class->apply_values = gtk_css_dynamic_apply_values;
animation_class->is_finished = gtk_css_dynamic_is_finished;
animation_class->is_static = gtk_css_dynamic_is_static;
g_slice_free (GtkCssDynamic, (GtkCssDynamic *)animation);
}
static void
gtk_css_dynamic_init (GtkCssDynamic *dynamic)
{
}
static const GtkStyleAnimationClass GTK_CSS_DYNAMIC_CLASS = {
"GtkCssDynamic",
gtk_css_dynamic_free,
gtk_css_dynamic_is_finished,
gtk_css_dynamic_is_static,
gtk_css_dynamic_apply_values,
gtk_css_dynamic_advance,
};
GtkStyleAnimation *
gtk_css_dynamic_new (gint64 timestamp)
{
GtkCssDynamic *dynamic;
dynamic = g_object_new (GTK_TYPE_CSS_DYNAMIC, NULL);
GtkCssDynamic *dynamic = g_slice_alloc (sizeof (GtkCssDynamic));
dynamic->parent.class = &GTK_CSS_DYNAMIC_CLASS;
dynamic->parent.ref_count = 1;
dynamic->timestamp = timestamp;
return GTK_STYLE_ANIMATION (dynamic);
return (GtkStyleAnimation *)dynamic;
}

View File

@ -26,27 +26,7 @@
G_BEGIN_DECLS
#define GTK_TYPE_CSS_DYNAMIC (gtk_css_dynamic_get_type ())
#define GTK_CSS_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_DYNAMIC, GtkCssDynamic))
#define GTK_CSS_DYNAMIC_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_DYNAMIC, GtkCssDynamicClass))
#define GTK_IS_CSS_DYNAMIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_DYNAMIC))
#define GTK_IS_CSS_DYNAMIC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_DYNAMIC))
#define GTK_CSS_DYNAMIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_DYNAMIC, GtkCssDynamicClass))
typedef struct _GtkCssDynamic GtkCssDynamic;
typedef struct _GtkCssDynamicClass GtkCssDynamicClass;
struct _GtkCssDynamic
{
GtkStyleAnimation parent;
gint64 timestamp;
};
struct _GtkCssDynamicClass
{
GtkStyleAnimationClass parent_class;
};
GType gtk_css_dynamic_get_type (void) G_GNUC_CONST;

View File

@ -294,7 +294,7 @@ parse_progress (GtkCssParser *parser,
if (*progress > 1.0)
{
gtk_css_parser_error_value (parser, "Percentages over 100%% are not allowed");
gtk_css_parser_error_value (parser, "Percentages over 100%% are not allowed. Given value: %f", *progress);
return FALSE;
}

View File

@ -20,39 +20,633 @@
#include "gtkcssnumbervalueprivate.h"
#include "gtkcsscalcvalueprivate.h"
#include "gtkcssenumvalueprivate.h"
#include "gtkcssdimensionvalueprivate.h"
#include "gtkcssstyleprivate.h"
#include "gtkprivate.h"
static GtkCssValue * gtk_css_calc_value_new (guint n_terms);
static GtkCssValue * gtk_css_calc_value_new_sum (GtkCssValue *a,
GtkCssValue *b);
enum {
TYPE_CALC = 0,
TYPE_DIMENSION = 1,
};
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
guint type : 1; /* Calc or dimension */
union {
struct {
GtkCssUnit unit;
double value;
} dimension;
struct {
guint n_terms;
GtkCssValue *terms[1];
} calc;
};
};
static GtkCssValue *
gtk_css_calc_value_new_from_array (GtkCssValue **values,
guint n_values)
{
GtkCssValue *result;
if (n_values > 1)
{
result = gtk_css_calc_value_new (n_values);
memcpy (result->calc.terms, values, n_values * sizeof (GtkCssValue *));
}
else
{
result = values[0];
}
return result;
}
static void
gtk_css_value_number_free (GtkCssValue *value)
{
g_slice_free (GtkCssValue, value);
}
static double
get_dpi (GtkCssStyle *style)
{
return _gtk_css_number_value_get (style->core->dpi, 96);
}
static double
get_base_font_size_px (guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
{
if (parent_style)
return _gtk_css_number_value_get (parent_style->core->font_size, 100);
else
return gtk_css_font_size_get_default_px (provider, style);
}
return _gtk_css_number_value_get (style->core->font_size, 100);
}
static GtkCssValue *
gtk_css_value_number_compute (GtkCssValue *number,
guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
double value;
if (G_UNLIKELY (number->type == TYPE_CALC))
{
const guint n_terms = number->calc.n_terms;
GtkCssValue *result;
gboolean changed = FALSE;
gsize i;
GtkCssValue **new_values;
new_values = g_alloca (sizeof (GtkCssValue *) * n_terms);
for (i = 0; i < n_terms; i++)
{
GtkCssValue *computed = _gtk_css_value_compute (number->calc.terms[i],
property_id, provider, style,
parent_style);
changed |= computed != number->calc.terms[i];
new_values[i] = computed;
}
if (changed)
{
result = gtk_css_calc_value_new_from_array (new_values, n_terms);
}
else
{
for (i = 0; i < n_terms; i++)
gtk_css_value_unref (new_values[i]);
result = _gtk_css_value_ref (number);
}
return result;
}
g_assert (number->type == TYPE_DIMENSION);
value = number->dimension.value;
switch (number->dimension.unit)
{
case GTK_CSS_PERCENT:
/* percentages for font sizes are computed, other percentages aren't */
if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
return gtk_css_dimension_value_new (value / 100.0 *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
G_GNUC_FALLTHROUGH;
case GTK_CSS_NUMBER:
case GTK_CSS_PX:
case GTK_CSS_DEG:
case GTK_CSS_S:
return _gtk_css_value_ref (number);
case GTK_CSS_PT:
return gtk_css_dimension_value_new (value * get_dpi (style) / 72.0,
GTK_CSS_PX);
case GTK_CSS_PC:
return gtk_css_dimension_value_new (value * get_dpi (style) / 72.0 * 12.0,
GTK_CSS_PX);
case GTK_CSS_IN:
return gtk_css_dimension_value_new (value * get_dpi (style),
GTK_CSS_PX);
case GTK_CSS_CM:
return gtk_css_dimension_value_new (value * get_dpi (style) * 0.39370078740157477,
GTK_CSS_PX);
case GTK_CSS_MM:
return gtk_css_dimension_value_new (value * get_dpi (style) * 0.039370078740157477,
GTK_CSS_PX);
case GTK_CSS_EM:
return gtk_css_dimension_value_new (value *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
case GTK_CSS_EX:
/* for now we pretend ex is half of em */
return gtk_css_dimension_value_new (value * 0.5 *
get_base_font_size_px (property_id, provider, style, parent_style),
GTK_CSS_PX);
case GTK_CSS_REM:
return gtk_css_dimension_value_new (value *
gtk_css_font_size_get_default_px (provider, style),
GTK_CSS_PX);
case GTK_CSS_RAD:
return gtk_css_dimension_value_new (value * 360.0 / (2 * G_PI),
GTK_CSS_DEG);
case GTK_CSS_GRAD:
return gtk_css_dimension_value_new (value * 360.0 / 400.0,
GTK_CSS_DEG);
case GTK_CSS_TURN:
return gtk_css_dimension_value_new (value * 360.0,
GTK_CSS_DEG);
case GTK_CSS_MS:
return gtk_css_dimension_value_new (value / 1000.0,
GTK_CSS_S);
default:
g_assert_not_reached();
}
}
static gboolean
gtk_css_value_number_equal (const GtkCssValue *val1,
const GtkCssValue *val2)
{
guint i;
if (val1->type != val2->type)
return FALSE;
if (G_LIKELY (val1->type == TYPE_DIMENSION))
{
return val1->dimension.unit == val2->dimension.unit &&
val1->dimension.value == val2->dimension.value;
}
g_assert (val1->type == TYPE_CALC);
if (val1->calc.n_terms != val2->calc.n_terms)
return FALSE;
for (i = 0; i < val1->calc.n_terms; i++)
{
if (!_gtk_css_value_equal (val1->calc.terms[i], val2->calc.terms[i]))
return FALSE;
}
return TRUE;
}
static void
gtk_css_value_number_print (const GtkCssValue *value,
GString *string)
{
guint i;
if (G_LIKELY (value->type == TYPE_DIMENSION))
{
const char *names[] = {
/* [GTK_CSS_NUMBER] = */ "",
/* [GTK_CSS_PERCENT] = */ "%",
/* [GTK_CSS_PX] = */ "px",
/* [GTK_CSS_PT] = */ "pt",
/* [GTK_CSS_EM] = */ "em",
/* [GTK_CSS_EX] = */ "ex",
/* [GTK_CSS_REM] = */ "rem",
/* [GTK_CSS_PC] = */ "pc",
/* [GTK_CSS_IN] = */ "in",
/* [GTK_CSS_CM] = */ "cm",
/* [GTK_CSS_MM] = */ "mm",
/* [GTK_CSS_RAD] = */ "rad",
/* [GTK_CSS_DEG] = */ "deg",
/* [GTK_CSS_GRAD] = */ "grad",
/* [GTK_CSS_TURN] = */ "turn",
/* [GTK_CSS_S] = */ "s",
/* [GTK_CSS_MS] = */ "ms",
};
char buf[G_ASCII_DTOSTR_BUF_SIZE];
if (isinf (value->dimension.value))
g_string_append (string, "infinite");
else
{
g_ascii_dtostr (buf, sizeof (buf), value->dimension.value);
g_string_append (string, buf);
if (value->dimension.value != 0.0)
g_string_append (string, names[value->dimension.unit]);
}
return;
}
g_assert (value->type == TYPE_CALC);
g_string_append (string, "calc(");
_gtk_css_value_print (value->calc.terms[0], string);
for (i = 1; i < value->calc.n_terms; i++)
{
g_string_append (string, " + ");
_gtk_css_value_print (value->calc.terms[i], string);
}
g_string_append (string, ")");
}
static GtkCssValue *
gtk_css_value_number_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress)
{
GtkCssValue *result, *mul_start, *mul_end;
if (start == end)
return _gtk_css_value_ref (start);
if (G_LIKELY (start->type == TYPE_DIMENSION && end->type == TYPE_DIMENSION))
{
if (start->dimension.unit == end->dimension.unit)
{
const double start_value = start->dimension.value;
const double end_value = end->dimension.value;
return gtk_css_dimension_value_new (start_value + (end_value - start_value) * progress,
start->dimension.unit);
}
}
mul_start = gtk_css_number_value_multiply (start, 1 - progress);
mul_end = gtk_css_number_value_multiply (end, progress);
result = gtk_css_number_value_add (mul_start, mul_end);
_gtk_css_value_unref (mul_start);
_gtk_css_value_unref (mul_end);
return result;
}
static const GtkCssValueClass GTK_CSS_VALUE_NUMBER = {
"GtkCssNumberValue",
gtk_css_value_number_free,
gtk_css_value_number_compute,
gtk_css_value_number_equal,
gtk_css_value_number_transition,
NULL,
NULL,
gtk_css_value_number_print
};
static gsize
gtk_css_value_calc_get_size (gsize n_terms)
{
g_assert (n_terms > 0);
return sizeof (GtkCssValue) + sizeof (GtkCssValue *) * (n_terms - 1);
}
static GtkCssValue *
gtk_css_calc_value_new (guint n_terms)
{
GtkCssValue *result;
result = _gtk_css_value_alloc (&GTK_CSS_VALUE_NUMBER,
gtk_css_value_calc_get_size (n_terms));
result->type = TYPE_CALC;
result->calc.n_terms = n_terms;
return result;
}
GtkCssValue *
gtk_css_dimension_value_new (double value,
GtkCssUnit unit)
{
static GtkCssValue number_singletons[] = {
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 0 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 1 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_NUMBER, 96 }} }, /* DPI default */
};
static GtkCssValue px_singletons[] = {
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 0 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 1 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 2 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 3 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 4 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 8 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 16 }} }, /* Icon size default */
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 32 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PX, 64 }} },
};
static GtkCssValue percent_singletons[] = {
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 0 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, FALSE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 50 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, FALSE, TYPE_DIMENSION, {{ GTK_CSS_PERCENT, 100 }} },
};
static GtkCssValue second_singletons[] = {
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_S, 0 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_S, 1 }} },
};
static GtkCssValue deg_singletons[] = {
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 0 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 90 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 180 }} },
{ &GTK_CSS_VALUE_NUMBER, 1, TRUE, TYPE_DIMENSION, {{ GTK_CSS_DEG, 270 }} },
};
GtkCssValue *result;
switch ((guint)unit)
{
case GTK_CSS_NUMBER:
if (value == 0 || value == 1)
return _gtk_css_value_ref (&number_singletons[(int) value]);
if (value == 96)
return _gtk_css_value_ref (&number_singletons[2]);
break;
case GTK_CSS_PX:
if (value == 0 ||
value == 1 ||
value == 2 ||
value == 3 ||
value == 4)
return _gtk_css_value_ref (&px_singletons[(int) value]);
if (value == 8)
return _gtk_css_value_ref (&px_singletons[5]);
if (value == 16)
return _gtk_css_value_ref (&px_singletons[6]);
if (value == 32)
return _gtk_css_value_ref (&px_singletons[7]);
if (value == 64)
return _gtk_css_value_ref (&px_singletons[8]);
break;
case GTK_CSS_PERCENT:
if (value == 0)
return _gtk_css_value_ref (&percent_singletons[0]);
if (value == 50)
return _gtk_css_value_ref (&percent_singletons[1]);
if (value == 100)
return _gtk_css_value_ref (&percent_singletons[2]);
break;
case GTK_CSS_S:
if (value == 0 || value == 1)
return _gtk_css_value_ref (&second_singletons[(int)value]);
break;
case GTK_CSS_DEG:
if (value == 0)
return _gtk_css_value_ref (&deg_singletons[0]);
if (value == 90)
return _gtk_css_value_ref (&deg_singletons[1]);
if (value == 180)
return _gtk_css_value_ref (&deg_singletons[2]);
if (value == 270)
return _gtk_css_value_ref (&deg_singletons[3]);
break;
default:
;
}
result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_NUMBER);
result->type = TYPE_DIMENSION;
result->dimension.unit = unit;
result->dimension.value = value;
result->is_computed = value == 0 ||
unit == GTK_CSS_NUMBER ||
unit == GTK_CSS_PX ||
unit == GTK_CSS_DEG ||
unit == GTK_CSS_S;
if (value == 5040)
g_critical ("%s: %f", __FUNCTION__, value);
return result;
}
/*
* gtk_css_number_value_get_calc_term_order:
* @value: Value to compute order for
*
* Determines the position of @value when printed as part of a calc()
* expression. Values with lower numbers are printed first. Note that
* these numbers are arbitrary, so when adding new types of values to
* print, feel free to change them in implementations so that they
* match.
*
* Returns: Magic value determining placement when printing calc()
* expression.
*/
static int
gtk_css_number_value_get_calc_term_order (const GtkCssValue *value)
{
if (G_LIKELY (value->type == TYPE_DIMENSION))
{
/* note: the order is alphabetic */
static const guint order_per_unit[] = {
/* [GTK_CSS_NUMBER] = */ 0,
/* [GTK_CSS_PERCENT] = */ 16,
/* [GTK_CSS_PX] = */ 11,
/* [GTK_CSS_PT] = */ 10,
/* [GTK_CSS_EM] = */ 3,
/* [GTK_CSS_EX] = */ 4,
/* [GTK_CSS_REM] = */ 13,
/* [GTK_CSS_PC] = */ 9,
/* [GTK_CSS_IN] = */ 6,
/* [GTK_CSS_CM] = */ 1,
/* [GTK_CSS_MM] = */ 7,
/* [GTK_CSS_RAD] = */ 12,
/* [GTK_CSS_DEG] = */ 2,
/* [GTK_CSS_GRAD] = */ 5,
/* [GTK_CSS_TURN] = */ 15,
/* [GTK_CSS_S] = */ 14,
/* [GTK_CSS_MS] = */ 8
};
return 1000 + order_per_unit[value->dimension.unit];
}
g_assert (value->type == TYPE_CALC);
/* This should never be needed because calc() can't contain calc(),
* but eh...
*/
return 0;
}
static void
gtk_css_calc_array_add (GPtrArray *array, GtkCssValue *value)
{
gsize i;
gint calc_term_order;
calc_term_order = gtk_css_number_value_get_calc_term_order (value);
for (i = 0; i < array->len; i++)
{
GtkCssValue *sum = gtk_css_number_value_try_add (g_ptr_array_index (array, i), value);
if (sum)
{
g_ptr_array_index (array, i) = sum;
_gtk_css_value_unref (value);
return;
}
else if (gtk_css_number_value_get_calc_term_order (g_ptr_array_index (array, i)) > calc_term_order)
{
g_ptr_array_insert (array, i, value);
return;
}
}
g_ptr_array_add (array, value);
}
static GtkCssValue *
gtk_css_calc_value_new_sum (GtkCssValue *value1,
GtkCssValue *value2)
{
GPtrArray *array;
GtkCssValue *result;
gsize i;
array = g_ptr_array_new ();
if (value1->class == &GTK_CSS_VALUE_NUMBER &&
value1->type == TYPE_CALC)
{
for (i = 0; i < value1->calc.n_terms; i++)
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value1->calc.terms[i]));
}
}
else
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value1));
}
if (value2->class == &GTK_CSS_VALUE_NUMBER &&
value2->type == TYPE_CALC)
{
for (i = 0; i < value2->calc.n_terms; i++)
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value2->calc.terms[i]));
}
}
else
{
gtk_css_calc_array_add (array, _gtk_css_value_ref (value2));
}
result = gtk_css_calc_value_new_from_array ((GtkCssValue **)array->pdata, array->len);
g_ptr_array_free (array, TRUE);
return result;
}
GtkCssDimension
gtk_css_number_value_get_dimension (const GtkCssValue *value)
{
GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
GtkCssDimension dimension = GTK_CSS_DIMENSION_PERCENTAGE;
guint i;
return number_value_class->get_dimension (value);
if (G_LIKELY (value->type == TYPE_DIMENSION))
return gtk_css_unit_get_dimension (value->dimension.unit);
g_assert (value->type == TYPE_CALC);
for (i = 0; i < value->calc.n_terms && dimension == GTK_CSS_DIMENSION_PERCENTAGE; i++)
{
dimension = gtk_css_number_value_get_dimension (value->calc.terms[i]);
if (dimension != GTK_CSS_DIMENSION_PERCENTAGE)
break;
}
return dimension;
}
gboolean
gtk_css_number_value_has_percent (const GtkCssValue *value)
{
GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
guint i;
return number_value_class->has_percent (value);
if (G_LIKELY (value->type == TYPE_DIMENSION))
{
return gtk_css_unit_get_dimension (value->dimension.unit) == GTK_CSS_DIMENSION_PERCENTAGE;
}
for (i = 0; i < value->calc.n_terms; i++)
{
if (gtk_css_number_value_has_percent (value->calc.terms[i]))
return TRUE;
}
return FALSE;
}
GtkCssValue *
gtk_css_number_value_multiply (GtkCssValue *value,
double factor)
{
GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
GtkCssValue *result;
guint i;
if (factor == 1)
return _gtk_css_value_ref (value);
return number_value_class->multiply (value, factor);
if (G_LIKELY (value->type == TYPE_DIMENSION))
{
return gtk_css_dimension_value_new (value->dimension.value * factor,
value->dimension.unit);
}
g_assert (value->type == TYPE_CALC);
result = gtk_css_calc_value_new (value->calc.n_terms);
for (i = 0; i < value->calc.n_terms; i++)
result->calc.terms[i] = gtk_css_number_value_multiply (value->calc.terms[i], factor);
return result;
}
GtkCssValue *
@ -72,35 +666,27 @@ GtkCssValue *
gtk_css_number_value_try_add (GtkCssValue *value1,
GtkCssValue *value2)
{
GtkCssNumberValueClass *number_value_class;
if (value1->class != value2->class)
if (G_UNLIKELY (value1->type != value2->type))
return NULL;
number_value_class = (GtkCssNumberValueClass *) value1->class;
if (G_LIKELY (value1->type == TYPE_DIMENSION))
{
if (value1->dimension.unit != value2->dimension.unit)
return NULL;
return number_value_class->try_add (value1, value2);
}
if (value1->dimension.value == 0)
return _gtk_css_value_ref (value2);
/*
* gtk_css_number_value_get_calc_term_order:
* @value: Value to compute order for
*
* Determines the position of @value when printed as part of a calc()
* expression. Values with lower numbers are printed first. Note that
* these numbers are arbitrary, so when adding new types of values to
* print, feel free to change them in implementations so that they
* match.
*
* Returns: Magic value determining placement when printing calc()
* expression.
*/
gint
gtk_css_number_value_get_calc_term_order (const GtkCssValue *value)
{
GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class;
if (value2->dimension.value == 0)
return _gtk_css_value_ref (value1);
return number_value_class->get_calc_term_order (value);
return gtk_css_dimension_value_new (value1->dimension.value + value2->dimension.value,
value1->dimension.unit);
}
g_assert (value1->type == TYPE_CALC);
/* Not possible for calc() values */
return NULL;
}
GtkCssValue *
@ -110,28 +696,6 @@ _gtk_css_number_value_new (double value,
return gtk_css_dimension_value_new (value, unit);
}
GtkCssValue *
gtk_css_number_value_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress)
{
GtkCssValue *result, *mul_start, *mul_end;
if (start == end)
return _gtk_css_value_ref (start);
mul_start = gtk_css_number_value_multiply (start, 1 - progress);
mul_end = gtk_css_number_value_multiply (end, progress);
result = gtk_css_number_value_add (mul_start, mul_end);
_gtk_css_value_unref (mul_start);
_gtk_css_value_unref (mul_end);
return result;
}
gboolean
gtk_css_number_value_can_parse (GtkCssParser *parser)
{
@ -157,15 +721,40 @@ _gtk_css_number_value_parse (GtkCssParser *parser,
}
double
_gtk_css_number_value_get (const GtkCssValue *number,
_gtk_css_number_value_get (const GtkCssValue *value,
double one_hundred_percent)
{
GtkCssNumberValueClass *number_value_class;
double result;
guint i;
gtk_internal_return_val_if_fail (number != NULL, 0.0);
if (G_LIKELY (value->type == TYPE_DIMENSION))
{
if (value->dimension.unit == GTK_CSS_PERCENT)
return value->dimension.value * one_hundred_percent / 100;
else
return value->dimension.value;
}
number_value_class = (GtkCssNumberValueClass *) number->class;
g_assert (value->type == TYPE_CALC);
return number_value_class->get (number, one_hundred_percent);
result = 0.0;
for (i = 0; i < value->calc.n_terms; i++)
result += _gtk_css_number_value_get (value->calc.terms[i], one_hundred_percent);
return result;
}
gboolean
gtk_css_dimension_value_is_zero (const GtkCssValue *value)
{
if (!value)
return TRUE;
if (value->class != &GTK_CSS_VALUE_NUMBER)
return FALSE;
if (value->type != TYPE_DIMENSION)
return FALSE;
return value->dimension.value == 0;
}

View File

@ -35,28 +35,11 @@ typedef enum /*< skip >*/ {
GTK_CSS_PARSE_TIME = (1 << 5)
} GtkCssNumberParseFlags;
typedef struct _GtkCssNumberValueClass GtkCssNumberValueClass;
struct _GtkCssNumberValueClass {
GtkCssValueClass value_class;
double (* get) (const GtkCssValue *value,
double one_hundred_percent);
GtkCssDimension (* get_dimension) (const GtkCssValue *value);
gboolean (* has_percent) (const GtkCssValue *value);
GtkCssValue * (* multiply) (GtkCssValue *value,
double factor);
GtkCssValue * (* try_add) (GtkCssValue *value1,
GtkCssValue *value2);
gint (* get_calc_term_order) (const GtkCssValue *value);
};
GtkCssValue * gtk_css_dimension_value_new (double value,
GtkCssUnit unit);
GtkCssValue * _gtk_css_number_value_new (double value,
GtkCssUnit unit);
GtkCssValue * gtk_css_number_value_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress);
gboolean gtk_css_number_value_can_parse (GtkCssParser *parser);
GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser,
GtkCssNumberParseFlags flags);
@ -69,11 +52,10 @@ GtkCssValue * gtk_css_number_value_add (GtkCssValue *val
GtkCssValue *value2);
GtkCssValue * gtk_css_number_value_try_add (GtkCssValue *value1,
GtkCssValue *value2);
gint gtk_css_number_value_get_calc_term_order (const GtkCssValue *value);
double _gtk_css_number_value_get (const GtkCssValue *number,
double one_hundred_percent) G_GNUC_PURE;
gboolean gtk_css_dimension_value_is_zero (const GtkCssValue *value) G_GNUC_PURE;
G_END_DECLS

View File

@ -293,8 +293,6 @@ gtk_css_style_get_section (GtkCssStyle *style,
gboolean
gtk_css_style_is_static (GtkCssStyle *style)
{
gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (style), TRUE);
return GTK_CSS_STYLE_GET_CLASS (style)->is_static (style);
}

View File

@ -24,39 +24,36 @@
#include "gtkcsseasevalueprivate.h"
#include "gtkprogresstrackerprivate.h"
G_DEFINE_TYPE (GtkCssTransition, _gtk_css_transition, GTK_TYPE_STYLE_ANIMATION)
static GtkStyleAnimation *
gtk_css_transition_advance (GtkStyleAnimation *style_animation,
gint64 timestamp)
struct _GtkCssTransition
{
GtkCssTransition *source = GTK_CSS_TRANSITION (style_animation);
GtkStyleAnimation parent;
GtkCssTransition *transition;
guint property;
GtkCssValue *start;
GtkCssValue *ease;
GtkProgressTracker tracker;
guint finished;
};
transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL);
transition->property = source->property;
transition->start = _gtk_css_value_ref (source->start);
transition->ease = _gtk_css_value_ref (source->ease);
static GtkStyleAnimation * gtk_css_transition_advance (GtkStyleAnimation *style_animation,
gint64 timestamp);
gtk_progress_tracker_init_copy (&source->tracker, &transition->tracker);
gtk_progress_tracker_advance_frame (&transition->tracker, timestamp);
return GTK_STYLE_ANIMATION (transition);
}
static void
gtk_css_transition_apply_values (GtkStyleAnimation *style_animation,
GtkCssAnimatedStyle *style)
{
GtkCssTransition *transition = GTK_CSS_TRANSITION (style_animation);
GtkCssTransition *transition = (GtkCssTransition *)style_animation;
GtkCssValue *value, *end;
double progress;
GtkProgressState state;
end = gtk_css_animated_style_get_intrinsic_value (style, transition->property);
if (transition->finished)
return;
end = gtk_css_animated_style_get_intrinsic_value (style, transition->property);
state = gtk_progress_tracker_get_state (&transition->tracker);
if (state == GTK_PROGRESS_STATE_BEFORE)
@ -83,49 +80,60 @@ gtk_css_transition_apply_values (GtkStyleAnimation *style_animation,
static gboolean
gtk_css_transition_is_finished (GtkStyleAnimation *animation)
{
GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
GtkCssTransition *transition = (GtkCssTransition *)animation;
return gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
return transition->finished;
}
static gboolean
gtk_css_transition_is_static (GtkStyleAnimation *animation)
{
GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
GtkCssTransition *transition = (GtkCssTransition *)animation;
return gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
return transition->finished;
}
static void
gtk_css_transition_finalize (GObject *object)
gtk_css_transition_free (GtkStyleAnimation *animation)
{
GtkCssTransition *transition = GTK_CSS_TRANSITION (object);
GtkCssTransition *self = (GtkCssTransition *)animation;
_gtk_css_value_unref (transition->start);
_gtk_css_value_unref (transition->ease);
gtk_css_value_unref (self->start);
gtk_css_value_unref (self->ease);
G_OBJECT_CLASS (_gtk_css_transition_parent_class)->finalize (object);
g_slice_free (GtkCssTransition, self);
}
static void
_gtk_css_transition_class_init (GtkCssTransitionClass *klass)
static const GtkStyleAnimationClass GTK_CSS_TRANSITION_CLASS = {
"GtkCssTransition",
gtk_css_transition_free,
gtk_css_transition_is_finished,
gtk_css_transition_is_static,
gtk_css_transition_apply_values,
gtk_css_transition_advance,
};
static GtkStyleAnimation *
gtk_css_transition_advance (GtkStyleAnimation *style_animation,
gint64 timestamp)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkStyleAnimationClass *animation_class = GTK_STYLE_ANIMATION_CLASS (klass);
GtkCssTransition *source = (GtkCssTransition *)style_animation;
GtkCssTransition *transition;
object_class->finalize = gtk_css_transition_finalize;
transition = g_slice_alloc (sizeof (GtkCssTransition));
transition->parent.class = &GTK_CSS_TRANSITION_CLASS;
transition->parent.ref_count = 1;
animation_class->advance = gtk_css_transition_advance;
animation_class->apply_values = gtk_css_transition_apply_values;
animation_class->is_finished = gtk_css_transition_is_finished;
animation_class->is_static = gtk_css_transition_is_static;
transition->property = source->property;
transition->start = _gtk_css_value_ref (source->start);
transition->ease = _gtk_css_value_ref (source->ease);
gtk_progress_tracker_init_copy (&source->tracker, &transition->tracker);
gtk_progress_tracker_advance_frame (&transition->tracker, timestamp);
transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
return (GtkStyleAnimation *)transition;
}
static void
_gtk_css_transition_init (GtkCssTransition *transition)
{
}
GtkStyleAnimation *
_gtk_css_transition_new (guint property,
GtkCssValue *start,
@ -139,21 +147,28 @@ _gtk_css_transition_new (guint property,
g_return_val_if_fail (start != NULL, NULL);
g_return_val_if_fail (ease != NULL, NULL);
transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL);
transition = g_slice_alloc (sizeof (GtkCssTransition));
transition->parent.class = &GTK_CSS_TRANSITION_CLASS;
transition->parent.ref_count = 1;
transition->property = property;
transition->start = _gtk_css_value_ref (start);
transition->ease = _gtk_css_value_ref (ease);
gtk_progress_tracker_start (&transition->tracker, duration_us, delay_us, 1.0);
gtk_progress_tracker_advance_frame (&transition->tracker, timestamp);
transition->finished = gtk_progress_tracker_get_state (&transition->tracker) == GTK_PROGRESS_STATE_AFTER;
return GTK_STYLE_ANIMATION (transition);
return (GtkStyleAnimation*)transition;
}
guint
_gtk_css_transition_get_property (GtkCssTransition *transition)
{
g_return_val_if_fail (GTK_IS_CSS_TRANSITION (transition), 0);
return transition->property;
}
gboolean
_gtk_css_transition_is_transition (GtkStyleAnimation *animation)
{
return animation->class == &GTK_CSS_TRANSITION_CLASS;
}

View File

@ -25,25 +25,8 @@
G_BEGIN_DECLS
#define GTK_TYPE_CSS_TRANSITION (_gtk_css_transition_get_type ())
#define GTK_CSS_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_TRANSITION, GtkCssTransition))
#define GTK_CSS_TRANSITION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_TRANSITION, GtkCssTransitionClass))
#define GTK_IS_CSS_TRANSITION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_TRANSITION))
#define GTK_IS_CSS_TRANSITION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_TRANSITION))
#define GTK_CSS_TRANSITION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_TRANSITION, GtkCssTransitionClass))
typedef struct _GtkCssTransition GtkCssTransition;
typedef struct _GtkCssTransitionClass GtkCssTransitionClass;
struct _GtkCssTransition
{
GtkStyleAnimation parent;
guint property;
GtkCssValue *start;
GtkCssValue *ease;
GtkProgressTracker tracker;
};
typedef struct _GtkCssTransition GtkCssTransition;
struct _GtkCssTransitionClass
{
@ -60,6 +43,7 @@ GtkStyleAnimation * _gtk_css_transition_new (guint
gint64 delay_us);
guint _gtk_css_transition_get_property (GtkCssTransition *transition);
gboolean _gtk_css_transition_is_transition (GtkStyleAnimation *animation);
G_END_DECLS

View File

@ -263,11 +263,6 @@ _gtk_css_value_transition (GtkCssValue *start,
gtk_internal_return_val_if_fail (start != NULL, FALSE);
gtk_internal_return_val_if_fail (end != NULL, FALSE);
/* We compare functions here instead of classes so that number
* values can all transition to each other */
if (start->class->transition != end->class->transition)
return NULL;
if (progress == 0)
return _gtk_css_value_ref (start);

View File

@ -377,6 +377,8 @@ struct _GtkPrintUnixDialog
gchar *format_for_printer;
gint current_page;
GtkCssNode *collate_paper_node;
GtkCssNode *page_layout_paper_node;
};
struct _GtkPrintUnixDialogClass
@ -799,6 +801,18 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog)
gtk_css_node_set_name (gtk_widget_get_css_node (dialog->collate_image), g_quark_from_static_string ("drawing"));
gtk_css_node_set_name (gtk_widget_get_css_node (dialog->page_layout_preview), g_quark_from_static_string ("drawing"));
dialog->collate_paper_node = gtk_css_node_new();
gtk_css_node_set_name (dialog->collate_paper_node, g_quark_from_static_string ("paper"));
gtk_css_node_set_parent (dialog->collate_paper_node,
gtk_widget_get_css_node (dialog->collate_image));
g_object_unref (dialog->collate_paper_node);
dialog->page_layout_paper_node = gtk_css_node_new();
gtk_css_node_set_name (dialog->page_layout_paper_node, g_quark_from_static_string ("paper"));
gtk_css_node_set_parent (dialog->page_layout_paper_node,
gtk_widget_get_css_node (dialog->page_layout_preview));
g_object_unref (dialog->page_layout_paper_node);
}
static void
@ -2181,7 +2195,8 @@ update_collate_icon (GtkToggleButton *toggle_button,
}
static void
paint_page (GtkWidget *widget,
paint_page (GtkPrintUnixDialog *dialog,
GtkWidget *widget,
cairo_t *cr,
gint x,
gint y,
@ -2198,7 +2213,7 @@ paint_page (GtkWidget *widget,
text_y = 21;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save_named (context, "paper");
gtk_style_context_save_to_node (context, dialog->collate_paper_node);
gtk_render_background (context, cr, x, y, width, height);
gtk_render_frame (context, cr, x, y, width, height);
@ -2257,16 +2272,16 @@ draw_collate (GtkDrawingArea *da,
if (copies == 1)
{
paint_page (widget, cr, x1 + p1, y, reverse ? "1" : "2", text_x);
paint_page (widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x);
paint_page (dialog, widget, cr, x1 + p1, y, reverse ? "1" : "2", text_x);
paint_page (dialog, widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x);
}
else
{
paint_page (widget, cr, x1 + p1, y, collate == reverse ? "1" : "2", text_x);
paint_page (widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x);
paint_page (dialog, widget, cr, x1 + p1, y, collate == reverse ? "1" : "2", text_x);
paint_page (dialog, widget, cr, x1 + p2, y + 10, reverse ? "2" : "1", text_x);
paint_page (widget, cr, x2 + p1, y, reverse ? "1" : "2", text_x);
paint_page (widget, cr, x2 + p2, y + 10, collate == reverse ? "2" : "1", text_x);
paint_page (dialog, widget, cr, x2 + p1, y, reverse ? "1" : "2", text_x);
paint_page (dialog, widget, cr, x2 + p2, y + 10, collate == reverse ? "2" : "1", text_x);
}
}
@ -2731,7 +2746,7 @@ draw_page (GtkDrawingArea *da,
}
context = gtk_widget_get_style_context (widget);
gtk_style_context_save_named (context, "paper");
gtk_style_context_save_to_node (context, dialog->page_layout_paper_node);
gtk_style_context_get_color (context, &color);
pos_x = (width - w) / 2;
@ -2841,6 +2856,7 @@ draw_page (GtkDrawingArea *da,
break;
}
cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
if (horizontal)
for (y = start_y; y != end_y + dy; y += dy)
{

View File

@ -246,6 +246,7 @@ typedef struct
GtkCssNode *overshoot_node[4];
GtkCssNode *undershoot_node[4];
GtkCssNode *junction_node;
Indicator hindicator;
Indicator vindicator;
@ -1838,7 +1839,7 @@ gtk_scrolled_window_snapshot_scrollbars_junction (GtkScrolledWindow *scrolled_wi
junction_rect.height = hscr_allocation.height;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save_named (context, "junction");
gtk_style_context_save_to_node (context, priv->junction_node);
gtk_snapshot_render_background (snapshot, context,
junction_rect.x, junction_rect.y,
@ -2049,6 +2050,12 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
gtk_scrolled_window_update_use_indicators (scrolled_window);
priv->junction_node = gtk_css_node_new ();
gtk_css_node_set_name (priv->junction_node, g_quark_from_static_string ("junction"));
gtk_css_node_set_parent (priv->junction_node, widget_node);
gtk_css_node_set_state (priv->junction_node, gtk_css_node_get_state (widget_node));
g_object_unref (priv->junction_node);
controller = gtk_event_controller_scroll_new (GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES |
GTK_EVENT_CONTROLLER_SCROLL_KINETIC);
g_signal_connect (controller, "scroll-begin",
@ -4205,7 +4212,7 @@ gtk_scrolled_window_set_child (GtkScrolledWindow *scrolled_window,
}
priv->child = scrollable_child;
gtk_widget_set_parent (scrollable_child, GTK_WIDGET (scrolled_window));
gtk_widget_insert_after (scrollable_child, GTK_WIDGET (scrolled_window), NULL);
g_object_set (scrollable_child,
"hadjustment", hadj,

View File

@ -21,84 +21,47 @@
#include "gtkstyleanimationprivate.h"
G_DEFINE_ABSTRACT_TYPE (GtkStyleAnimation, _gtk_style_animation, G_TYPE_OBJECT)
static GtkStyleAnimation *
gtk_style_animation_real_advance (GtkStyleAnimation *animation,
gint64 timestamp)
{
return NULL;
}
static void
gtk_style_animation_real_apply_values (GtkStyleAnimation *animation,
GtkCssAnimatedStyle *style)
{
}
static gboolean
gtk_style_animation_real_is_finished (GtkStyleAnimation *animation)
{
return TRUE;
}
static gboolean
gtk_style_animation_real_is_static (GtkStyleAnimation *animation)
{
return FALSE;
}
static void
_gtk_style_animation_class_init (GtkStyleAnimationClass *klass)
{
klass->advance = gtk_style_animation_real_advance;
klass->apply_values = gtk_style_animation_real_apply_values;
klass->is_finished = gtk_style_animation_real_is_finished;
klass->is_static = gtk_style_animation_real_is_static;
}
static void
_gtk_style_animation_init (GtkStyleAnimation *animation)
{
}
GtkStyleAnimation *
_gtk_style_animation_advance (GtkStyleAnimation *animation,
gint64 timestamp)
_gtk_style_animation_advance (GtkStyleAnimation *animation,
gint64 timestamp)
{
GtkStyleAnimationClass *klass;
g_assert (animation != NULL);
g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), NULL);
klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
return klass->advance (animation, timestamp);
return animation->class->advance (animation, timestamp);
}
void
_gtk_style_animation_apply_values (GtkStyleAnimation *animation,
GtkCssAnimatedStyle *style)
{
GtkStyleAnimationClass *klass;
g_return_if_fail (GTK_IS_STYLE_ANIMATION (animation));
g_return_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style));
klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
klass->apply_values (animation, style);
animation->class->apply_values (animation, style);
}
gboolean
_gtk_style_animation_is_finished (GtkStyleAnimation *animation)
{
GtkStyleAnimationClass *klass;
return animation->class->is_finished (animation);
}
g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), TRUE);
klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
GtkStyleAnimation *
gtk_style_animation_ref (GtkStyleAnimation *animation)
{
animation->ref_count++;
return animation;
}
return klass->is_finished (animation);
GtkStyleAnimation *
gtk_style_animation_unref (GtkStyleAnimation *animation)
{
animation->ref_count--;
if (animation->ref_count == 0)
{
animation->class->free (animation);
return NULL;
}
return animation;
}
/**
@ -115,11 +78,5 @@ _gtk_style_animation_is_finished (GtkStyleAnimation *animation)
gboolean
_gtk_style_animation_is_static (GtkStyleAnimation *animation)
{
GtkStyleAnimationClass *klass;
g_return_val_if_fail (GTK_IS_STYLE_ANIMATION (animation), TRUE);
klass = GTK_STYLE_ANIMATION_GET_CLASS (animation);
return klass->is_static (animation);
return animation->class->is_static (animation);
}

View File

@ -24,25 +24,19 @@
G_BEGIN_DECLS
#define GTK_TYPE_STYLE_ANIMATION (_gtk_style_animation_get_type ())
#define GTK_STYLE_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimation))
#define GTK_STYLE_ANIMATION_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimationClass))
#define GTK_IS_STYLE_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_STYLE_ANIMATION))
#define GTK_IS_STYLE_ANIMATION_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_STYLE_ANIMATION))
#define GTK_STYLE_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STYLE_ANIMATION, GtkStyleAnimationClass))
typedef struct _GtkStyleAnimation GtkStyleAnimation;
typedef struct _GtkStyleAnimationClass GtkStyleAnimationClass;
struct _GtkStyleAnimation
{
GObject parent;
const GtkStyleAnimationClass *class;
guint ref_count;
};
struct _GtkStyleAnimationClass
{
GObjectClass parent_class;
const char *type_name;
void (* free) (GtkStyleAnimation *animation);
gboolean (* is_finished) (GtkStyleAnimation *animation);
gboolean (* is_static) (GtkStyleAnimation *animation);
void (* apply_values) (GtkStyleAnimation *animation,
@ -60,6 +54,9 @@ void _gtk_style_animation_apply_values (GtkStyleAnimation
gboolean _gtk_style_animation_is_finished (GtkStyleAnimation *animation);
gboolean _gtk_style_animation_is_static (GtkStyleAnimation *animation);
GtkStyleAnimation * gtk_style_animation_ref (GtkStyleAnimation *animation);
GtkStyleAnimation * gtk_style_animation_unref (GtkStyleAnimation *animation);
G_END_DECLS

View File

@ -471,42 +471,6 @@ gtk_style_context_remove_provider_for_display (GdkDisplay *display,
_gtk_style_cascade_remove_provider (cascade, provider);
}
/*
* gtk_style_context_set_id:
* @context: a #GtkStyleContext
* @id: (allow-none): the id to use or %NULL for none.
*
* Sets the CSS ID to be used when obtaining style information.
**/
void
gtk_style_context_set_id (GtkStyleContext *context,
const char *id)
{
GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
gtk_css_node_set_id (priv->cssnode, g_quark_from_string (id));
}
/*
* gtk_style_context_get_id:
* @context: a #GtkStyleContext
*
* Returns the CSS ID used when obtaining style information.
*
* Returns: (nullable): the ID or %NULL if no ID is set.
**/
const char *
gtk_style_context_get_id (GtkStyleContext *context)
{
GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context);
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
return g_quark_to_string (gtk_css_node_get_id (priv->cssnode));
}
/**
* gtk_style_context_set_state:
* @context: a #GtkStyleContext
@ -627,29 +591,6 @@ gtk_style_context_save_to_node (GtkStyleContext *context,
priv->cssnode = g_object_ref (node);
}
void
gtk_style_context_save_named (GtkStyleContext *context,
const char *name)
{
GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context);
GtkCssNode *cssnode;
/* Make sure we have the style existing. It is the
* parent of the new saved node after all.
*/
if (!gtk_style_context_is_saved (context))
gtk_style_context_lookup_style (context);
cssnode = gtk_css_transient_node_new (priv->cssnode);
gtk_css_node_set_parent (cssnode, gtk_style_context_get_root (context));
if (name)
gtk_css_node_set_name (cssnode, g_quark_from_string (name));
gtk_style_context_save_to_node (context, cssnode);
g_object_unref (cssnode);
}
/**
* gtk_style_context_save:
* @context: a #GtkStyleContext
@ -665,9 +606,23 @@ gtk_style_context_save_named (GtkStyleContext *context,
void
gtk_style_context_save (GtkStyleContext *context)
{
GtkStyleContextPrivate *priv = gtk_style_context_get_instance_private (context);
GtkCssNode *cssnode;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
gtk_style_context_save_named (context, NULL);
/* Make sure we have the style existing. It is the
* parent of the new saved node after all.
*/
if (!gtk_style_context_is_saved (context))
gtk_style_context_lookup_style (context);
cssnode = gtk_css_transient_node_new (priv->cssnode);
gtk_css_node_set_parent (cssnode, gtk_style_context_get_root (context));
gtk_style_context_save_to_node (context, cssnode);
g_object_unref (cssnode);
}
/**

View File

@ -33,22 +33,15 @@ G_BEGIN_DECLS
GtkStyleContext *gtk_style_context_new_for_node (GtkCssNode *node);
GtkCssNode *gtk_style_context_get_node (GtkStyleContext *context);
void gtk_style_context_set_id (GtkStyleContext *context,
const char *id);
const char * gtk_style_context_get_id (GtkStyleContext *context);
GtkStyleProvider *
gtk_style_context_get_style_provider (GtkStyleContext *context);
void gtk_style_context_save_named (GtkStyleContext *context,
const char *name);
void gtk_style_context_save_to_node (GtkStyleContext *context,
GtkCssNode *node);
GtkCssStyle * gtk_style_context_lookup_style (GtkStyleContext *context);
GtkCssValue * _gtk_style_context_peek_property (GtkStyleContext *context,
guint property_id);
gboolean _gtk_style_context_check_region_name (const gchar *str);
void _gtk_style_context_get_cursor_color (GtkStyleContext *context,
GdkRGBA *primary_color,
GdkRGBA *secondary_color);

View File

@ -3135,44 +3135,6 @@ gtk_widget_has_tick_callback (GtkWidget *widget)
return priv->tick_callbacks != NULL;
}
static void
gtk_widget_connect_frame_clock (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GdkFrameClock *frame_clock;
frame_clock = gtk_widget_get_frame_clock (widget);
if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
{
priv->clock_tick_id = g_signal_connect (frame_clock, "update",
G_CALLBACK (gtk_widget_on_frame_clock_update),
widget);
gdk_frame_clock_begin_updating (frame_clock);
}
gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
}
static void
gtk_widget_disconnect_frame_clock (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
if (priv->clock_tick_id)
{
GdkFrameClock *frame_clock;
frame_clock = gtk_widget_get_frame_clock (widget);
g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
priv->clock_tick_id = 0;
gdk_frame_clock_end_updating (frame_clock);
}
}
typedef struct _GtkSurfaceTransformChangedCallbackInfo GtkSurfaceTransformChangedCallbackInfo;
struct _GtkSurfaceTransformChangedCallbackInfo
@ -7578,10 +7540,21 @@ static void
gtk_widget_real_realize (GtkWidget *widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
GdkFrameClock *frame_clock;
priv->realized = TRUE;
gtk_widget_connect_frame_clock (widget);
/* Connect frame clock */
frame_clock = gtk_widget_get_frame_clock (widget);
if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
{
priv->clock_tick_id = g_signal_connect (frame_clock, "update",
G_CALLBACK (gtk_widget_on_frame_clock_update),
widget);
gdk_frame_clock_begin_updating (frame_clock);
}
gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
}
/*****************************************
@ -7607,7 +7580,17 @@ gtk_widget_real_unrealize (GtkWidget *widget)
gtk_widget_forall (widget, (GtkCallback)gtk_widget_unrealize, NULL);
gtk_widget_disconnect_frame_clock (widget);
/* Disconnect frame clock */
gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
if (priv->clock_tick_id)
{
GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget);
g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
priv->clock_tick_id = 0;
gdk_frame_clock_end_updating (frame_clock);
}
priv->realized = FALSE;
}

View File

@ -448,7 +448,7 @@ set_columns_type (GtkTreeView *tree_view, ColumnsType type)
#endif
/* FALL THRU */
G_GNUC_FALLTHROUGH;
case COLUMNS_ONE:
rend = gtk_cell_renderer_text_new ();