diff --git a/clutter/clutter-box-layout.c b/clutter/clutter-box-layout.c index 49b31a686..00b16256a 100644 --- a/clutter/clutter-box-layout.c +++ b/clutter/clutter-box-layout.c @@ -94,11 +94,14 @@ struct _ClutterBoxLayoutPrivate guint spacing; + gulong easing_mode; + guint easing_duration; GHashTable *allocations; - guint is_vertical : 1; - guint is_pack_start : 1; - guint is_animating : 1; + guint is_vertical : 1; + guint is_pack_start : 1; + guint is_animating : 1; + guint use_animations : 1; }; struct _ClutterBoxChild @@ -131,7 +134,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, @@ -170,10 +176,19 @@ 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)); - clutter_layout_manager_begin_animation (layout, 500, CLUTTER_EASE_OUT_CUBIC); - clutter_layout_manager_layout_changed (layout); + 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) g_object_notify (G_OBJECT (self), "x-align"); @@ -207,10 +222,19 @@ 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)); - clutter_layout_manager_begin_animation (layout, 500, CLUTTER_EASE_OUT_CUBIC); - clutter_layout_manager_layout_changed (layout); + 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) g_object_notify (G_OBJECT (self), "x-fill"); @@ -227,12 +251,21 @@ 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)); - clutter_layout_manager_begin_animation (layout, 500, CLUTTER_EASE_OUT_CUBIC); - clutter_layout_manager_layout_changed (layout); + 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"); } @@ -723,7 +756,7 @@ allocate_box_child (ClutterBoxLayout *self, allocate_fill (child, &child_box, box_child); - if (priv->is_animating) + if (priv->use_animations && priv->is_animating) { ClutterLayoutManager *manager = CLUTTER_LAYOUT_MANAGER (self); ClutterActorBox *start = NULL; @@ -987,6 +1020,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; @@ -1015,6 +1060,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; @@ -1101,6 +1158,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 @@ -1114,6 +1227,10 @@ clutter_box_layout_init (ClutterBoxLayout *layout) priv->is_pack_start = FALSE; priv->spacing = 0; + priv->use_animations = FALSE; + priv->easing_mode = CLUTTER_EASE_OUT_CUBIC; + priv->easing_duration = 500; + priv->allocations = g_hash_table_new_full (NULL, NULL, NULL, @@ -1161,7 +1278,15 @@ clutter_box_layout_set_spacing (ClutterBoxLayout *layout, priv->spacing = spacing; manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_begin_animation (manager, 500, CLUTTER_EASE_OUT_CUBIC); + + 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"); } @@ -1212,7 +1337,15 @@ clutter_box_layout_set_vertical (ClutterBoxLayout *layout, priv->is_vertical = vertical ? TRUE : FALSE; manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_begin_animation (manager, 500, CLUTTER_EASE_OUT_CUBIC); + + 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"); } @@ -1266,7 +1399,15 @@ clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, priv->is_pack_start = pack_start ? TRUE : FALSE; manager = CLUTTER_LAYOUT_MANAGER (layout); - clutter_layout_manager_begin_animation (manager, 500, CLUTTER_EASE_OUT_CUBIC); + + 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"); } @@ -1670,3 +1811,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; +} diff --git a/clutter/clutter-box-layout.h b/clutter/clutter-box-layout.h index be2be9130..035368ac2 100644 --- a/clutter/clutter-box-layout.h +++ b/clutter/clutter-box-layout.h @@ -97,46 +97,56 @@ struct _ClutterBoxLayoutClass GType clutter_box_layout_get_type (void) G_GNUC_CONST; -ClutterLayoutManager *clutter_box_layout_new (void); +ClutterLayoutManager *clutter_box_layout_new (void); -void clutter_box_layout_set_spacing (ClutterBoxLayout *layout, - guint spacing); -guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout); -void clutter_box_layout_set_vertical (ClutterBoxLayout *layout, - gboolean vertical); -gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout); -void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, - gboolean pack_start); -gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout); +void clutter_box_layout_set_spacing (ClutterBoxLayout *layout, + guint spacing); +guint clutter_box_layout_get_spacing (ClutterBoxLayout *layout); +void clutter_box_layout_set_vertical (ClutterBoxLayout *layout, + gboolean vertical); +gboolean clutter_box_layout_get_vertical (ClutterBoxLayout *layout); +void clutter_box_layout_set_pack_start (ClutterBoxLayout *layout, + gboolean pack_start); +gboolean clutter_box_layout_get_pack_start (ClutterBoxLayout *layout); -void clutter_box_layout_pack (ClutterBoxLayout *layout, - ClutterActor *actor, - gboolean expand, - gboolean x_fill, - gboolean y_fill, - ClutterBoxAlignment x_align, - ClutterBoxAlignment y_align); -void clutter_box_layout_set_alignment (ClutterBoxLayout *layout, - ClutterActor *actor, - ClutterBoxAlignment x_align, - ClutterBoxAlignment y_align); -void clutter_box_layout_get_alignment (ClutterBoxLayout *layout, - ClutterActor *actor, - ClutterBoxAlignment *x_align, - ClutterBoxAlignment *y_align); -void clutter_box_layout_set_fill (ClutterBoxLayout *layout, - ClutterActor *actor, - gboolean x_fill, - gboolean y_fill); -void clutter_box_layout_get_fill (ClutterBoxLayout *layout, - ClutterActor *actor, - gboolean *x_fill, - gboolean *y_fill); -void clutter_box_layout_set_expand (ClutterBoxLayout *layout, - ClutterActor *actor, - gboolean expand); -gboolean clutter_box_layout_get_expand (ClutterBoxLayout *layout, - ClutterActor *actor); +void clutter_box_layout_pack (ClutterBoxLayout *layout, + ClutterActor *actor, + gboolean expand, + gboolean x_fill, + gboolean y_fill, + ClutterBoxAlignment x_align, + ClutterBoxAlignment y_align); +void clutter_box_layout_set_alignment (ClutterBoxLayout *layout, + ClutterActor *actor, + ClutterBoxAlignment x_align, + ClutterBoxAlignment y_align); +void clutter_box_layout_get_alignment (ClutterBoxLayout *layout, + ClutterActor *actor, + ClutterBoxAlignment *x_align, + ClutterBoxAlignment *y_align); +void clutter_box_layout_set_fill (ClutterBoxLayout *layout, + ClutterActor *actor, + gboolean x_fill, + gboolean y_fill); +void clutter_box_layout_get_fill (ClutterBoxLayout *layout, + ClutterActor *actor, + gboolean *x_fill, + gboolean *y_fill); +void clutter_box_layout_set_expand (ClutterBoxLayout *layout, + ClutterActor *actor, + gboolean expand); +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 diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 2bd5f55eb..8ad28f785 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -1937,6 +1937,14 @@ clutter_box_layout_get_expand clutter_box_layout_set_fill clutter_box_layout_get_fill + +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 + CLUTTER_TYPE_BOX_LAYOUT CLUTTER_BOX_LAYOUT diff --git a/tests/interactive/test-box-layout.c b/tests/interactive/test-box-layout.c index e45631880..a8b72453a 100644 --- a/tests/interactive/test-box-layout.c +++ b/tests/interactive/test-box-layout.c @@ -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; @@ -167,6 +168,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);