[totem] backend: Use copy/pasted version of MxAspectFrame
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [totem] backend: Use copy/pasted version of MxAspectFrame
- Date: Mon, 4 Apr 2011 16:29:03 +0000 (UTC)
commit f782e2e18269c6c6279d14699aa87fcce9d68f3b
Author: Bastien Nocera <hadess hadess net>
Date: Mon Apr 4 17:14:28 2011 +0100
backend: Use copy/pasted version of MxAspectFrame
Until we get a solution for this directly in ClutterGst
src/backend/Makefile.am | 4 +-
src/backend/bacon-video-widget-gst-0.10.c | 9 +-
src/backend/totem-aspect-frame.c | 399 +++++++++++++++++++++++++++++
src/backend/totem-aspect-frame.h | 91 +++++++
4 files changed, 498 insertions(+), 5 deletions(-)
---
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index f2c089f..f4c1ec0 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -54,7 +54,9 @@ libbaconvideowidget_la_SOURCES = \
video-utils.c video-utils.h \
bacon-video-widget-gst-0.10.c \
bacon-video-widget-gst-missing-plugins.c \
- bacon-video-widget-gst-missing-plugins.h
+ bacon-video-widget-gst-missing-plugins.h \
+ totem-aspect-frame.h \
+ totem-aspect-frame.c
libbaconvideowidget_la_CPPFLAGS = \
-D_REENTRANT \
diff --git a/src/backend/bacon-video-widget-gst-0.10.c b/src/backend/bacon-video-widget-gst-0.10.c
index 075436c..fa234f5 100644
--- a/src/backend/bacon-video-widget-gst-0.10.c
+++ b/src/backend/bacon-video-widget-gst-0.10.c
@@ -65,6 +65,7 @@
#include <clutter-gst/clutter-gst.h>
#include <mx/mx.h>
+#include "totem-aspect-frame.h"
/* system */
#include <unistd.h>
@@ -4969,7 +4970,7 @@ bacon_video_widget_set_zoom (BaconVideoWidget *bvw,
if (bvw->priv->frame == NULL)
return;
- mx_aspect_frame_set_expand (MX_ASPECT_FRAME (bvw->priv->frame),
+ totem_aspect_frame_set_expand (TOTEM_ASPECT_FRAME (bvw->priv->frame),
(mode == BVW_ZOOM_EXPAND));
}
@@ -4989,7 +4990,7 @@ bacon_video_widget_get_zoom (BaconVideoWidget *bvw)
g_return_val_if_fail (bvw != NULL, 1.0);
g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), 1.0);
- expand = mx_aspect_frame_get_expand (MX_ASPECT_FRAME (bvw->priv->frame));
+ expand = totem_aspect_frame_get_expand (TOTEM_ASPECT_FRAME (bvw->priv->frame));
return expand ? BVW_ZOOM_EXPAND : BVW_ZOOM_NONE;
}
@@ -6263,7 +6264,7 @@ bacon_video_widget_new (BvwUseType type, GError ** error)
g_critical ("Could not create Clutter video sink");
/* The logo */
- bvw->priv->logo_frame = mx_aspect_frame_new ();
+ bvw->priv->logo_frame = totem_aspect_frame_new ();
bvw->priv->logo = clutter_texture_new ();
mx_bin_set_child (MX_BIN (bvw->priv->logo_frame), bvw->priv->logo);
clutter_container_add_actor (CLUTTER_CONTAINER (bvw->priv->stage), bvw->priv->logo_frame);
@@ -6275,7 +6276,7 @@ bacon_video_widget_new (BvwUseType type, GError ** error)
clutter_actor_hide (CLUTTER_ACTOR (bvw->priv->logo_frame));
/* The video */
- bvw->priv->frame = mx_aspect_frame_new ();
+ bvw->priv->frame = totem_aspect_frame_new ();
mx_bin_set_child (MX_BIN (bvw->priv->frame), bvw->priv->texture);
clutter_container_add_actor (CLUTTER_CONTAINER (bvw->priv->stage), bvw->priv->frame);
diff --git a/src/backend/totem-aspect-frame.c b/src/backend/totem-aspect-frame.c
new file mode 100644
index 0000000..458d93f
--- /dev/null
+++ b/src/backend/totem-aspect-frame.c
@@ -0,0 +1,399 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * mx-aspect-frame.c: A container that respect the aspect ratio of its child
+ *
+ * Copyright 2010, 2011 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "totem-aspect-frame.h"
+
+G_DEFINE_TYPE (TotemAspectFrame, totem_aspect_frame, MX_TYPE_BIN)
+
+#define ASPECT_FRAME_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ TOTEM_TYPE_ASPECT_FRAME, \
+ TotemAspectFramePrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_EXPAND,
+ PROP_RATIO
+};
+
+struct _TotemAspectFramePrivate
+{
+ guint expand : 1;
+
+ gfloat ratio;
+};
+
+
+static void
+totem_aspect_frame_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TotemAspectFrame *frame = TOTEM_ASPECT_FRAME (object);
+
+ switch (property_id)
+ {
+ case PROP_EXPAND:
+ g_value_set_boolean (value, totem_aspect_frame_get_expand (frame));
+ break;
+
+ case PROP_RATIO:
+ g_value_set_float (value, totem_aspect_frame_get_ratio (frame));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+totem_aspect_frame_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_EXPAND:
+ totem_aspect_frame_set_expand (TOTEM_ASPECT_FRAME (object),
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_RATIO:
+ totem_aspect_frame_set_ratio (TOTEM_ASPECT_FRAME (object),
+ g_value_get_float (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+totem_aspect_frame_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (totem_aspect_frame_parent_class)->dispose (object);
+}
+
+static void
+totem_aspect_frame_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (totem_aspect_frame_parent_class)->finalize (object);
+}
+
+static void
+totem_aspect_frame_get_preferred_width (ClutterActor *actor,
+ gfloat for_height,
+ gfloat *min_width_p,
+ gfloat *nat_width_p)
+{
+ gboolean override;
+ MxPadding padding;
+
+ mx_widget_get_padding (MX_WIDGET (actor), &padding);
+ if (for_height >= 0)
+ for_height = MAX (0, for_height - padding.top - padding.bottom);
+
+ if (for_height >= 0)
+ override = FALSE;
+ else
+ g_object_get (G_OBJECT (actor), "natural-height-set", &override, NULL);
+
+ if (override)
+ g_object_get (G_OBJECT (actor), "natural-height", &for_height, NULL);
+
+ CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->
+ get_preferred_width (actor, for_height, min_width_p, nat_width_p);
+
+ if (min_width_p)
+ *min_width_p += padding.left + padding.right;
+ if (nat_width_p)
+ *nat_width_p += padding.left + padding.right;
+}
+
+static void
+totem_aspect_frame_get_preferred_height (ClutterActor *actor,
+ gfloat for_width,
+ gfloat *min_height_p,
+ gfloat *nat_height_p)
+{
+ gboolean override;
+ MxPadding padding;
+
+ mx_widget_get_padding (MX_WIDGET (actor), &padding);
+ if (for_width >= 0)
+ for_width = MAX (0, for_width - padding.left - padding.right);
+
+ if (for_width >= 0)
+ override = FALSE;
+ else
+ g_object_get (G_OBJECT (actor), "natural-width-set", &override, NULL);
+
+ if (override)
+ g_object_get (G_OBJECT (actor), "natural-width", &for_width, NULL);
+
+ CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->
+ get_preferred_height (actor, for_width, min_height_p, nat_height_p);
+}
+
+static void
+totem_aspect_frame_allocate (ClutterActor *actor,
+ const ClutterActorBox *box,
+ ClutterAllocationFlags flags)
+{
+ MxPadding padding;
+ ClutterActor *child;
+ ClutterActorBox child_box;
+ gfloat aspect, child_aspect, width, height, box_width, box_height;
+
+ TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
+
+ CLUTTER_ACTOR_CLASS (totem_aspect_frame_parent_class)->
+ allocate (actor, box, flags);
+
+ child = mx_bin_get_child (MX_BIN (actor));
+ if (!child)
+ return;
+
+ mx_widget_get_padding (MX_WIDGET (actor), &padding);
+
+ box_width = box->x2 - box->x1 - padding.left - padding.right;
+ box_height = box->y2 - box->y1 - padding.top - padding.bottom;
+ clutter_actor_get_preferred_size (child, NULL, NULL, &width, &height);
+
+ aspect = box_width / box_height;
+ if (priv->ratio >= 0.f)
+ child_aspect = priv->ratio;
+ else
+ child_aspect = width / height;
+
+ if ((aspect < child_aspect) ^ priv->expand)
+ {
+ width = box_width;
+ height = box_width / child_aspect;
+ }
+ else
+ {
+ height = box_height;
+ width = box_height * child_aspect;
+ }
+
+ child_box.x1 = (box_width - width) / 2 + padding.left;
+ child_box.y1 = (box_height - height) / 2 + padding.top;
+ child_box.x2 = child_box.x1 + width;
+ child_box.y2 = child_box.y1 + height;
+
+ clutter_actor_allocate (child, &child_box, flags);
+}
+
+static void
+totem_aspect_frame_paint (ClutterActor *actor)
+{
+ ClutterActor *child = mx_bin_get_child (MX_BIN (actor));
+ TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
+
+ if (!child)
+ return;
+
+ if (priv->expand)
+ {
+ MxPadding padding;
+ gfloat width, height;
+
+ clutter_actor_get_size (actor, &width, &height);
+ mx_widget_get_padding (MX_WIDGET (actor), &padding);
+
+ /* Special-case textures and just munge their coordinates.
+ * This avoids clipping, which can break Clutter's batching.
+ */
+ if (CLUTTER_IS_TEXTURE (child))
+ {
+ guint8 opacity;
+ gfloat x, y, tx, ty;
+ CoglHandle material;
+
+ clutter_actor_get_position (child, &x, &y);
+
+ material =
+ clutter_texture_get_cogl_material (CLUTTER_TEXTURE (child));
+ opacity = clutter_actor_get_paint_opacity (child);
+ cogl_material_set_color4ub (material,
+ opacity, opacity, opacity, opacity);
+ cogl_set_source (material);
+
+ x -= padding.left;
+ y -= padding.top;
+ width -= padding.left + padding.right;
+ height -= padding.top + padding.bottom;
+
+ tx = (width / (width - (x * 2.f))) / 2.f;
+ ty = (height / (height - (y * 2.f))) / 2.f;
+
+ cogl_rectangle_with_texture_coords (padding.left, padding.top,
+ padding.left + width,
+ padding.top + height,
+ 0.5f - tx, 0.5f - ty,
+ 0.5f + tx, 0.5f + ty);
+ }
+ else
+ {
+ cogl_clip_push_rectangle (padding.left, padding.top,
+ padding.left + width, padding.top + height);
+ clutter_actor_paint (child);
+ cogl_clip_pop ();
+ }
+ }
+ else
+ clutter_actor_paint (child);
+}
+
+static void
+totem_aspect_frame_pick (ClutterActor *actor,
+ const ClutterColor *color)
+{
+ ClutterActorBox box;
+
+ ClutterActor *child = mx_bin_get_child (MX_BIN (actor));
+ TotemAspectFramePrivate *priv = TOTEM_ASPECT_FRAME (actor)->priv;
+
+ clutter_actor_get_allocation_box (actor, &box);
+
+ cogl_set_source_color4ub (color->red, color->green,
+ color->blue, color->alpha);
+ cogl_rectangle (box.x1, box.y1, box.x2, box.y2);
+
+ if (!child)
+ return;
+
+ if (priv->expand)
+ {
+ MxPadding padding;
+ mx_widget_get_padding (MX_WIDGET (actor), &padding);
+
+ cogl_clip_push_rectangle (padding.left, padding.top,
+ padding.left + (box.x2 - box.x1),
+ padding.top + (box.y2 - box.y1));
+ clutter_actor_paint (child);
+ cogl_clip_pop ();
+ }
+ else
+ clutter_actor_paint (child);
+}
+
+static void
+totem_aspect_frame_class_init (TotemAspectFrameClass *klass)
+{
+ GParamSpec *pspec;
+
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (TotemAspectFramePrivate));
+
+ object_class->get_property = totem_aspect_frame_get_property;
+ object_class->set_property = totem_aspect_frame_set_property;
+ object_class->dispose = totem_aspect_frame_dispose;
+ object_class->finalize = totem_aspect_frame_finalize;
+
+ actor_class->get_preferred_width = totem_aspect_frame_get_preferred_width;
+ actor_class->get_preferred_height = totem_aspect_frame_get_preferred_height;
+ actor_class->allocate = totem_aspect_frame_allocate;
+ actor_class->paint = totem_aspect_frame_paint;
+ actor_class->pick = totem_aspect_frame_pick;
+
+ pspec = g_param_spec_boolean ("expand",
+ "Expand",
+ "Fill the allocated area with the child and "
+ "clip off the excess.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_EXPAND, pspec);
+
+ pspec = g_param_spec_float ("ratio",
+ "Ratio",
+ "Override the child's aspect ratio "
+ "(width/height).",
+ -1.f, G_MAXFLOAT, -1.f,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_RATIO, pspec);
+}
+
+static void
+totem_aspect_frame_init (TotemAspectFrame *self)
+{
+ TotemAspectFramePrivate *priv = self->priv = ASPECT_FRAME_PRIVATE (self);
+ priv->ratio = -1.f;
+}
+
+ClutterActor *
+totem_aspect_frame_new (void)
+{
+ return g_object_new (TOTEM_TYPE_ASPECT_FRAME, NULL);
+}
+
+void
+totem_aspect_frame_set_expand (TotemAspectFrame *frame, gboolean expand)
+{
+ TotemAspectFramePrivate *priv;
+
+ g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
+
+ priv = frame->priv;
+ if (priv->expand != expand)
+ {
+ priv->expand = expand;
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
+ g_object_notify (G_OBJECT (frame), "expand");
+ }
+}
+
+gboolean
+totem_aspect_frame_get_expand (TotemAspectFrame *frame)
+{
+ g_return_val_if_fail (TOTEM_IS_ASPECT_FRAME (frame), FALSE);
+ return frame->priv->expand;
+}
+
+void
+totem_aspect_frame_set_ratio (TotemAspectFrame *frame, gfloat ratio)
+{
+ TotemAspectFramePrivate *priv;
+
+ g_return_if_fail (TOTEM_IS_ASPECT_FRAME (frame));
+
+ priv = frame->priv;
+ if (priv->ratio != ratio)
+ {
+ priv->ratio = ratio;
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (frame));
+ g_object_notify (G_OBJECT (frame), "ratio");
+ }
+}
+
+gfloat
+totem_aspect_frame_get_ratio (TotemAspectFrame *frame)
+{
+ g_return_val_if_fail (TOTEM_IS_ASPECT_FRAME (frame), -1.f);
+ return frame->priv->ratio;
+}
diff --git a/src/backend/totem-aspect-frame.h b/src/backend/totem-aspect-frame.h
new file mode 100644
index 0000000..1a11418
--- /dev/null
+++ b/src/backend/totem-aspect-frame.h
@@ -0,0 +1,91 @@
+
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * mx-aspect-frame.h: A container that respect the aspect ratio of its child
+ *
+ * Copyright 2010, 2011 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __TOTEM_ASPECT_FRAME_H__
+#define __TOTEM_ASPECT_FRAME_H__
+
+#include <glib-object.h>
+#include <mx/mx.h>
+
+G_BEGIN_DECLS
+
+#define TOTEM_TYPE_ASPECT_FRAME totem_aspect_frame_get_type()
+
+#define TOTEM_ASPECT_FRAME(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ TOTEM_TYPE_ASPECT_FRAME, TotemAspectFrame))
+
+#define TOTEM_ASPECT_FRAME_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ TOTEM_TYPE_ASPECT_FRAME, TotemAspectFrameClass))
+
+#define TOTEM_IS_ASPECT_FRAME(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ TOTEM_TYPE_ASPECT_FRAME))
+
+#define TOTEM_IS_ASPECT_FRAME_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ TOTEM_TYPE_ASPECT_FRAME))
+
+#define TOTEM_ASPECT_FRAME_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TOTEM_TYPE_ASPECT_FRAME, TotemAspectFrameClass))
+
+typedef struct _TotemAspectFrame TotemAspectFrame;
+typedef struct _TotemAspectFrameClass TotemAspectFrameClass;
+typedef struct _TotemAspectFramePrivate TotemAspectFramePrivate;
+
+struct _TotemAspectFrame
+{
+ MxBin parent;
+
+ TotemAspectFramePrivate *priv;
+};
+
+struct _TotemAspectFrameClass
+{
+ MxBinClass parent_class;
+
+ /* padding for future expansion */
+ void (*_padding_0) (void);
+ void (*_padding_1) (void);
+ void (*_padding_2) (void);
+ void (*_padding_3) (void);
+ void (*_padding_4) (void);
+};
+
+GType totem_aspect_frame_get_type (void) G_GNUC_CONST;
+
+ClutterActor * totem_aspect_frame_new (void);
+
+void totem_aspect_frame_set_expand (TotemAspectFrame *frame,
+ gboolean expand);
+gboolean totem_aspect_frame_get_expand (TotemAspectFrame *frame);
+
+void totem_aspect_frame_set_ratio (TotemAspectFrame *frame,
+ gfloat ratio);
+gfloat totem_aspect_frame_get_ratio (TotemAspectFrame *frame);
+
+G_END_DECLS
+
+#endif /* __TOTEM_ASPECT_FRAME_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]