Merge branch 'animate-layout-manager' into ebassi-next
* animate-layout-manager: layout-manager: Document the animation support layout-manager: Rewind the timeline in begin_animation() box-layout: Remove the allocations hash table docs: Clean up the README file layout: Let begin_animation() return the Alpha box-layout: Add knobs for controlling animations box-layout: Animate layout properties layout: Add animation support to LayoutManager Add ActorBox animation methods
This commit is contained in:
commit
3d350078a8
117
README
117
README
@ -1,5 +1,5 @@
|
||||
Clutter 1.2 README
|
||||
==================
|
||||
Clutter - README
|
||||
===============================================================================
|
||||
|
||||
Clutter is an open source software library for creating fast, visually
|
||||
rich and animated graphical user interfaces.
|
||||
@ -22,7 +22,6 @@ If you are building the Introspection data you will also need:
|
||||
|
||||
• GObject-Introspection >= 0.6.4
|
||||
|
||||
|
||||
The official website is:
|
||||
http://www.clutter-project.org
|
||||
|
||||
@ -42,41 +41,63 @@ Clutter is licensed under the terms of the GNU Lesser General Public
|
||||
License, version 2.1 or (at your option) later.
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
===============================================================================
|
||||
|
||||
See the INSTALL file. Info on specific Clutter options;
|
||||
|
||||
--enable-debug=[no/minimum/yes]
|
||||
Controls Clutter debugging level (default=yes):
|
||||
yes: All glib asserts, checks and runtime clutter verbose messages.
|
||||
minimum: Just glib cast checks and runtime clutter verbose messagaes.
|
||||
no: No glib asserts or checks and no runtime clutter verbose messages
|
||||
(Only really of use in extreme performance cases)
|
||||
Controls Clutter debugging level:
|
||||
|
||||
yes:
|
||||
All GLib asserts, checks and support for runtime Clutter
|
||||
debugging notes through CLUTTER_DEBUG. This is the default
|
||||
value for snapshots.
|
||||
|
||||
minimum:
|
||||
Just GType cast checks and support for runtime Clutter
|
||||
debugging notes through CLUTTER_DEBUG. This is the default
|
||||
for stable releases.
|
||||
|
||||
no:
|
||||
No GLib asserts or checks and no support for runtime Clutter
|
||||
debugging notes. Only use in extreme performance and/or size
|
||||
optimization cases.
|
||||
|
||||
--enable-cogl-debug=[no/minimum/yes]
|
||||
Controls COGL debugging level (default=minimum):
|
||||
yes: All runtime verbose messages and error checking for each GL
|
||||
primitive
|
||||
minimum: All runtime verbose messages
|
||||
no: No error checking and no messages
|
||||
|
||||
yes:
|
||||
Support for COGL debugging notes through COGL_DEBUG and
|
||||
error checking for each GL primitive.
|
||||
|
||||
minimum:
|
||||
Support for COGL debugging notes through COGL_DEBUG. This is
|
||||
the default for snapshots.
|
||||
|
||||
no:
|
||||
Disable support for COGL runtime debugging notes. This is
|
||||
the default for stable releases.
|
||||
|
||||
--enable-maintainer-flags=[no/yes]
|
||||
Use strict compiler flags (default=no)
|
||||
Use strict compiler flags. This defaults to 'yes' for snapshots and
|
||||
to 'no' for stable releases.
|
||||
|
||||
--enable-gtk-doc
|
||||
use gtk-doc to build API documentation (default=no). Requires gtk-doc
|
||||
present on system
|
||||
present on the target system.
|
||||
|
||||
--enable-manual=[no/yes]
|
||||
Build application developers manual. Requires jw and xmlto binaries.
|
||||
Presently incomplete.
|
||||
--enable-docs=[no/yes]
|
||||
Build additional documentation. Requires xsltproc for DocBook
|
||||
conversion, and optionally jw for PDF generation.
|
||||
|
||||
--with-flavour=[glx/eglx/eglnative/sdl/osx/win32/fruity]
|
||||
Select the Clutter backend: (default=glx)
|
||||
|
||||
glx: Fully featured GLX backend. Using Open GL.
|
||||
glx:
|
||||
Fully featured GLX backend. Using Open GL.
|
||||
|
||||
eglx: EGL/Open GL ES backend for EGL on X windows implementations
|
||||
eglx:
|
||||
EGL/Open GL ES backend for EGL on X windows implementations
|
||||
|
||||
eglnative:
|
||||
EGL/Open GL ES backend on 'native windowing system' - i.e
|
||||
@ -84,10 +105,12 @@ See the INSTALL file. Info on specific Clutter options;
|
||||
a createNativeWindow() call. Also it optionally supports
|
||||
tslib for touchscreen events.
|
||||
|
||||
sdl: Basic SDL backend, using Open GL. Should provide portability
|
||||
sdl:
|
||||
Basic SDL backend, using Open GL. Should provide portability
|
||||
to Windows and possibly other OS's. (DEPRECATED)
|
||||
|
||||
osx: OS X backend. (EXPERIMENTAL)
|
||||
osx:
|
||||
OS X backend. (EXPERIMENTAL)
|
||||
|
||||
win32:
|
||||
Microsoft Windows(tm) WGL backend
|
||||
@ -98,12 +121,15 @@ See the INSTALL file. Info on specific Clutter options;
|
||||
--with-imagebackend=[gdk-pixbuf/quartz/internal]
|
||||
Select the image loading backend used by COGL
|
||||
|
||||
gdk-pixbuf: Depend on gdk-pixbuf-2.0 (default for the glx, eglx,
|
||||
gdk-pixbuf:
|
||||
Depend on gdk-pixbuf-2.0 (default for the glx, eglx,
|
||||
eglnative, sdl, win32 flavours and recommended)
|
||||
|
||||
quartz: Depend on CoreGraphics (default for the osx flavour)
|
||||
quartz:
|
||||
Depend on CoreGraphics (default for the osx flavour)
|
||||
|
||||
internal: Internal JPEG and PNG loader. Should only be used
|
||||
internal:
|
||||
Internal JPEG and PNG loader. Should only be used
|
||||
for testing on new platforms
|
||||
|
||||
--with-gles=[1.1/2.0]
|
||||
@ -112,15 +138,18 @@ See the INSTALL file. Info on specific Clutter options;
|
||||
--with-json=[internal/check/system]
|
||||
Select the JSON-GLib copy to use (default=check)
|
||||
|
||||
internal: Use the internal copy of JSON-GLib for ClutterScript
|
||||
internal:
|
||||
Use the internal copy of JSON-GLib for ClutterScript
|
||||
|
||||
check: Check for the existence of a system copy of JSON-GLib
|
||||
check:
|
||||
Check for the existence of a system copy of JSON-GLib
|
||||
and if it is available, make Clutter depend on it
|
||||
|
||||
system: Only use the system copy of JSON-GLib
|
||||
system:
|
||||
Only use the system copy of JSON-GLib
|
||||
|
||||
VERSIONING
|
||||
==========
|
||||
===============================================================================
|
||||
|
||||
Clutter uses the common "Linux kernel" versioning system, where
|
||||
even-numbered minor versions are stable and odd-numbered minor
|
||||
@ -137,7 +166,7 @@ numbers are only used for released archives; odd micro numbers are
|
||||
only used on the SVN repository.
|
||||
|
||||
HACKING
|
||||
=======
|
||||
===============================================================================
|
||||
|
||||
If you want to hack on and improve Clutter, check the contained TODO
|
||||
file for pending tasks, the HACKING file for general implementation guidelines,
|
||||
@ -147,7 +176,7 @@ used throughout Clutter. Remember: the coding style is mandatory; patches
|
||||
not conforming to it will be rejected.
|
||||
|
||||
BUGS
|
||||
====
|
||||
===============================================================================
|
||||
|
||||
Bugs should be reported to the OpenedHand Bugzilla at:
|
||||
|
||||
@ -171,8 +200,8 @@ behaviour.
|
||||
If the bug exposes a crash, the exact text printed out and a stack trace
|
||||
obtained using gdb are greatly appreciated.
|
||||
|
||||
PATCHES
|
||||
=======
|
||||
CONTRIBUTING
|
||||
===============================================================================
|
||||
|
||||
Patches should be submitted using Bugzilla. Patches fixing a bug should be
|
||||
attached to the bug report; patches for new features or for fixing bugs not
|
||||
@ -199,13 +228,13 @@ If you do not intend to waive your copyright you should contact the Clutter
|
||||
development team to arrange a suitable solution.
|
||||
|
||||
RELEASE NOTES
|
||||
=============
|
||||
===============================================================================
|
||||
|
||||
Relevant information for developers with existing Clutter applications
|
||||
wanting to port to newer releases (See NEWS for general new feature info).
|
||||
|
||||
Release Notes for Clutter 1.2
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* ClutterStageManager is now publicly available and documented API.
|
||||
|
||||
@ -213,7 +242,7 @@ Release Notes for Clutter 1.2
|
||||
back to the internal copy only if JSON-GLib is not installed.
|
||||
|
||||
Cogl API changes for Clutter 1.2
|
||||
--------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* cogl_viewport is now deprecated in favour of cogl_set_viewport which
|
||||
accepts a viewport offset.
|
||||
@ -250,7 +279,7 @@ Cogl API changes for Clutter 1.2
|
||||
|
||||
|
||||
Release Notes for Clutter 1.0
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* The clutter_actor_set_shader_param() function now takes a
|
||||
GValue, which can be set using the clutter_value_set_shader()
|
||||
@ -365,8 +394,8 @@ Release Notes for Clutter 1.0
|
||||
takes the duration of the timeline in milliseconds, and thus it replaces
|
||||
the clutter_timeline_new_for_duration() variant.
|
||||
|
||||
Cogl API changes for Clutter 1.0
|
||||
--------------------------------
|
||||
Cogl API changes for Clutter 1.0
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* All drawing functions now use a source material to determine how geometry is
|
||||
filled. The source material is set via cogl_set_source. Or the convenience
|
||||
@ -473,7 +502,7 @@ Release Notes for Clutter 1.0
|
||||
a corresponding cogl_get_depth_test_enabled function has been added.
|
||||
|
||||
Release Notes for Clutter 0.8
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* The COGL GL wrapper API has been completely overhauled and now
|
||||
contains many new features including new greatly improved texture
|
||||
@ -639,7 +668,7 @@ Release Notes for Clutter 0.8
|
||||
* ClutterContainer can have per child custom properties via ClutterChildMeta.
|
||||
|
||||
Release Notes for Clutter 0.6
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* Now that every actor has events, the class signal handlers have been
|
||||
removed from ClutterStageClass and moved into ClutterActorClass.
|
||||
@ -728,7 +757,7 @@ Release Notes for Clutter 0.6
|
||||
respectively.
|
||||
|
||||
Release Notes for Clutter 0.4.0
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* clutter_actor_show_all does not recurse for groups at least (this is to
|
||||
match the original group_show_all behaviour). This is like 0.3 but was
|
||||
@ -747,7 +776,7 @@ Release Notes for Clutter 0.4.0
|
||||
overhauled.
|
||||
|
||||
Release Notes for Clutter 0.3.1
|
||||
-------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* clutter_actor_apply_transform_to_point() parameters changed to use
|
||||
ClutterVertices.
|
||||
@ -758,7 +787,7 @@ Release Notes for Clutter 0.3.1
|
||||
* Exisiting X11 based egl backend public API calls now prefixed eglx.
|
||||
|
||||
Release Notes for Clutter 0.3
|
||||
-----------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* ClutterTexture changes:
|
||||
+ clutter_texture_set_pixbuf() now takes a GError paremeter.
|
||||
|
@ -8454,6 +8454,53 @@ clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
box->y2 = y_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_interpolate:
|
||||
* @initial: the initial #ClutterActorBox
|
||||
* @final: the final #ClutterActorBox
|
||||
* @progress: the interpolation progress
|
||||
* @result: (out): return location for the interpolation
|
||||
*
|
||||
* Interpolates between @initial and @final #ClutterActorBox<!-- -->es
|
||||
* using @progress
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
const ClutterActorBox *final,
|
||||
gdouble progress,
|
||||
ClutterActorBox *result)
|
||||
{
|
||||
g_return_if_fail (initial != NULL);
|
||||
g_return_if_fail (final != NULL);
|
||||
g_return_if_fail (result != NULL);
|
||||
|
||||
result->x1 = initial->x1 + (final->x1 - initial->x1) * progress;
|
||||
result->y1 = initial->y1 + (final->y1 - initial->y1) * progress;
|
||||
result->x2 = initial->x2 + (final->x2 - initial->x2) * progress;
|
||||
result->y2 = initial->y2 + (final->y2 - initial->y2) * progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_actor_box_clamp_to_pixel:
|
||||
* @box: (inout): the #ClutterActorBox to clamp
|
||||
*
|
||||
* Clamps the components of @box to the nearest integer
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
|
||||
{
|
||||
g_return_if_fail (box != NULL);
|
||||
|
||||
box->x1 = floorf (box->x1 + 0.5);
|
||||
box->y1 = floorf (box->y1 + 0.5);
|
||||
box->x2 = floorf (box->x2 + 0.5);
|
||||
box->y2 = floorf (box->y2 + 0.5);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct _ShaderData
|
||||
|
@ -94,8 +94,13 @@ struct _ClutterBoxLayoutPrivate
|
||||
|
||||
guint spacing;
|
||||
|
||||
gulong easing_mode;
|
||||
guint easing_duration;
|
||||
|
||||
guint is_vertical : 1;
|
||||
guint is_pack_start : 1;
|
||||
guint is_animating : 1;
|
||||
guint use_animations : 1;
|
||||
};
|
||||
|
||||
struct _ClutterBoxChild
|
||||
@ -109,6 +114,11 @@ struct _ClutterBoxChild
|
||||
guint y_fill : 1;
|
||||
|
||||
guint expand : 1;
|
||||
|
||||
/* the last stable allocation before an animation; it is
|
||||
* used as the initial ActorBox when interpolating
|
||||
*/
|
||||
ClutterActorBox *last_allocation;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -128,7 +138,10 @@ enum
|
||||
|
||||
PROP_SPACING,
|
||||
PROP_VERTICAL,
|
||||
PROP_PACK_START
|
||||
PROP_PACK_START,
|
||||
PROP_USE_ANIMATIONS,
|
||||
PROP_EASING_MODE,
|
||||
PROP_EASING_DURATION
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ClutterBoxChild,
|
||||
@ -167,8 +180,18 @@ box_child_set_align (ClutterBoxChild *self,
|
||||
if (x_changed || y_changed)
|
||||
{
|
||||
ClutterLayoutManager *layout;
|
||||
ClutterBoxLayout *box;
|
||||
|
||||
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
|
||||
box = CLUTTER_BOX_LAYOUT (layout);
|
||||
|
||||
if (box->priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (layout,
|
||||
box->priv->easing_duration,
|
||||
box->priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (layout);
|
||||
|
||||
if (x_changed)
|
||||
@ -203,8 +226,18 @@ box_child_set_fill (ClutterBoxChild *self,
|
||||
if (x_changed || y_changed)
|
||||
{
|
||||
ClutterLayoutManager *layout;
|
||||
ClutterBoxLayout *box;
|
||||
|
||||
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
|
||||
box = CLUTTER_BOX_LAYOUT (layout);
|
||||
|
||||
if (box->priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (layout,
|
||||
box->priv->easing_duration,
|
||||
box->priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (layout);
|
||||
|
||||
if (x_changed)
|
||||
@ -222,10 +255,20 @@ box_child_set_expand (ClutterBoxChild *self,
|
||||
if (self->expand != expand)
|
||||
{
|
||||
ClutterLayoutManager *layout;
|
||||
ClutterBoxLayout *box;
|
||||
|
||||
self->expand = expand;
|
||||
|
||||
layout = clutter_layout_meta_get_manager (CLUTTER_LAYOUT_META (self));
|
||||
box = CLUTTER_BOX_LAYOUT (layout);
|
||||
|
||||
if (box->priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (layout,
|
||||
box->priv->easing_duration,
|
||||
box->priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (layout);
|
||||
|
||||
g_object_notify (G_OBJECT (self), "expand");
|
||||
@ -312,6 +355,16 @@ clutter_box_child_get_property (GObject *gobject,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_box_child_finalize (GObject *gobject)
|
||||
{
|
||||
ClutterBoxChild *self = CLUTTER_BOX_CHILD (gobject);
|
||||
|
||||
clutter_actor_box_free (self->last_allocation);
|
||||
|
||||
G_OBJECT_CLASS (clutter_box_child_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_box_child_class_init (ClutterBoxChildClass *klass)
|
||||
{
|
||||
@ -320,6 +373,7 @@ clutter_box_child_class_init (ClutterBoxChildClass *klass)
|
||||
|
||||
gobject_class->set_property = clutter_box_child_set_property;
|
||||
gobject_class->get_property = clutter_box_child_get_property;
|
||||
gobject_class->finalize = clutter_box_child_finalize;
|
||||
|
||||
pspec = g_param_spec_boolean ("expand",
|
||||
"Expand",
|
||||
@ -374,6 +428,8 @@ clutter_box_child_init (ClutterBoxChild *self)
|
||||
self->x_fill = self->y_fill = FALSE;
|
||||
|
||||
self->expand = FALSE;
|
||||
|
||||
self->last_allocation = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -698,14 +754,6 @@ allocate_box_child (ClutterBoxLayout *self,
|
||||
|
||||
child_box.x1 = 0;
|
||||
child_box.x2 = floorf (avail_width + 0.5);
|
||||
|
||||
allocate_fill (child, &child_box, box_child);
|
||||
clutter_actor_allocate (child, &child_box, flags);
|
||||
|
||||
if (box_child->expand)
|
||||
*position += (child_nat + priv->spacing + extra_space);
|
||||
else
|
||||
*position += (child_nat + priv->spacing);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -721,15 +769,61 @@ allocate_box_child (ClutterBoxLayout *self,
|
||||
|
||||
child_box.y1 = 0;
|
||||
child_box.y2 = floorf (avail_height + 0.5);
|
||||
}
|
||||
|
||||
allocate_fill (child, &child_box, box_child);
|
||||
|
||||
if (priv->use_animations && priv->is_animating)
|
||||
{
|
||||
ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||
ClutterActorBox *start = NULL;
|
||||
ClutterActorBox end = { 0, };
|
||||
gdouble p;
|
||||
|
||||
p = clutter_layout_manager_get_animation_progress (manager);
|
||||
|
||||
start = box_child->last_allocation;
|
||||
if (start == NULL)
|
||||
{
|
||||
/* if there is no allocation available then the child has just
|
||||
* been added to the container; we put it in the final state
|
||||
* and store its allocation for later
|
||||
*/
|
||||
box_child->last_allocation = clutter_actor_box_copy (&child_box);
|
||||
|
||||
goto do_allocate;
|
||||
}
|
||||
|
||||
end = child_box;
|
||||
|
||||
/* interpolate between the initial and final values */
|
||||
clutter_actor_box_interpolate (start, &end, p, &child_box);
|
||||
|
||||
CLUTTER_NOTE (ANIMATION,
|
||||
"Animate { %.1f, %.1f, %.1f, %.1f }\t"
|
||||
"%.3f * { %.1f, %.1f, %.1f, %.1f }\t"
|
||||
"-> { %.1f, %.1f, %.1f, %.1f }",
|
||||
start->x1, start->y1,
|
||||
start->x2, start->y2,
|
||||
p,
|
||||
child_box.x1, child_box.y1,
|
||||
child_box.x2, child_box.y2,
|
||||
end.x1, end.y1,
|
||||
end.x2, end.y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* store the allocation for later animations */
|
||||
box_child->last_allocation = clutter_actor_box_copy (&child_box);
|
||||
}
|
||||
|
||||
do_allocate:
|
||||
clutter_actor_allocate (child, &child_box, flags);
|
||||
|
||||
if (box_child->expand)
|
||||
*position += (child_nat + priv->spacing + extra_space);
|
||||
else
|
||||
*position += (child_nat + priv->spacing);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -887,6 +981,35 @@ clutter_box_layout_allocate (ClutterLayoutManager *layout,
|
||||
g_list_free (children);
|
||||
}
|
||||
|
||||
static ClutterAlpha *
|
||||
clutter_box_layout_begin_animation (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong easing)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (manager)->priv;
|
||||
ClutterLayoutManagerClass *parent_class;
|
||||
|
||||
priv->is_animating = TRUE;
|
||||
|
||||
/* we want the default implementation */
|
||||
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class);
|
||||
|
||||
return parent_class->begin_animation (manager, duration, easing);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_box_layout_end_animation (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv = CLUTTER_BOX_LAYOUT (manager)->priv;
|
||||
ClutterLayoutManagerClass *parent_class;
|
||||
|
||||
priv->is_animating = FALSE;
|
||||
|
||||
/* we want the default implementation */
|
||||
parent_class = CLUTTER_LAYOUT_MANAGER_CLASS (clutter_box_layout_parent_class);
|
||||
parent_class->end_animation (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_box_layout_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
@ -909,6 +1032,18 @@ clutter_box_layout_set_property (GObject *gobject,
|
||||
clutter_box_layout_set_pack_start (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_USE_ANIMATIONS:
|
||||
clutter_box_layout_set_use_animations (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_EASING_MODE:
|
||||
clutter_box_layout_set_easing_mode (self, g_value_get_ulong (value));
|
||||
break;
|
||||
|
||||
case PROP_EASING_DURATION:
|
||||
clutter_box_layout_set_easing_duration (self, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -937,6 +1072,18 @@ clutter_box_layout_get_property (GObject *gobject,
|
||||
g_value_set_boolean (value, priv->is_pack_start);
|
||||
break;
|
||||
|
||||
case PROP_USE_ANIMATIONS:
|
||||
g_value_set_boolean (value, priv->use_animations);
|
||||
break;
|
||||
|
||||
case PROP_EASING_MODE:
|
||||
g_value_set_ulong (value, priv->easing_mode);
|
||||
break;
|
||||
|
||||
case PROP_EASING_DURATION:
|
||||
g_value_set_uint (value, priv->easing_duration);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -963,6 +1110,8 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
|
||||
layout_class->set_container = clutter_box_layout_set_container;
|
||||
layout_class->get_child_meta_type =
|
||||
clutter_box_layout_get_child_meta_type;
|
||||
layout_class->begin_animation = clutter_box_layout_begin_animation;
|
||||
layout_class->end_animation = clutter_box_layout_end_animation;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (ClutterBoxLayoutPrivate));
|
||||
|
||||
@ -1010,6 +1159,62 @@ clutter_box_layout_class_init (ClutterBoxLayoutClass *klass)
|
||||
0, G_MAXUINT, 0,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_SPACING, pspec);
|
||||
|
||||
/**
|
||||
* ClutterBoxLayout:use-animations:
|
||||
*
|
||||
* Whether the #ClutterBoxLayout should animate changes in the
|
||||
* layout properties
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_boolean ("use-animations",
|
||||
"Use Animations",
|
||||
"Whether layout changes should be animated",
|
||||
FALSE,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_USE_ANIMATIONS, pspec);
|
||||
|
||||
/**
|
||||
* ClutterBoxLayout:easing-mode:
|
||||
*
|
||||
* The easing mode for the animations, in case
|
||||
* #ClutterBoxLayout:use-animations is set to %TRUE
|
||||
*
|
||||
* The easing mode has the same semantics of #ClutterAnimation:mode: it can
|
||||
* either be a value from the #ClutterAnimationMode enumeration, like
|
||||
* %CLUTTER_EASE_OUT_CUBIC, or a logical id as returned by
|
||||
* clutter_alpha_register_func()
|
||||
*
|
||||
* The default value is %CLUTTER_EASE_OUT_CUBIC
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_ulong ("easing-mode",
|
||||
"Easing Mode",
|
||||
"The easing mode of the animations",
|
||||
0, G_MAXULONG,
|
||||
CLUTTER_EASE_OUT_CUBIC,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_EASING_MODE, pspec);
|
||||
|
||||
/**
|
||||
* ClutterBoxLayout:easing-duration:
|
||||
*
|
||||
* The duration of the animations, in case #ClutterBoxLayout:use-animations
|
||||
* is set to %TRUE
|
||||
*
|
||||
* The duration is expressed in milliseconds
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
pspec = g_param_spec_uint ("easing-duration",
|
||||
"Easing Duration",
|
||||
"The duration of the animations",
|
||||
0, G_MAXUINT,
|
||||
500,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
g_object_class_install_property (gobject_class, PROP_EASING_DURATION, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1022,6 +1227,10 @@ clutter_box_layout_init (ClutterBoxLayout *layout)
|
||||
priv->is_vertical = FALSE;
|
||||
priv->is_pack_start = FALSE;
|
||||
priv->spacing = 0;
|
||||
|
||||
priv->use_animations = FALSE;
|
||||
priv->easing_mode = CLUTTER_EASE_OUT_CUBIC;
|
||||
priv->easing_duration = 500;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1065,6 +1274,14 @@ clutter_box_layout_set_spacing (ClutterBoxLayout *layout,
|
||||
priv->spacing = spacing;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
|
||||
if (priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (manager,
|
||||
priv->easing_duration,
|
||||
priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "spacing");
|
||||
@ -1116,6 +1333,14 @@ clutter_box_layout_set_vertical (ClutterBoxLayout *layout,
|
||||
priv->is_vertical = vertical ? TRUE : FALSE;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
|
||||
if (priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (manager,
|
||||
priv->easing_duration,
|
||||
priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "vertical");
|
||||
@ -1170,6 +1395,14 @@ clutter_box_layout_set_pack_start (ClutterBoxLayout *layout,
|
||||
priv->is_pack_start = pack_start ? TRUE : FALSE;
|
||||
|
||||
manager = CLUTTER_LAYOUT_MANAGER (layout);
|
||||
|
||||
if (priv->use_animations)
|
||||
{
|
||||
clutter_layout_manager_begin_animation (manager,
|
||||
priv->easing_duration,
|
||||
priv->easing_mode);
|
||||
}
|
||||
else
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "pack-start");
|
||||
@ -1574,3 +1807,154 @@ clutter_box_layout_get_expand (ClutterBoxLayout *layout,
|
||||
|
||||
return CLUTTER_BOX_CHILD (meta)->expand;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_set_use_animations:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
* @animate: %TRUE if the @layout should use animations
|
||||
*
|
||||
* Sets whether @layout should animate changes in the layout properties
|
||||
*
|
||||
* The duration of the animations is controlled by
|
||||
* clutter_box_layout_set_easing_duration(); the easing mode to be used
|
||||
* by the animations is controlled by clutter_box_layout_set_easing_mode()
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
|
||||
gboolean animate)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->use_animations != animate)
|
||||
{
|
||||
priv->use_animations = animate;
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "use-animations");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_get_use_animations:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
*
|
||||
* Retrieves whether @layout should animate changes in the layout properties
|
||||
*
|
||||
* Since clutter_box_layout_set_use_animations()
|
||||
*
|
||||
* Return value: %TRUE if the animations should be used, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
gboolean
|
||||
clutter_box_layout_get_use_animations (ClutterBoxLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), FALSE);
|
||||
|
||||
return layout->priv->use_animations;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_set_easing_mode:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
* @mode: an easing mode, either from #ClutterAnimationMode or a logical id
|
||||
* from clutter_alpha_register_func()
|
||||
*
|
||||
* Sets the easing mode to be used by @layout when animating changes in layout
|
||||
* properties
|
||||
*
|
||||
* Use clutter_box_layout_set_use_animations() to enable and disable the
|
||||
* animations
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
gulong mode)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->easing_mode != mode)
|
||||
{
|
||||
priv->easing_mode = mode;
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "easing-mode");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_get_easing_mode:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
*
|
||||
* Retrieves the easing mode set using clutter_box_layout_set_easing_mode()
|
||||
*
|
||||
* Return value: an easing mode
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
gulong
|
||||
clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout),
|
||||
CLUTTER_EASE_OUT_CUBIC);
|
||||
|
||||
return layout->priv->easing_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_set_easing_duration:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
* @msecs: the duration of the animations, in milliseconds
|
||||
*
|
||||
* Sets the duration of the animations used by @layout when animating changes
|
||||
* in the layout properties
|
||||
*
|
||||
* Use clutter_box_layout_set_use_animations() to enable and disable the
|
||||
* animations
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
|
||||
guint msecs)
|
||||
{
|
||||
ClutterBoxLayoutPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_BOX_LAYOUT (layout));
|
||||
|
||||
priv = layout->priv;
|
||||
|
||||
if (priv->easing_duration != msecs)
|
||||
{
|
||||
priv->easing_duration = msecs;
|
||||
|
||||
g_object_notify (G_OBJECT (layout), "easing-duration");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_box_layout_get_easing_duration:
|
||||
* @layout: a #ClutterBoxLayout
|
||||
*
|
||||
* Retrieves the duration set using clutter_box_layout_set_easing_duration()
|
||||
*
|
||||
* Return value: the duration of the animations, in milliseconds
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
guint
|
||||
clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_BOX_LAYOUT (layout), 500);
|
||||
|
||||
return layout->priv->easing_duration;
|
||||
}
|
||||
|
@ -138,6 +138,16 @@ void clutter_box_layout_set_expand (ClutterBoxLayout *la
|
||||
gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout,
|
||||
ClutterActor *actor);
|
||||
|
||||
void clutter_box_layout_set_use_animations (ClutterBoxLayout *layout,
|
||||
gboolean animate);
|
||||
gboolean clutter_box_layout_get_use_animations (ClutterBoxLayout *layout);
|
||||
void clutter_box_layout_set_easing_mode (ClutterBoxLayout *layout,
|
||||
gulong mode);
|
||||
gulong clutter_box_layout_get_easing_mode (ClutterBoxLayout *layout);
|
||||
void clutter_box_layout_set_easing_duration (ClutterBoxLayout *layout,
|
||||
guint msecs);
|
||||
guint clutter_box_layout_get_easing_duration (ClutterBoxLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BOX_LAYOUT_H__ */
|
||||
|
@ -36,10 +36,10 @@
|
||||
* a generic container using #ClutterLayoutManager called #ClutterBox.
|
||||
*
|
||||
* Clutter provides some simple #ClutterLayoutManager sub-classes, like
|
||||
* #ClutterFixedLayout and #ClutterBinLayout.
|
||||
* #ClutterFlowLayout and #ClutterBinLayout.
|
||||
*
|
||||
* <refsect2 id="ClutterLayoutManager-use-in-Actor">
|
||||
* <title>Using ClutterLayoutManager inside an Actor</title>
|
||||
* <title>Using a Layout Manager inside an Actor</title>
|
||||
* <para>In order to use a #ClutterLayoutManager inside a #ClutterActor
|
||||
* sub-class you should invoke clutter_layout_manager_get_preferred_width()
|
||||
* inside the <structname>ClutterActor</structname>::get_preferred_width()
|
||||
@ -70,18 +70,20 @@
|
||||
* #ClutterActor, so you should read the relative documentation
|
||||
* <link linkend="clutter-subclassing-ClutterActor">for subclassing
|
||||
* ClutterActor</link>.</para>
|
||||
* <para>The layout manager implementation can hold a back reference
|
||||
* to the #ClutterContainer by implementing the set_container()
|
||||
* virtual function. The layout manager should not hold a reference
|
||||
* on the container actor, to avoid reference cycles.</para>
|
||||
* <para>The layout manager implementation can hold a back pointer
|
||||
* to the #ClutterContainer by implementing the
|
||||
* <function>set_container()</function> virtual function. The layout manager
|
||||
* should not hold a real reference (i.e. call g_object_ref()) on the
|
||||
* container actor, to avoid reference cycles.</para>
|
||||
* <para>If the layout manager has properties affecting the layout
|
||||
* policies then it should emit the #ClutterLayoutManager::layout-changed
|
||||
* signal on itself by using the clutter_layout_manager_layout_changed()
|
||||
* function.</para>
|
||||
* function whenever one of these properties changes.</para>
|
||||
* <para>If the layout manager has layout properties, that is properties that
|
||||
* should exist only as the result of the presence of a specific (layout
|
||||
* manager, container actor, child actor) combination, then it should
|
||||
* override the <structname>ClutterLayoutManager</structname>::get_child_meta_type()
|
||||
* manager, container actor, child actor) combination, and it wishes to store
|
||||
* those properties inside a #ClutterLayoutMeta then it should override the
|
||||
* <structname>ClutterLayoutManager</structname>::get_child_meta_type()
|
||||
* virtual function to return the #GType of the #ClutterLayoutMeta sub-class
|
||||
* used to store the layout properties; optionally, the #ClutterLayoutManager
|
||||
* sub-class might also override the
|
||||
@ -107,6 +109,176 @@
|
||||
* child of the #ClutterContainer.</para>
|
||||
* </refsect2>
|
||||
*
|
||||
* <refsect2 id="ClutterLayoutManager-animation">
|
||||
* <title>Animating a ClutterLayoutManager</title>
|
||||
* <para>A layout manager is used to let a #ClutterContainer take complete
|
||||
* ownership over the layout (that is: the position and sizing) of its
|
||||
* children; this means that using the Clutter animation API, like
|
||||
* clutter_actor_animate(), to animate the position and sizing of a child of
|
||||
* a layout manager it is not going to work properly, as the animation will
|
||||
* automatically override any setting done by the layout manager
|
||||
* itself.</para>
|
||||
* <para>It is possible for a #ClutterLayoutManager sub-class to animate its
|
||||
* children layout by using the base class animation support. The
|
||||
* #ClutterLayoutManager animation support consists of three virtual
|
||||
* functions: <function>begin_animation()</function>,
|
||||
* <function>get_animation_progress()</function> and
|
||||
* <function>end_animation()</function>.</para>
|
||||
* <variablelist>
|
||||
* <varlistentry>
|
||||
* <term><function>begin_animation (duration, easing)</function></term>
|
||||
* <listitem><para>This virtual function is invoked when the layout
|
||||
* manager should begin an animation. The implementation should set up
|
||||
* the state for the animation and create the ancillary objects for
|
||||
* animating the layout. The default implementation creates a
|
||||
* #ClutterTimeline for the given duration and a #ClutterAlpha binding
|
||||
* the timeline to the given easing mode. This function returns a
|
||||
* #ClutterAlpha which should be used to control the animation from
|
||||
* the caller perspective.</para></listitem>
|
||||
* </varlistentry>
|
||||
* <varlistentry>
|
||||
* <term><function>get_animation_progress()</function></term>
|
||||
* <listitem><para>This virtual function should be invoked when animating
|
||||
* a layout manager. It returns the progress of the animation, using the
|
||||
* same semantics as the #ClutterAlpha:alpha value.</para></listitem>
|
||||
* </varlistentry>
|
||||
* <varlistentry>
|
||||
* <term><function>end_animation()</function></term>
|
||||
* <listitem><para>This virtual function is invoked when the animation of
|
||||
* a layout manager ends, and it is meant to be used for bookkeeping the
|
||||
* objects created in the <function>begin_animation()</function>
|
||||
* function. The default implementation will call it implicitly when the
|
||||
* timeline is complete.</para></listitem>
|
||||
* </varlistentry>
|
||||
* </variablelist>
|
||||
* <para>The simplest way to animate a layout is to create a #ClutterTimeline
|
||||
* inside the <function>begin_animation()</function> virtual function, along
|
||||
* with a #ClutterAlpha, and for each #ClutterTimeline::new-frame signal
|
||||
* emission call clutter_layout_manager_layout_changed(), which will cause a
|
||||
* relayout. The #ClutterTimeline::completed signal emission should cause
|
||||
* clutter_layout_manager_end_animation() to be called. The default
|
||||
* implementation provided internally by #ClutterLayoutManager does exactly
|
||||
* this, so most sub-classes should either not override any animation-related
|
||||
* virtual function or simply override <function>begin_animation()</function>
|
||||
* and <function>end_animation()</function> to set up ad hoc state, and then
|
||||
* chain up to the parent's implementation.</para>
|
||||
* <example id="example-ClutterLayoutManager-animation">
|
||||
* <title>Animation of a Layout Manager</title>
|
||||
* <para>The code below shows how a #ClutterLayoutManager sub-class should
|
||||
* provide animating the allocation of its children from within the
|
||||
* <function>allocate()</function> virtual function implementation. The
|
||||
* animation is computed between the last stable allocation performed
|
||||
* before the animation started and the desired final allocation.</para>
|
||||
* <para>The <varname>is_animating</varname> variable is stored inside the
|
||||
* #ClutterLayoutManager sub-class and it is updated by overriding the
|
||||
* <function>begin_animation()</function> and
|
||||
* <function>end_animation()</function> virtual functions and chaining up
|
||||
* to the base class implementation.</para>
|
||||
* <para>The last stable allocation is stored within a #ClutterLayoutMeta
|
||||
* sub-class used by the implementation.</para>
|
||||
* <programlisting>
|
||||
* static void
|
||||
* my_layout_manager_allocate (ClutterLayoutManager *manager,
|
||||
* ClutterContainer *container,
|
||||
* const ClutterActorBox *allocation,
|
||||
* ClutterAllocationFlags flags)
|
||||
* {
|
||||
* MyLayoutManager *self = MY_LAYOUT_MANAGER (manager);
|
||||
* GList *children, *l;
|
||||
*
|
||||
* children = clutter_container_get_children (container);
|
||||
*
|
||||
* for (l = children; l != NULL; l = l->next)
|
||||
* {
|
||||
* ClutterActor *child = l->data;
|
||||
* ClutterLayoutMeta *meta;
|
||||
* MyLayoutMeta *my_meta;
|
||||
*
|
||||
* /* retrieve the layout meta-object */
|
||||
* meta = clutter_layout_manager_get_child_meta (manager,
|
||||
* container,
|
||||
* child);
|
||||
* my_meta = MY_LAYOUT_META (meta);
|
||||
*
|
||||
* /* compute the desired allocation for the child */
|
||||
* compute_allocation (self, my_meta, child,
|
||||
* allocation, flags,
|
||||
* &child_box);
|
||||
*
|
||||
* /* this is the additional code that deals with the animation
|
||||
* * of the layout manager
|
||||
* */
|
||||
* if (!self->is_animating)
|
||||
* {
|
||||
* /* store the last stable allocation for later use */
|
||||
* my_meta->last_alloc = clutter_actor_box_copy (&child_box);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* ClutterActorBox end = { 0, };
|
||||
* gdouble p;
|
||||
*
|
||||
* /* get the progress of the animation */
|
||||
* p = clutter_layout_manager_get_animation_progress (manager);
|
||||
*
|
||||
* if (my_meta->last_alloc != NULL)
|
||||
* {
|
||||
* /* copy the desired allocation as the final state */
|
||||
* end = child_box;
|
||||
*
|
||||
* /* then interpolate the initial and final state
|
||||
* * depending on the progress of the animation,
|
||||
* * and put the result inside the box we will use
|
||||
* * to allocate the child
|
||||
* */
|
||||
* clutter_actor_box_interpolate (my_meta->last_alloc,
|
||||
* &end,
|
||||
* p,
|
||||
* &child_box);
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* /* if there is no stable allocation then the child was
|
||||
* * added while animating; one possible course of action
|
||||
* * is to just bail out and fall through to the allocation
|
||||
* * to position the child directly at its final state
|
||||
* */
|
||||
* my_meta->last_alloc =
|
||||
* clutter_actor_box_copy (&child_box);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* /* allocate the child */
|
||||
* clutter_actor_allocate (child, &child_box, flags);
|
||||
* }
|
||||
*
|
||||
* g_list_free (children);
|
||||
* }
|
||||
* </programlisting>
|
||||
* </example>
|
||||
* <para>Sub-classes of #ClutterLayoutManager that support animations of the
|
||||
* layout changes should call clutter_layout_manager_begin_animation()
|
||||
* whenever a layout property changes value, e.g.:</para>
|
||||
* <informalexample>
|
||||
* <programlisting>
|
||||
* if (self->orientation != new_orientation)
|
||||
* {
|
||||
* ClutterLayoutManager *manager;
|
||||
*
|
||||
* self->orientation = new_orientation;
|
||||
*
|
||||
* manager = CLUTTER_LAYOUT_MANAGER (self);
|
||||
* clutter_layout_manager_layout_changed (manager);
|
||||
* clutter_layout_manager_begin_animation (manager, 500, CLUTTER_LINEAR);
|
||||
*
|
||||
* g_object_notify (G_OBJECT (self), "orientation");
|
||||
* }
|
||||
* </programlisting>
|
||||
* </informalexample>
|
||||
* <para>The code above will animate a change in the
|
||||
* <varname>orientation</varname> layout property of a layout manager.</para>
|
||||
* </refsect2>
|
||||
*
|
||||
* #ClutterLayoutManager is available since Clutter 1.2
|
||||
*/
|
||||
|
||||
@ -117,11 +289,13 @@
|
||||
#include <glib-object.h>
|
||||
#include <gobject/gvaluecollector.h>
|
||||
|
||||
#include "clutter-alpha.h"
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-layout-manager.h"
|
||||
#include "clutter-layout-meta.h"
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-timeline.h"
|
||||
|
||||
#define LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED(m,method) G_STMT_START { \
|
||||
GObject *_obj = G_OBJECT (m); \
|
||||
@ -142,6 +316,8 @@ G_DEFINE_ABSTRACT_TYPE (ClutterLayoutManager,
|
||||
G_TYPE_INITIALLY_UNOWNED);
|
||||
|
||||
static GQuark quark_layout_meta = 0;
|
||||
static GQuark quark_layout_alpha = 0;
|
||||
|
||||
static guint manager_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static void
|
||||
@ -217,17 +393,105 @@ layout_manager_real_get_child_meta_type (ClutterLayoutManager *manager)
|
||||
return G_TYPE_INVALID;
|
||||
}
|
||||
|
||||
static ClutterAlpha *
|
||||
layout_manager_real_begin_animation (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha != NULL)
|
||||
{
|
||||
clutter_alpha_set_mode (alpha, mode);
|
||||
|
||||
timeline = clutter_alpha_get_timeline (alpha);
|
||||
clutter_timeline_set_duration (timeline, duration);
|
||||
clutter_timeline_rewind (timeline);
|
||||
|
||||
return alpha;
|
||||
};
|
||||
|
||||
timeline = clutter_timeline_new (duration);
|
||||
|
||||
alpha = clutter_alpha_new_full (timeline, mode);
|
||||
|
||||
/* let the alpha take ownership of the timeline */
|
||||
g_object_unref (timeline);
|
||||
|
||||
g_signal_connect_swapped (timeline, "completed",
|
||||
G_CALLBACK (clutter_layout_manager_end_animation),
|
||||
manager);
|
||||
g_signal_connect_swapped (timeline, "new-frame",
|
||||
G_CALLBACK (clutter_layout_manager_layout_changed),
|
||||
manager);
|
||||
|
||||
g_object_set_qdata_full (G_OBJECT (manager),
|
||||
quark_layout_alpha, alpha,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
|
||||
clutter_timeline_start (timeline);
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
layout_manager_real_get_animation_progress (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha == NULL)
|
||||
return 1.0;
|
||||
|
||||
return clutter_alpha_get_alpha (alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
layout_manager_real_end_animation (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterTimeline *timeline;
|
||||
ClutterAlpha *alpha;
|
||||
|
||||
alpha = g_object_get_qdata (G_OBJECT (manager), quark_layout_alpha);
|
||||
if (alpha == NULL)
|
||||
return;
|
||||
|
||||
timeline = clutter_alpha_get_timeline (alpha);
|
||||
g_assert (timeline != NULL);
|
||||
|
||||
if (clutter_timeline_is_playing (timeline))
|
||||
clutter_timeline_stop (timeline);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (timeline,
|
||||
G_CALLBACK (clutter_layout_manager_end_animation),
|
||||
manager);
|
||||
g_signal_handlers_disconnect_by_func (timeline,
|
||||
G_CALLBACK (clutter_layout_manager_layout_changed),
|
||||
manager);
|
||||
|
||||
g_object_set_qdata (G_OBJECT (manager), quark_layout_alpha, NULL);
|
||||
|
||||
clutter_layout_manager_layout_changed (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_layout_manager_class_init (ClutterLayoutManagerClass *klass)
|
||||
{
|
||||
quark_layout_meta =
|
||||
g_quark_from_static_string ("clutter-layout-manager-child-meta");
|
||||
quark_layout_alpha =
|
||||
g_quark_from_static_string ("clutter-layout-manager-alpha");
|
||||
|
||||
klass->get_preferred_width = layout_manager_real_get_preferred_width;
|
||||
klass->get_preferred_height = layout_manager_real_get_preferred_height;
|
||||
klass->allocate = layout_manager_real_allocate;
|
||||
klass->create_child_meta = layout_manager_real_create_child_meta;
|
||||
klass->get_child_meta_type = layout_manager_real_get_child_meta_type;
|
||||
klass->begin_animation = layout_manager_real_begin_animation;
|
||||
klass->get_animation_progress = layout_manager_real_get_animation_progress;
|
||||
klass->end_animation = layout_manager_real_end_animation;
|
||||
|
||||
/**
|
||||
* ClutterLayoutManager::layout-changed:
|
||||
@ -905,3 +1169,81 @@ clutter_layout_manager_list_child_properties (ClutterLayoutManager *manager,
|
||||
|
||||
return pspecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_manager_begin_animation:
|
||||
* @manager: a #ClutterLayoutManager
|
||||
* @duration: the duration of the animation, in milliseconds
|
||||
* @mode: the easing mode of the animation
|
||||
*
|
||||
* Begins an animation of @duration milliseconds, using the provided
|
||||
* easing @mode
|
||||
*
|
||||
* The easing mode can be specified either as a #ClutterAnimationMode
|
||||
* or as a logical id returned by clutter_alpha_register_func()
|
||||
*
|
||||
* The result of this function depends on the @manager implementation
|
||||
*
|
||||
* Return value: (transfer none): The #ClutterAlpha created by the
|
||||
* layout manager; the returned instance is owned by the layout
|
||||
* manager and should not be unreferenced
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
ClutterAlpha *
|
||||
clutter_layout_manager_begin_animation (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode)
|
||||
{
|
||||
ClutterLayoutManagerClass *klass;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), NULL);
|
||||
|
||||
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return klass->begin_animation (manager, duration, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_manager_end_animation:
|
||||
* @manager: a #ClutterLayoutManager
|
||||
*
|
||||
* Ends an animation started by clutter_layout_manager_begin_animation()
|
||||
*
|
||||
* The result of this call depends on the @manager implementation
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
void
|
||||
clutter_layout_manager_end_animation (ClutterLayoutManager *manager)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||
|
||||
CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager)->end_animation (manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_layout_manager_get_animation_progress:
|
||||
* @manager: a #ClutterLayoutManager
|
||||
*
|
||||
* Retrieves the progress of the animation, if one has been started by
|
||||
* clutter_layout_manager_begin_animation()
|
||||
*
|
||||
* The returned value has the same semantics of the #ClutterAlpha:alpha
|
||||
* value
|
||||
*
|
||||
* Return value: the progress of the animation
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
gdouble
|
||||
clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager)
|
||||
{
|
||||
ClutterLayoutManagerClass *klass;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_LAYOUT_MANAGER (manager), 1.0);
|
||||
|
||||
klass = CLUTTER_LAYOUT_MANAGER_GET_CLASS (manager);
|
||||
|
||||
return klass->get_animation_progress (manager);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define __CLUTTER_LAYOUT_MANAGER_H__
|
||||
|
||||
#include <clutter/clutter-actor.h>
|
||||
#include <clutter/clutter-alpha.h>
|
||||
#include <clutter/clutter-container.h>
|
||||
#include <clutter/clutter-types.h>
|
||||
|
||||
@ -82,6 +83,12 @@ struct _ClutterLayoutManager
|
||||
* @create_child_meta: virtual function; override to create a
|
||||
* #ClutterLayoutMeta instance associated to a #ClutterContainer and a
|
||||
* child #ClutterActor, used to maintain layout manager specific properties
|
||||
* @begin_animation: virtual function; override to control the animation
|
||||
* of a #ClutterLayoutManager with the given duration and easing mode
|
||||
* @end_animation: virtual function; override to end an animation started
|
||||
* by clutter_layout_manager_begin_animation()
|
||||
* @get_animation_progress: virtual function; override to control the
|
||||
* progress of the animation of a #ClutterLayoutManager
|
||||
* @layout_changed: class handler for the #ClutterLayoutManager::layout-changed
|
||||
* signal
|
||||
*
|
||||
@ -96,6 +103,7 @@ struct _ClutterLayoutManagerClass
|
||||
GInitiallyUnownedClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
/* vfuncs, not signals */
|
||||
void (* get_preferred_width) (ClutterLayoutManager *manager,
|
||||
ClutterContainer *container,
|
||||
gfloat for_height,
|
||||
@ -119,6 +127,13 @@ struct _ClutterLayoutManagerClass
|
||||
ClutterContainer *container,
|
||||
ClutterActor *actor);
|
||||
|
||||
ClutterAlpha * (* begin_animation) (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode);
|
||||
gdouble (* get_animation_progress) (ClutterLayoutManager *manager);
|
||||
void (* end_animation) (ClutterLayoutManager *manager);
|
||||
|
||||
/* signals */
|
||||
void (* layout_changed) (ClutterLayoutManager *manager);
|
||||
|
||||
/*< private >*/
|
||||
@ -184,6 +199,12 @@ void clutter_layout_manager_child_get_property (ClutterLayoutMa
|
||||
const gchar *property_name,
|
||||
GValue *value);
|
||||
|
||||
ClutterAlpha * clutter_layout_manager_begin_animation (ClutterLayoutManager *manager,
|
||||
guint duration,
|
||||
gulong mode);
|
||||
void clutter_layout_manager_end_animation (ClutterLayoutManager *manager);
|
||||
gdouble clutter_layout_manager_get_animation_progress (ClutterLayoutManager *manager);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_LAYOUT_MANAGER_H__ */
|
||||
|
@ -153,6 +153,11 @@ gboolean clutter_actor_box_contains (const ClutterActorBox *box,
|
||||
gfloat y);
|
||||
void clutter_actor_box_from_vertices (ClutterActorBox *box,
|
||||
const ClutterVertex verts[]);
|
||||
void clutter_actor_box_interpolate (const ClutterActorBox *initial,
|
||||
const ClutterActorBox *final,
|
||||
gdouble progress,
|
||||
ClutterActorBox *result);
|
||||
void clutter_actor_box_clamp_to_pixel (ClutterActorBox *box);
|
||||
|
||||
/**
|
||||
* ClutterGeometry:
|
||||
|
@ -416,6 +416,8 @@ clutter_actor_box_get_size
|
||||
clutter_actor_box_get_area
|
||||
clutter_actor_box_contains
|
||||
clutter_actor_box_from_vertices
|
||||
clutter_actor_box_clamp_to_pixel
|
||||
clutter_actor_box_interpolate
|
||||
|
||||
<SUBSECTION>
|
||||
ClutterVertex
|
||||
@ -1771,6 +1773,11 @@ clutter_layout_manager_child_get_property
|
||||
clutter_layout_manager_find_child_property
|
||||
clutter_layout_manager_list_child_properties
|
||||
|
||||
<SUBSECTION>
|
||||
clutter_layout_manager_begin_animation
|
||||
clutter_layout_manager_end_animation
|
||||
clutter_layout_manager_get_animation_progress
|
||||
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_TYPE_LAYOUT_MANAGER
|
||||
CLUTTER_LAYOUT_MANAGER
|
||||
@ -1935,6 +1942,14 @@ clutter_box_layout_get_expand
|
||||
clutter_box_layout_set_fill
|
||||
clutter_box_layout_get_fill
|
||||
|
||||
<SUBSECTION>
|
||||
clutter_box_layout_set_use_animations
|
||||
clutter_box_layout_get_use_animations
|
||||
clutter_box_layout_set_easing_duration
|
||||
clutter_box_layout_get_easing_duration
|
||||
clutter_box_layout_set_easing_mode
|
||||
clutter_box_layout_get_easing_mode
|
||||
|
||||
<SUBSECTION Standard>
|
||||
CLUTTER_TYPE_BOX_LAYOUT
|
||||
CLUTTER_BOX_LAYOUT
|
||||
|
@ -29,6 +29,7 @@
|
||||
"Press v\t\342\236\236\tSwitch horizontal/vertical\n" \
|
||||
"Press p\t\342\236\236\tSwitch pack start/end\n" \
|
||||
"Press s\t\342\236\236\tIncrement spacing (up to 12px)\n" \
|
||||
"Press a\t\342\236\236\tSwitch animations on/off\n" \
|
||||
"Press q\t\342\236\236\tQuit"
|
||||
|
||||
static ClutterActor *hover_actor = NULL;
|
||||
@ -169,6 +170,11 @@ key_release_cb (ClutterActor *actor,
|
||||
|
||||
switch (clutter_event_get_key_symbol (event))
|
||||
{
|
||||
case CLUTTER_a:
|
||||
toggle = clutter_box_layout_get_use_animations (layout);
|
||||
clutter_box_layout_set_use_animations (layout, !toggle);
|
||||
break;
|
||||
|
||||
case CLUTTER_v:
|
||||
toggle = clutter_box_layout_get_vertical (layout);
|
||||
clutter_box_layout_set_vertical (layout, !toggle);
|
||||
|
Loading…
x
Reference in New Issue
Block a user