1 | /* |
2 | * Copyright © 2012 Red Hat Inc. |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | * |
17 | * Authors: Benjamin Otte <otte@gnome.org> |
18 | */ |
19 | |
20 | #include "config.h" |
21 | |
22 | #include "gtkcsstransitionprivate.h" |
23 | |
24 | #include "gtkcsseasevalueprivate.h" |
25 | #include "gtkprogresstrackerprivate.h" |
26 | |
27 | struct _GtkCssTransition |
28 | { |
29 | GtkStyleAnimation parent; |
30 | |
31 | guint property; |
32 | guint finished; |
33 | GtkCssValue *start; |
34 | GtkCssValue *ease; |
35 | GtkProgressTracker tracker; |
36 | }; |
37 | |
38 | |
39 | static GtkStyleAnimation * gtk_css_transition_advance (GtkStyleAnimation *style_animation, |
40 | gint64 timestamp); |
41 | |
42 | |
43 | |
44 | static void |
45 | gtk_css_transition_apply_values (GtkStyleAnimation *style_animation, |
46 | GtkCssAnimatedStyle *style) |
47 | { |
48 | GtkCssTransition *transition = (GtkCssTransition *)style_animation; |
49 | GtkCssValue *value, *end; |
50 | double progress; |
51 | GtkProgressState state; |
52 | |
53 | if (transition->finished) |
54 | return; |
55 | |
56 | end = gtk_css_animated_style_get_intrinsic_value (style, id: transition->property); |
57 | state = gtk_progress_tracker_get_state (tracker: &transition->tracker); |
58 | |
59 | if (state == GTK_PROGRESS_STATE_BEFORE) |
60 | value = _gtk_css_value_ref (value: transition->start); |
61 | else if (state == GTK_PROGRESS_STATE_DURING) |
62 | { |
63 | progress = gtk_progress_tracker_get_progress (tracker: &transition->tracker, FALSE); |
64 | progress = _gtk_css_ease_value_transform (ease: transition->ease, progress); |
65 | |
66 | value = _gtk_css_value_transition (start: transition->start, |
67 | end, |
68 | property_id: transition->property, |
69 | progress); |
70 | } |
71 | else |
72 | return; |
73 | |
74 | if (value == NULL) |
75 | value = _gtk_css_value_ref (value: end); |
76 | |
77 | gtk_css_animated_style_set_animated_value (style, id: transition->property, value); |
78 | } |
79 | |
80 | static gboolean |
81 | gtk_css_transition_is_finished (GtkStyleAnimation *animation) |
82 | { |
83 | GtkCssTransition *transition = (GtkCssTransition *)animation; |
84 | |
85 | return transition->finished; |
86 | } |
87 | |
88 | static gboolean |
89 | gtk_css_transition_is_static (GtkStyleAnimation *animation) |
90 | { |
91 | GtkCssTransition *transition = (GtkCssTransition *)animation; |
92 | |
93 | return transition->finished; |
94 | } |
95 | |
96 | static void |
97 | gtk_css_transition_free (GtkStyleAnimation *animation) |
98 | { |
99 | GtkCssTransition *self = (GtkCssTransition *)animation; |
100 | |
101 | gtk_css_value_unref (value: self->start); |
102 | gtk_css_value_unref (value: self->ease); |
103 | |
104 | g_slice_free (GtkCssTransition, self); |
105 | } |
106 | |
107 | static const GtkStyleAnimationClass GTK_CSS_TRANSITION_CLASS = { |
108 | "GtkCssTransition" , |
109 | gtk_css_transition_free, |
110 | gtk_css_transition_is_finished, |
111 | gtk_css_transition_is_static, |
112 | gtk_css_transition_apply_values, |
113 | gtk_css_transition_advance, |
114 | }; |
115 | |
116 | static GtkStyleAnimation * |
117 | gtk_css_transition_advance (GtkStyleAnimation *style_animation, |
118 | gint64 timestamp) |
119 | { |
120 | GtkCssTransition *source = (GtkCssTransition *)style_animation; |
121 | GtkCssTransition *transition; |
122 | |
123 | transition = g_slice_alloc (block_size: sizeof (GtkCssTransition)); |
124 | transition->parent.class = >K_CSS_TRANSITION_CLASS; |
125 | transition->parent.ref_count = 1; |
126 | |
127 | transition->property = source->property; |
128 | transition->start = _gtk_css_value_ref (value: source->start); |
129 | transition->ease = _gtk_css_value_ref (value: source->ease); |
130 | |
131 | gtk_progress_tracker_init_copy (source: &source->tracker, dest: &transition->tracker); |
132 | gtk_progress_tracker_advance_frame (tracker: &transition->tracker, frame_time: timestamp); |
133 | transition->finished = gtk_progress_tracker_get_state (tracker: &transition->tracker) == GTK_PROGRESS_STATE_AFTER; |
134 | |
135 | return (GtkStyleAnimation *)transition; |
136 | } |
137 | GtkStyleAnimation * |
138 | _gtk_css_transition_new (guint property, |
139 | GtkCssValue *start, |
140 | GtkCssValue *ease, |
141 | gint64 timestamp, |
142 | gint64 duration_us, |
143 | gint64 delay_us) |
144 | { |
145 | GtkCssTransition *transition; |
146 | |
147 | g_return_val_if_fail (start != NULL, NULL); |
148 | g_return_val_if_fail (ease != NULL, NULL); |
149 | |
150 | transition = g_slice_alloc (block_size: sizeof (GtkCssTransition)); |
151 | transition->parent.class = >K_CSS_TRANSITION_CLASS; |
152 | transition->parent.ref_count = 1; |
153 | |
154 | transition->property = property; |
155 | transition->start = _gtk_css_value_ref (value: start); |
156 | transition->ease = _gtk_css_value_ref (value: ease); |
157 | gtk_progress_tracker_start (tracker: &transition->tracker, duration: duration_us, delay: delay_us, iteration_count: 1.0); |
158 | gtk_progress_tracker_advance_frame (tracker: &transition->tracker, frame_time: timestamp); |
159 | transition->finished = gtk_progress_tracker_get_state (tracker: &transition->tracker) == GTK_PROGRESS_STATE_AFTER; |
160 | |
161 | return (GtkStyleAnimation*)transition; |
162 | } |
163 | |
164 | guint |
165 | _gtk_css_transition_get_property (GtkCssTransition *transition) |
166 | { |
167 | return transition->property; |
168 | } |
169 | |
170 | gboolean |
171 | _gtk_css_transition_is_transition (GtkStyleAnimation *animation) |
172 | { |
173 | return animation->class == >K_CSS_TRANSITION_CLASS; |
174 | } |
175 | |