summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <llandwerlin@gmail.com>2013-03-08 16:03:00 +0000
committerBastien Nocera <hadess@hadess.net>2013-07-25 19:56:40 +0200
commit8d8d21f587060ed3090773f3229fb8e2ef4ba41f (patch)
tree7299b17647ee6c89c174eca505a9174e031cb8d0
parent7c3c3ef508862cd139794e89ac578b254eb6ae6e (diff)
downloadtotem-8d8d21f587060ed3090773f3229fb8e2ef4ba41f.tar.gz
backend: Make rotation/crop work together
This fixes problems with the widget not taking all the available space when rotated, and the expand being broken in rotated mode. https://bugzilla.gnome.org/show_bug.cgi?id=679169
-rw-r--r--src/backend/totem-aspect-frame.c111
1 files changed, 75 insertions, 36 deletions
diff --git a/src/backend/totem-aspect-frame.c b/src/backend/totem-aspect-frame.c
index c17c86daa..703d48e8b 100644
--- a/src/backend/totem-aspect-frame.c
+++ b/src/backend/totem-aspect-frame.c
@@ -137,44 +137,98 @@ totem_aspect_frame_get_preferred_height (ClutterActor *actor,
}
static void
+totem_aspect_frame_get_size (TotemAspectFrame *frame,
+ gdouble rotation,
+ gfloat *width,
+ gfloat *height)
+{
+ ClutterActorBox box;
+ gfloat w, h;
+
+ clutter_actor_get_allocation_box (CLUTTER_ACTOR (frame), &box);
+
+ if (rotation == 90.0 || rotation == 270.0)
+ {
+ w = box.y2 - box.y1;
+ h = box.x2 - box.x1;
+ }
+ else
+ {
+ w = box.x2 - box.x1;
+ h = box.y2 - box.y1;
+ }
+
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+}
+
+static void
+_get_allocation (ClutterActor *actor,
+ gfloat *width,
+ gfloat *height)
+{
+ ClutterActorBox box;
+
+ clutter_actor_get_allocation_box (actor, &box);
+
+ if (width)
+ *width = box.x2 - box.x1;
+ if (height)
+ *height = box.y2 - box.y1;
+}
+
+static void
totem_aspect_frame_set_rotation_internal (TotemAspectFrame *frame,
gdouble rotation,
gboolean animate)
{
+ TotemAspectFramePrivate *priv = frame->priv;
ClutterActor *actor;
- gfloat w, h;
- gdouble scale;
+ gfloat frame_width, frame_height;
+ gfloat child_width, child_height;
+ gfloat child_dest_width, child_dest_height;
+ gdouble frame_aspect;
+ gdouble child_aspect;
+
+ actor = clutter_actor_get_child_at_index (CLUTTER_ACTOR (frame), 0);
+ if (!actor)
+ return;
- g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
+ totem_aspect_frame_get_size (frame, rotation,
+ &frame_width, &frame_height);
+ _get_allocation (actor, &child_width, &child_height);
+
+ if (child_width <= 0.0f || child_height <= 0.0f)
+ return;
- g_object_get (G_OBJECT (frame),
- "width", &w,
- "height", &h,
- NULL);
+ frame_aspect = frame_width / frame_height;
+ child_aspect = child_width / child_height;
- /* So that the larger side fits the smaller side
- * FIXME: check the angle instead */
- if (rotation == 90.0 || rotation == 270.0)
+ if ((frame_aspect < child_aspect) ^ priv->expand)
{
- if (w > h)
- scale = h / (double) w;
- else
- scale = w / (double) h;
+ child_dest_width = frame_width;
+ child_dest_height = frame_width / child_aspect;
}
else
{
- scale = 1.0;
+ child_dest_height = frame_height;
+ child_dest_width = frame_height * child_aspect;
}
- actor = CLUTTER_ACTOR (frame);
+ clutter_actor_set_pivot_point (actor, 0.5, 0.5);
if (animate)
{
clutter_actor_save_easing_state (actor);
clutter_actor_set_easing_duration (actor, 500);
}
+
clutter_actor_set_rotation_angle (actor, CLUTTER_Z_AXIS, rotation);
- clutter_actor_set_scale (actor, scale, scale);
+ clutter_actor_set_scale (actor,
+ child_dest_width / child_width,
+ child_dest_height / child_height);
if (animate)
clutter_actor_restore_easing_state (actor);
@@ -188,7 +242,6 @@ totem_aspect_frame_allocate (ClutterActor *actor,
ClutterActor *child;
ClutterActorBox child_box;
gfloat aspect, child_aspect, width, height, box_width, box_height;
- gdouble rotation;
TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
@@ -201,6 +254,7 @@ totem_aspect_frame_allocate (ClutterActor *actor,
box_width = box->x2 - box->x1;
box_height = box->y2 - box->y1;
+
clutter_actor_get_preferred_size (child, NULL, NULL, &width, &height);
if (width <= 0.0f || height <= 0.0f)
@@ -227,14 +281,8 @@ totem_aspect_frame_allocate (ClutterActor *actor,
clutter_actor_allocate (child, &child_box, flags);
- clutter_actor_save_easing_state (child);
- clutter_actor_set_easing_duration (child, 0);
-
- /* FIXME: We should swap height and width if the actor is on its side */
- rotation = totem_aspect_frame_get_rotation (TOTEM_ASPECT_FRAME (actor));
totem_aspect_frame_set_rotation_internal (TOTEM_ASPECT_FRAME (actor),
- rotation,
- FALSE);
+ priv->rotation, FALSE);
}
static void
@@ -344,19 +392,10 @@ totem_aspect_frame_set_expand (TotemAspectFrame *frame, gboolean expand)
priv = frame->priv;
if (priv->expand != expand)
{
- ClutterActor *child;
-
priv->expand = expand;
- child = clutter_actor_get_child_at_index (CLUTTER_ACTOR (frame), 0);
- if (child)
- {
- /* Duration will be reset in _allocate() */
- clutter_actor_save_easing_state (child);
- clutter_actor_set_easing_duration (child, 500);
- clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
- }
-
g_object_notify (G_OBJECT (frame), "expand");
+
+ totem_aspect_frame_set_rotation_internal (frame, priv->rotation, TRUE);
}
}