1 /*
2  * Clutter.
3  *
4  * An OpenGL based 'interactive canvas' library.
5  *
6  * Authored By Matthew Allum  <mallum@openedhand.com>
7  *             Jorn Baayen  <jorn@openedhand.com>
8  *             Emmanuele Bassi  <ebassi@openedhand.com>
9  *
10  * Copyright (C) 2006 OpenedHand
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "clutter-build-config.h"
28 #endif
29 
30 #define CLUTTER_DISABLE_DEPRECATION_WARNINGS
31 
32 #include "deprecated/clutter-actor.h"
33 #include "clutter-alpha.h"
34 #include "clutter-behaviour.h"
35 #include "clutter-behaviour-depth.h"
36 #include "clutter-enum-types.h"
37 #include "clutter-main.h"
38 #include "clutter-debug.h"
39 #include "clutter-private.h"
40 
41 /**
42  * SECTION:clutter-behaviour-depth
43  * @Title: ClutterBehaviourDepth
44  * @short_description: A behaviour controlling the Z position
45  * @Deprecated: 1.6: Use clutter_actor_animate() instead
46  *
47  * #ClutterBehaviourDepth is a simple #ClutterBehaviour controlling the
48  * depth of a set of actors between a start and end depth.
49  *
50  * #ClutterBehaviourDepth is available since Clutter 0.4.
51  *
52  * Deprecated: 1.6: Use the #ClutterActor:depth property and
53  *   clutter_actor_animate(), or #ClutterAnimator, or #ClutterState
54  *   instead.
55  */
56 
57 struct _ClutterBehaviourDepthPrivate
58 {
59   gint depth_start;
60   gint depth_end;
61 };
62 
63 enum
64 {
65   PROP_0,
66 
67   PROP_DEPTH_START,
68   PROP_DEPTH_END
69 };
70 
G_DEFINE_TYPE_WITH_PRIVATE(ClutterBehaviourDepth,clutter_behaviour_depth,CLUTTER_TYPE_BEHAVIOUR)71 G_DEFINE_TYPE_WITH_PRIVATE (ClutterBehaviourDepth,
72                             clutter_behaviour_depth,
73                             CLUTTER_TYPE_BEHAVIOUR)
74 
75 static void
76 alpha_notify_foreach (ClutterBehaviour *behaviour,
77                       ClutterActor     *actor,
78                       gpointer          user_data)
79 {
80   clutter_actor_set_depth (actor, GPOINTER_TO_INT (user_data));
81 }
82 
83 static void
clutter_behaviour_depth_alpha_notify(ClutterBehaviour * behaviour,gdouble alpha_value)84 clutter_behaviour_depth_alpha_notify (ClutterBehaviour *behaviour,
85                                       gdouble           alpha_value)
86 {
87   ClutterBehaviourDepthPrivate *priv;
88   gint depth;
89 
90   priv = CLUTTER_BEHAVIOUR_DEPTH (behaviour)->priv;
91 
92   /* Need to create factor as to avoid borking signedness */
93   depth = (alpha_value * (priv->depth_end - priv->depth_start))
94         + priv->depth_start;
95 
96   CLUTTER_NOTE (ANIMATION, "alpha: %.4f, depth: %d", alpha_value, depth);
97 
98   clutter_behaviour_actors_foreach (behaviour,
99                                     alpha_notify_foreach,
100                                     GINT_TO_POINTER (depth));
101 }
102 
103 static void
clutter_behaviour_depth_applied(ClutterBehaviour * behaviour,ClutterActor * actor)104 clutter_behaviour_depth_applied (ClutterBehaviour *behaviour,
105                                  ClutterActor     *actor)
106 {
107   ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (behaviour);
108 
109   clutter_actor_set_depth (actor, depth->priv->depth_start);
110 }
111 
112 static void
clutter_behaviour_depth_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * pspec)113 clutter_behaviour_depth_set_property (GObject      *gobject,
114                                       guint         prop_id,
115                                       const GValue *value,
116                                       GParamSpec   *pspec)
117 {
118   ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (gobject);
119 
120   switch (prop_id)
121     {
122     case PROP_DEPTH_START:
123       depth->priv->depth_start = g_value_get_int (value);
124       break;
125     case PROP_DEPTH_END:
126       depth->priv->depth_end = g_value_get_int (value);
127       break;
128     default:
129       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
130       break;
131     }
132 }
133 
134 static void
clutter_behaviour_depth_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * pspec)135 clutter_behaviour_depth_get_property (GObject    *gobject,
136                                       guint       prop_id,
137                                       GValue     *value,
138                                       GParamSpec *pspec)
139 {
140   ClutterBehaviourDepth *depth = CLUTTER_BEHAVIOUR_DEPTH (gobject);
141 
142   switch (prop_id)
143     {
144     case PROP_DEPTH_START:
145       g_value_set_int (value, depth->priv->depth_start);
146       break;
147     case PROP_DEPTH_END:
148       g_value_set_int (value, depth->priv->depth_end);
149       break;
150     default:
151       G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
152       break;
153     }
154 }
155 
156 static void
clutter_behaviour_depth_class_init(ClutterBehaviourDepthClass * klass)157 clutter_behaviour_depth_class_init (ClutterBehaviourDepthClass *klass)
158 {
159   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
160   ClutterBehaviourClass *behaviour_class = CLUTTER_BEHAVIOUR_CLASS (klass);
161 
162   gobject_class->set_property = clutter_behaviour_depth_set_property;
163   gobject_class->get_property = clutter_behaviour_depth_get_property;
164 
165   behaviour_class->alpha_notify = clutter_behaviour_depth_alpha_notify;
166   behaviour_class->applied = clutter_behaviour_depth_applied;
167 
168   /**
169    * ClutterBehaviourDepth:depth-start:
170    *
171    * Start depth level to apply to the actors.
172    *
173    * Since: 0.4
174    *
175    * Deprecated: 1.6
176    */
177   g_object_class_install_property (gobject_class,
178                                    PROP_DEPTH_START,
179                                    g_param_spec_int ("depth-start",
180                                                      P_("Start Depth"),
181                                                      P_("Initial depth to apply"),
182                                                      G_MININT, G_MAXINT, 0,
183                                                      CLUTTER_PARAM_READWRITE));
184   /**
185    * ClutterBehaviourDepth:depth-end:
186    *
187    * End depth level to apply to the actors.
188    *
189    * Since: 0.4
190    *
191    * Deprecated: 1.6
192    */
193   g_object_class_install_property (gobject_class,
194                                    PROP_DEPTH_END,
195                                    g_param_spec_int ("depth-end",
196                                                      P_("End Depth"),
197                                                      P_("Final depth to apply"),
198                                                      G_MININT, G_MAXINT, 0,
199                                                      CLUTTER_PARAM_READWRITE));
200 }
201 
202 static void
clutter_behaviour_depth_init(ClutterBehaviourDepth * depth)203 clutter_behaviour_depth_init (ClutterBehaviourDepth *depth)
204 {
205   depth->priv = clutter_behaviour_depth_get_instance_private (depth);
206 }
207 
208 /**
209  * clutter_behaviour_depth_new:
210  * @alpha: (allow-none): a #ClutterAlpha instance, or %NULL
211  * @depth_start: initial value of the depth
212  * @depth_end: final value of the depth
213  *
214  * Creates a new #ClutterBehaviourDepth which can be used to control
215  * the ClutterActor:depth property of a set of #ClutterActor<!-- -->s.
216  *
217  * If @alpha is not %NULL, the #ClutterBehaviour will take ownership
218  * of the #ClutterAlpha instance. In the case when @alpha is %NULL,
219  * it can be set later with clutter_behaviour_set_alpha().
220  *
221  * Return value: (transfer full): the newly created behaviour
222  *
223  * Since: 0.4
224  *
225  * Deprecated: 1.6
226  */
227 ClutterBehaviour *
clutter_behaviour_depth_new(ClutterAlpha * alpha,gint depth_start,gint depth_end)228 clutter_behaviour_depth_new (ClutterAlpha *alpha,
229                              gint          depth_start,
230                              gint          depth_end)
231 {
232   g_return_val_if_fail (alpha == NULL || CLUTTER_IS_ALPHA (alpha), NULL);
233 
234   return g_object_new (CLUTTER_TYPE_BEHAVIOUR_DEPTH,
235                        "alpha", alpha,
236                        "depth-start", depth_start,
237                        "depth-end", depth_end,
238                        NULL);
239 }
240 
241 /**
242  * clutter_behaviour_depth_set_bounds:
243  * @behaviour: a #ClutterBehaviourDepth
244  * @depth_start: initial value of the depth
245  * @depth_end: final value of the depth
246  *
247  * Sets the boundaries of the @behaviour.
248  *
249  * Since: 0.6
250  *
251  * Deprecated: 1.6
252  */
253 void
clutter_behaviour_depth_set_bounds(ClutterBehaviourDepth * behaviour,gint depth_start,gint depth_end)254 clutter_behaviour_depth_set_bounds (ClutterBehaviourDepth *behaviour,
255                                     gint                   depth_start,
256                                     gint                   depth_end)
257 {
258   ClutterBehaviourDepthPrivate *priv;
259 
260   g_return_if_fail (CLUTTER_IS_BEHAVIOUR_DEPTH (behaviour));
261 
262   priv = behaviour->priv;
263 
264   g_object_freeze_notify (G_OBJECT (behaviour));
265 
266   if (priv->depth_start != depth_start)
267     {
268       priv->depth_start = depth_start;
269       g_object_notify (G_OBJECT (behaviour), "depth-start");
270     }
271 
272   if (priv->depth_end != depth_end)
273     {
274       priv->depth_end = depth_end;
275       g_object_notify (G_OBJECT (behaviour), "depth-end");
276     }
277 
278   g_object_thaw_notify (G_OBJECT (behaviour));
279 }
280 
281 /**
282  * clutter_behaviour_depth_get_bounds:
283  * @behaviour: a #ClutterBehaviourDepth
284  * @depth_start: (out): return location for the initial depth value, or %NULL
285  * @depth_end: (out): return location for the final depth value, or %NULL
286  *
287  * Gets the boundaries of the @behaviour
288  *
289  * Since: 0.6
290  *
291  * Deprecated: 1.6
292  */
293 void
clutter_behaviour_depth_get_bounds(ClutterBehaviourDepth * behaviour,gint * depth_start,gint * depth_end)294 clutter_behaviour_depth_get_bounds (ClutterBehaviourDepth *behaviour,
295                                     gint                  *depth_start,
296                                     gint                  *depth_end)
297 {
298   g_return_if_fail (CLUTTER_IS_BEHAVIOUR_DEPTH (behaviour));
299 
300   if (depth_start)
301     *depth_start = behaviour->priv->depth_start;
302 
303   if (depth_end)
304     *depth_end = behaviour->priv->depth_end;
305 }
306