From ffd1dec01f98d853c017b575fd4df26377ed7e65 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 04 Jan 2008 20:26:12 +0000 Subject: Added, EvTransitionAnimation will contain the implementations for page 2008-01-04 Carlos Garnacho * shell/ev-transition-animation.[ch]: Added, EvTransitionAnimation will contain the implementations for page transition animations, at the moment it just has the "replace" effect. * shell/Makefile.am: Added these files to build. svn path=/trunk/; revision=2799 --- (limited to 'shell') diff --git a/shell/Makefile.am b/shell/Makefile.am index b301374..2b5d58e 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -84,6 +84,8 @@ evince_SOURCES= \ ev-timeline.h \ ev-tooltip.c \ ev-tooltip.h \ + ev-transition-animation.c \ + ev-transition-animation.h \ main.c \ xdg-user-dir-lookup.c diff --git a/shell/ev-transition-animation.c b/shell/ev-transition-animation.c new file mode 100644 index 0000000..13c8f01 --- /dev/null +++ b/shell/ev-transition-animation.c @@ -0,0 +1,316 @@ +/* ev-transition-animation.c + * this file is part of evince, a gnome document viewer + * + * Copyright (C) 2007 Carlos Garnacho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include "ev-transition-animation.h" +#include "ev-timeline.h" + +#define EV_TRANSITION_ANIMATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_TRANSITION_ANIMATION, EvTransitionAnimationPriv)) +#define N_BLINDS 6 + +typedef struct EvTransitionAnimationPriv EvTransitionAnimationPriv; + +struct EvTransitionAnimationPriv { + EvTransitionEffect *effect; + cairo_surface_t *origin_surface; + cairo_surface_t *dest_surface; +}; + +enum { + PROP_0, + PROP_EFFECT, + PROP_ORIGIN_SURFACE, + PROP_DEST_SURFACE +}; + + +G_DEFINE_TYPE (EvTransitionAnimation, ev_transition_animation, EV_TYPE_TIMELINE) + + +static void +ev_transition_animation_init (EvTransitionAnimation *animation) +{ +} + +static void +ev_transition_animation_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EvTransitionAnimationPriv *priv; + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_EFFECT: + if (priv->effect) + g_object_unref (priv->effect); + + priv->effect = g_value_dup_object (value); + break; + case PROP_ORIGIN_SURFACE: + ev_transition_animation_set_origin_surface (EV_TRANSITION_ANIMATION (object), + g_value_get_pointer (value)); + break; + case PROP_DEST_SURFACE: + ev_transition_animation_set_dest_surface (EV_TRANSITION_ANIMATION (object), + g_value_get_pointer (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +ev_transition_animation_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EvTransitionAnimationPriv *priv; + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_EFFECT: + g_value_set_object (value, priv->effect); + break; + case PROP_ORIGIN_SURFACE: + g_value_set_pointer (value, priv->origin_surface); + break; + case PROP_DEST_SURFACE: + g_value_set_pointer (value, priv->dest_surface); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +ev_transition_animation_finalize (GObject *object) +{ + EvTransitionAnimationPriv *priv; + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object); + + if (priv->effect) + g_object_unref (priv->effect); + + if (priv->origin_surface) + cairo_surface_destroy (priv->origin_surface); + + if (priv->dest_surface) + cairo_surface_destroy (priv->dest_surface); + + G_OBJECT_CLASS (ev_transition_animation_parent_class)->finalize (object); +} + +static GObject * +ev_transition_animation_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + EvTransitionAnimationPriv *priv; + EvTransitionEffect *effect; + gint duration; + + object = G_OBJECT_CLASS (ev_transition_animation_parent_class)->constructor (type, + n_construct_properties, + construct_params); + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (object); + effect = priv->effect; + + g_object_get (effect, "duration", &duration, NULL); + ev_timeline_set_duration (EV_TIMELINE (object), duration * 1000); + + return object; +} + +static void +ev_transition_animation_class_init (EvTransitionAnimationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = ev_transition_animation_set_property; + object_class->get_property = ev_transition_animation_get_property; + object_class->finalize = ev_transition_animation_finalize; + object_class->constructor = ev_transition_animation_constructor; + + g_object_class_install_property (object_class, + PROP_EFFECT, + g_param_spec_object ("effect", + "Effect", + "Transition effect description", + EV_TYPE_TRANSITION_EFFECT, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ORIGIN_SURFACE, + g_param_spec_pointer ("origin-surface", + "Origin surface", + "Cairo surface from which the animation will happen", + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DEST_SURFACE, + g_param_spec_pointer ("dest-surface", + "Destination surface", + "Cairo surface to which the animation will happen", + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (EvTransitionAnimationPriv)); +} + +static void +paint_surface (cairo_t *cr, + cairo_surface_t *surface, + gdouble x_offset, + gdouble y_offset, + gdouble alpha, + GdkRectangle page_area) +{ + gint width, height; + + gdk_cairo_rectangle (cr, &page_area); + cairo_clip (cr); + + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_height (surface); + + cairo_save (cr); + + if (width != page_area.width || height != page_area.height) { + cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_FAST); + cairo_scale (cr, + (gdouble) page_area.width / width, + (gdouble) page_area.height / height); + } + + cairo_surface_set_device_offset (surface, x_offset, y_offset); + cairo_set_source_surface (cr, surface, 0, 0); + + if (alpha == 0.) + cairo_paint (cr); + else + cairo_paint_with_alpha (cr, alpha); + + cairo_restore (cr); +} + +void +ev_transition_animation_paint (EvTransitionAnimation *animation, + cairo_t *cr, + GdkRectangle page_area) +{ + EvTransitionAnimationPriv *priv; + EvTransitionEffectType type; + gdouble progress; + + g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation)); + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation); + g_object_get (priv->effect, "type", &type, NULL); + progress = ev_timeline_get_progress (EV_TIMELINE (animation)); + + if (!priv->dest_surface) { + /* animation is still not ready, paint the origin surface */ + paint_surface (cr, priv->origin_surface, 0, 0, 0, page_area); + return; + } + + switch (type) { + case EV_TRANSITION_EFFECT_REPLACE: + /* just paint the destination slide */ + paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area); + break; + default: { + GEnumValue *enum_value; + + enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_TRANSITION_EFFECT_TYPE), type); + + g_warning ("Unimplemented transition animation: '%s', " + "please post a bug report in Evince bugzilla " + "(http://bugzilla.gnome.org) with a testcase.", + enum_value->value_nick); + + /* just paint the destination slide */ + paint_surface (cr, priv->dest_surface, 0, 0, 0, page_area); + } + } +} + +EvTransitionAnimation * +ev_transition_animation_new (EvTransitionEffect *effect) +{ + g_return_val_if_fail (EV_IS_TRANSITION_EFFECT (effect), NULL); + + return g_object_new (EV_TYPE_TRANSITION_ANIMATION, + "effect", effect, + NULL); +} + +void +ev_transition_animation_set_origin_surface (EvTransitionAnimation *animation, + cairo_surface_t *origin_surface) +{ + EvTransitionAnimationPriv *priv; + cairo_surface_t *surface; + + g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation)); + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation); + + surface = cairo_surface_reference (origin_surface); + + if (priv->origin_surface) + cairo_surface_destroy (priv->origin_surface); + + priv->origin_surface = surface; + g_object_notify (G_OBJECT (animation), "origin-surface"); + + if (priv->origin_surface && priv->dest_surface) + ev_timeline_start (EV_TIMELINE (animation)); +} + +void +ev_transition_animation_set_dest_surface (EvTransitionAnimation *animation, + cairo_surface_t *dest_surface) +{ + EvTransitionAnimationPriv *priv; + cairo_surface_t *surface; + + g_return_if_fail (EV_IS_TRANSITION_ANIMATION (animation)); + + priv = EV_TRANSITION_ANIMATION_GET_PRIVATE (animation); + + surface = cairo_surface_reference (dest_surface); + + if (priv->dest_surface) + cairo_surface_destroy (priv->dest_surface); + + priv->dest_surface = surface; + g_object_notify (G_OBJECT (animation), "dest-surface"); + + if (priv->origin_surface && priv->dest_surface) + ev_timeline_start (EV_TIMELINE (animation)); +} diff --git a/shell/ev-transition-animation.h b/shell/ev-transition-animation.h new file mode 100644 index 0000000..b07619f --- /dev/null +++ b/shell/ev-transition-animation.h @@ -0,0 +1,66 @@ +/* ev-transition-animation.h + * this file is part of evince, a gnome document viewer + * + * Copyright (C) 2007 Carlos Garnacho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EV_TRANSITION_ANIMATION_H__ +#define __EV_TRANSITION_ANIMATION_H__ + +#include "ev-timeline.h" +#include "ev-transition-effect.h" + +G_BEGIN_DECLS + +#define EV_TYPE_TRANSITION_ANIMATION (ev_transition_animation_get_type ()) +#define EV_TRANSITION_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_TRANSITION_ANIMATION, EvTransitionAnimation)) +#define EV_TRANSITION_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_TRANSITION_ANIMATION, EvTransitionAnimationClass)) +#define EV_IS_TRANSITION_ANIMATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_TRANSITION_ANIMATION)) +#define EV_IS_TRANSITION_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_TRANSITION_ANIMATION)) +#define EV_TRANSITION_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_TRANSITION_ANIMATION, EvTransitionAnimationClass)) + +typedef struct EvTransitionAnimation EvTransitionAnimation; +typedef struct EvTransitionAnimationClass EvTransitionAnimationClass; + +struct EvTransitionAnimation { + EvTimeline parent_instance; +}; + +struct EvTransitionAnimationClass { + EvTimelineClass parent_class; +}; + + +GType ev_transition_animation_get_type (void) G_GNUC_CONST; + +EvTransitionAnimation * ev_transition_animation_new (EvTransitionEffect *effect); + +void ev_transition_animation_set_origin_surface (EvTransitionAnimation *animation, + cairo_surface_t *origin_surface); +void ev_transition_animation_set_dest_surface (EvTransitionAnimation *animation, + cairo_surface_t *origin_surface); +gint ev_transition_animation_get_page_from (EvTransitionAnimation *animation); +gint ev_transition_animation_get_page_to (EvTransitionAnimation *animation); + +void ev_transition_animation_paint (EvTransitionAnimation *animation, + cairo_t *cr, + GdkRectangle page_area); + +G_END_DECLS + +#endif /* __EV_TRANSITION_ANIMATION_H__ */ -- cgit v0.9.1