~ubuntu-branches/debian/jessie/cheese/jessie

« back to all changes in this revision

Viewing changes to libcheese/totem-aspect-frame.c

  • Committer: Package Import Robot
  • Author(s): Andreas Henriksson
  • Date: 2014-04-02 21:39:33 UTC
  • mfrom: (1.5.1) (15.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20140402213933-r0w3gna0pv7q7085
Tags: 3.12.0-1
* New upstream release.
* Revert changes done in 3.10.1-3
  - i.e. lower gnome-desktop build-dependency again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
23
22
 */
24
23
 
 
24
#include <math.h>
 
25
 
25
26
#include "totem-aspect-frame.h"
26
27
 
27
 
G_DEFINE_TYPE (TotemAspectFrame, totem_aspect_frame, CLUTTER_TYPE_ACTOR)
 
28
typedef struct 
 
29
{
 
30
  guint expand : 1;
 
31
  gdouble rotation;
 
32
} TotemAspectFramePrivate;
28
33
 
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)
33
35
 
34
36
enum
35
37
{
38
40
  PROP_EXPAND,
39
41
};
40
42
 
41
 
struct _TotemAspectFramePrivate
42
 
{
43
 
  guint expand : 1;
44
 
};
45
 
 
46
43
 
47
44
static void
48
45
totem_aspect_frame_get_property (GObject    *object,
134
131
}
135
132
 
136
133
static void
 
134
totem_aspect_frame_get_size (TotemAspectFrame *frame,
 
135
                             gdouble           rotation,
 
136
                             gfloat           *width,
 
137
                             gfloat           *height)
 
138
{
 
139
  ClutterActorBox box;
 
140
  gfloat w, h;
 
141
 
 
142
  clutter_actor_get_allocation_box (CLUTTER_ACTOR (frame), &box);
 
143
 
 
144
  if (fmod (rotation, 180.0) == 90.0)
 
145
    {
 
146
      w = box.y2 - box.y1;
 
147
      h = box.x2 - box.x1;
 
148
    }
 
149
  else
 
150
    {
 
151
      w = box.x2 - box.x1;
 
152
      h = box.y2 - box.y1;
 
153
    }
 
154
 
 
155
  if (width)
 
156
    *width = w;
 
157
  if (height)
 
158
    *height = h;
 
159
}
 
160
 
 
161
static void
 
162
_get_allocation (ClutterActor *actor,
 
163
                 gfloat       *width,
 
164
                 gfloat       *height)
 
165
{
 
166
  ClutterActorBox box;
 
167
 
 
168
  clutter_actor_get_allocation_box (actor, &box);
 
169
 
 
170
  if (width)
 
171
    *width = box.x2 - box.x1;
 
172
  if (height)
 
173
    *height = box.y2 - box.y1;
 
174
}
 
175
 
 
176
static void
 
177
totem_aspect_frame_set_rotation_internal (TotemAspectFrame *frame,
 
178
                                          gdouble           rotation,
 
179
                                          gboolean          animate)
 
180
{
 
181
  TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (frame);
 
182
  ClutterActor *actor;
 
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;
 
188
 
 
189
  actor = clutter_actor_get_child_at_index (CLUTTER_ACTOR (frame), 0);
 
190
  if (!actor)
 
191
    return;
 
192
 
 
193
  totem_aspect_frame_get_size (frame, rotation,
 
194
                               &frame_width, &frame_height);
 
195
  _get_allocation (actor, &child_width, &child_height);
 
196
 
 
197
  if (child_width <= 0.0f || child_height <= 0.0f)
 
198
    return;
 
199
 
 
200
  frame_aspect = frame_width / frame_height;
 
201
  child_aspect = child_width / child_height;
 
202
 
 
203
  if ((frame_aspect < child_aspect) ^ priv->expand)
 
204
    {
 
205
      child_dest_width = frame_width;
 
206
      child_dest_height = frame_width / child_aspect;
 
207
    }
 
208
  else
 
209
    {
 
210
      child_dest_height = frame_height;
 
211
      child_dest_width = frame_height * child_aspect;
 
212
    }
 
213
 
 
214
  clutter_actor_set_pivot_point (actor, 0.5, 0.5);
 
215
 
 
216
  if (animate)
 
217
    {
 
218
      clutter_actor_save_easing_state (actor);
 
219
      clutter_actor_set_easing_duration (actor, 500);
 
220
    }
 
221
 
 
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);
 
226
 
 
227
  if (animate)
 
228
    clutter_actor_restore_easing_state (actor);
 
229
}
 
230
 
 
231
static void
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;
144
239
 
145
 
  TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
 
240
  TotemAspectFramePrivate *priv = totem_aspect_frame_get_instance_private (TOTEM_ASPECT_FRAME (actor));
146
241
 
147
242
  CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->
148
243
    allocate (actor, box, flags);
153
248
 
154
249
  box_width = box->x2 - box->x1;
155
250
  box_height = box->y2 - box->y1;
 
251
 
156
252
  clutter_actor_get_preferred_size (child, NULL, NULL, &width, &height);
157
253
 
 
254
  if (width <= 0.0f || height <= 0.0f)
 
255
    return;
 
256
 
158
257
  aspect = box_width / box_height;
159
258
  child_aspect = width / height;
160
259
 
175
274
  child_box.y2 = child_box.y1 + height;
176
275
 
177
276
  clutter_actor_allocate (child, &child_box, flags);
 
277
 
 
278
  totem_aspect_frame_set_rotation_internal (TOTEM_ASPECT_FRAME (actor),
 
279
                                            priv->rotation, FALSE);
178
280
}
179
281
 
180
282
static void
181
283
totem_aspect_frame_paint (ClutterActor *actor)
182
284
{
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));
185
287
 
186
288
  child = clutter_actor_get_child_at_index (actor, 0);
187
289
 
194
296
 
195
297
      clutter_actor_get_size (actor, &width, &height);
196
298
 
197
 
      /* Special-case textures and just munge their coordinates.
198
 
       * This avoids clipping, which can break Clutter's batching.
199
 
       */
200
 
      if (CLUTTER_IS_TEXTURE (child))
201
 
        {
202
 
          guint8 opacity;
203
 
          gfloat x, y, tx, ty;
204
 
          CoglHandle material;
205
 
 
206
 
          clutter_actor_get_position (child, &x, &y);
207
 
 
208
 
          material =
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);
214
 
 
215
 
          tx = (width / (width - (x * 2.f))) / 2.f;
216
 
          ty = (height / (height - (y * 2.f))) / 2.f;
217
 
 
218
 
          cogl_rectangle_with_texture_coords (0.0, 0.0,
219
 
                                              width,
220
 
                                              height,
221
 
                                              0.5f - tx, 0.5f - ty,
222
 
                                              0.5f + tx, 0.5f + ty);
223
 
        }
224
 
      else
225
 
        {
226
 
          cogl_clip_push_rectangle (0.0, 0.0, width, height);
227
 
          clutter_actor_paint (child);
228
 
          cogl_clip_pop ();
229
 
        }
 
299
      cogl_clip_push_rectangle (0.0, 0.0, width, height);
 
300
      clutter_actor_paint (child);
 
301
      cogl_clip_pop ();
230
302
    }
231
303
  else
232
304
    clutter_actor_paint (child);
238
310
{
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));
242
314
 
243
315
  clutter_actor_get_allocation_box (actor, &box);
244
316
 
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);
248
318
 
249
319
  child = clutter_actor_get_child_at_index (actor, 0);
250
320
 
269
339
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
270
340
  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
271
341
 
272
 
  g_type_class_add_private (klass, sizeof (TotemAspectFramePrivate));
273
 
 
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;
294
362
static void
295
363
totem_aspect_frame_init (TotemAspectFrame *self)
296
364
{
297
 
  self->priv = ASPECT_FRAME_PRIVATE (self);
 
365
  clutter_actor_set_pivot_point (CLUTTER_ACTOR (self), 0.5f, 0.5f);
298
366
}
299
367
 
300
368
ClutterActor *
310
378
 
311
379
  g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
312
380
 
313
 
  priv = frame->priv;
 
381
  priv = totem_aspect_frame_get_instance_private (frame); 
314
382
  if (priv->expand != expand)
315
383
    {
316
384
      priv->expand = expand;
317
 
      clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
318
385
      g_object_notify (G_OBJECT (frame), "expand");
 
386
 
 
387
      totem_aspect_frame_set_rotation_internal (frame, priv->rotation, TRUE);
319
388
    }
320
389
}
321
390
 
322
391
gboolean
323
392
totem_aspect_frame_get_expand (TotemAspectFrame *frame)
324
393
{
 
394
  TotemAspectFramePrivate *priv;
 
395
 
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); 
 
398
  return priv->expand;
327
399
}
328
400
 
329
401
void
334
406
 
335
407
  clutter_actor_add_child (CLUTTER_ACTOR (frame), child);
336
408
}
 
409
 
 
410
void
 
411
totem_aspect_frame_set_rotation (TotemAspectFrame *frame,
 
412
                                 gdouble           rotation)
 
413
{
 
414
  TotemAspectFramePrivate *priv;
 
415
 
 
416
  g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
 
417
  g_return_if_fail (fmod (rotation, 90.0) == 0.0);
 
418
 
 
419
  priv = totem_aspect_frame_get_instance_private (frame); 
 
420
  rotation = fmod (rotation, 360.0);
 
421
 
 
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)
 
425
    rotation = 360.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);
 
430
 
 
431
  g_debug ("Setting rotation to '%lf'", rotation);
 
432
 
 
433
  priv->rotation = rotation;
 
434
  totem_aspect_frame_set_rotation_internal (frame, rotation, TRUE);
 
435
}
 
436
 
 
437
gdouble
 
438
totem_aspect_frame_get_rotation (TotemAspectFrame *frame)
 
439
{
 
440
  TotemAspectFramePrivate *priv;
 
441
  gdouble rotation;
 
442
 
 
443
  g_return_val_if_fail (TOTEM_IS_ASPECT_FRAME (frame), 0.0);
 
444
 
 
445
  priv = totem_aspect_frame_get_instance_private (frame); 
 
446
  rotation = fmod (priv->rotation, 360.0);
 
447
  g_debug ("Got rotation %lf", rotation);
 
448
 
 
449
  return rotation;
 
450
}