19
19
* You should have received a copy of the GNU Lesser General Public License
20
20
* along with this program; if not, write to the Free Software Foundation,
21
21
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
* Boston, MA 02111-1307, USA.
25
26
#include "totem-aspect-frame.h"
27
G_DEFINE_TYPE (TotemAspectFrame, totem_aspect_frame, CLUTTER_TYPE_ACTOR)
32
} TotemAspectFramePrivate;
29
#define ASPECT_FRAME_PRIVATE(o) \
30
(G_TYPE_INSTANCE_GET_PRIVATE ((o), \
31
TOTEM_TYPE_ASPECT_FRAME, \
32
TotemAspectFramePrivate))
34
G_DEFINE_TYPE_WITH_PRIVATE (TotemAspectFrame, totem_aspect_frame, CLUTTER_TYPE_ACTOR)
134
totem_aspect_frame_get_size (TotemAspectFrame *frame,
142
clutter_actor_get_allocation_box (CLUTTER_ACTOR (frame), &box);
144
if (fmod (rotation, 180.0) == 90.0)
162
_get_allocation (ClutterActor *actor,
168
clutter_actor_get_allocation_box (actor, &box);
171
*width = box.x2 - box.x1;
173
*height = box.y2 - box.y1;
177
totem_aspect_frame_set_rotation_internal (TotemAspectFrame *frame,
181
TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (frame);
183
gfloat frame_width, frame_height;
184
gfloat child_width, child_height;
185
gfloat child_dest_width, child_dest_height;
186
gdouble frame_aspect;
187
gdouble child_aspect;
189
actor = clutter_actor_get_child_at_index (CLUTTER_ACTOR (frame), 0);
193
totem_aspect_frame_get_size (frame, rotation,
194
&frame_width, &frame_height);
195
_get_allocation (actor, &child_width, &child_height);
197
if (child_width <= 0.0f || child_height <= 0.0f)
200
frame_aspect = frame_width / frame_height;
201
child_aspect = child_width / child_height;
203
if ((frame_aspect < child_aspect) ^ priv->expand)
205
child_dest_width = frame_width;
206
child_dest_height = frame_width / child_aspect;
210
child_dest_height = frame_height;
211
child_dest_width = frame_height * child_aspect;
214
clutter_actor_set_pivot_point (actor, 0.5, 0.5);
218
clutter_actor_save_easing_state (actor);
219
clutter_actor_set_easing_duration (actor, 500);
222
clutter_actor_set_rotation_angle (actor, CLUTTER_Z_AXIS, rotation);
223
clutter_actor_set_scale (actor,
224
child_dest_width / child_width,
225
child_dest_height / child_height);
228
clutter_actor_restore_easing_state (actor);
137
232
totem_aspect_frame_allocate (ClutterActor *actor,
138
233
const ClutterActorBox *box,
139
234
ClutterAllocationFlags flags)
142
237
ClutterActorBox child_box;
143
238
gfloat aspect, child_aspect, width, height, box_width, box_height;
145
TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
240
TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (TOTEM_ASPECT_FRAME (actor));
147
242
CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->
148
243
allocate (actor, box, flags);
154
249
box_width = box->x2 - box->x1;
155
250
box_height = box->y2 - box->y1;
156
252
clutter_actor_get_preferred_size (child, NULL, NULL, &width, &height);
254
if (width <= 0.0f || height <= 0.0f)
158
257
aspect = box_width / box_height;
159
258
child_aspect = width / height;
175
274
child_box.y2 = child_box.y1 + height;
177
276
clutter_actor_allocate (child, &child_box, flags);
278
totem_aspect_frame_set_rotation_internal (TOTEM_ASPECT_FRAME (actor),
279
priv->rotation, FALSE);
181
283
totem_aspect_frame_paint (ClutterActor *actor)
183
285
ClutterActor *child;
184
TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
286
TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (TOTEM_ASPECT_FRAME (actor));
186
288
child = clutter_actor_get_child_at_index (actor, 0);
195
297
clutter_actor_get_size (actor, &width, &height);
197
/* Special-case textures and just munge their coordinates.
198
* This avoids clipping, which can break Clutter's batching.
200
if (CLUTTER_IS_TEXTURE (child))
206
clutter_actor_get_position (child, &x, &y);
209
clutter_texture_get_cogl_material (CLUTTER_TEXTURE (child));
210
opacity = clutter_actor_get_paint_opacity (child);
211
cogl_material_set_color4ub (material,
212
opacity, opacity, opacity, opacity);
213
cogl_set_source (material);
215
tx = (width / (width - (x * 2.f))) / 2.f;
216
ty = (height / (height - (y * 2.f))) / 2.f;
218
cogl_rectangle_with_texture_coords (0.0, 0.0,
221
0.5f - tx, 0.5f - ty,
222
0.5f + tx, 0.5f + ty);
226
cogl_clip_push_rectangle (0.0, 0.0, width, height);
227
clutter_actor_paint (child);
299
cogl_clip_push_rectangle (0.0, 0.0, width, height);
300
clutter_actor_paint (child);
232
304
clutter_actor_paint (child);
239
311
ClutterActorBox box;
240
312
ClutterActor *child;
241
TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
313
TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (TOTEM_ASPECT_FRAME (actor));
243
315
clutter_actor_get_allocation_box (actor, &box);
245
cogl_set_source_color4ub (color->red, color->green,
246
color->blue, color->alpha);
247
cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
317
CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->pick (actor, color);
249
319
child = clutter_actor_get_child_at_index (actor, 0);
269
339
GObjectClass *object_class = G_OBJECT_CLASS (klass);
270
340
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
272
g_type_class_add_private (klass, sizeof (TotemAspectFramePrivate));
274
342
object_class->get_property = totem_aspect_frame_get_property;
275
343
object_class->set_property = totem_aspect_frame_set_property;
276
344
object_class->dispose = totem_aspect_frame_dispose;
311
379
g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
381
priv = totem_aspect_frame_get_instance_private (frame);
314
382
if (priv->expand != expand)
316
384
priv->expand = expand;
317
clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
318
385
g_object_notify (G_OBJECT (frame), "expand");
387
totem_aspect_frame_set_rotation_internal (frame, priv->rotation, TRUE);
323
392
totem_aspect_frame_get_expand (TotemAspectFrame *frame)
394
TotemAspectFramePrivate *priv;
325
396
g_return_val_if_fail (TOTEM_IS_ASPECT_FRAME (frame), FALSE);
326
return frame->priv->expand;
397
priv = totem_aspect_frame_get_instance_private (frame);
335
407
clutter_actor_add_child (CLUTTER_ACTOR (frame), child);
411
totem_aspect_frame_set_rotation (TotemAspectFrame *frame,
414
TotemAspectFramePrivate *priv;
416
g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
417
g_return_if_fail (fmod (rotation, 90.0) == 0.0);
419
priv = totem_aspect_frame_get_instance_private (frame);
420
rotation = fmod (rotation, 360.0);
422
/* When animating, make sure that we go in the right direction,
423
* otherwise we'll spin in the wrong direction going back to 0 from 270 */
424
if (rotation == 0.0 && priv->rotation == 270.0)
426
else if (rotation == 90.0 && priv->rotation == 360.0)
427
totem_aspect_frame_set_rotation_internal (frame, 0.0, FALSE);
428
else if (rotation == 270.0 && fmod (priv->rotation, 360.0) == 0.0)
429
totem_aspect_frame_set_rotation_internal (frame, 360.0, FALSE);
431
g_debug ("Setting rotation to '%lf'", rotation);
433
priv->rotation = rotation;
434
totem_aspect_frame_set_rotation_internal (frame, rotation, TRUE);
438
totem_aspect_frame_get_rotation (TotemAspectFrame *frame)
440
TotemAspectFramePrivate *priv;
443
g_return_val_if_fail (TOTEM_IS_ASPECT_FRAME (frame), 0.0);
445
priv = totem_aspect_frame_get_instance_private (frame);
446
rotation = fmod (priv->rotation, 360.0);
447
g_debug ("Got rotation %lf", rotation);