actor: Implement implicit animatable properties
Clutter is meant to be, and I quote from the README, a toolkit: for creating fast, compelling, portable, and dynamic graphical user interfaces and yet the default mode of operation for setting an actor's state on the scene graph (position, size, opacity, rotation, scaling, depth, etc.) is *not* dynamic. We assume a static UI, and then animate it. This is the wrong way to design an API for a toolkit meant to be used to create animated user interfaces. The default mode of operation should be to implicitly animate every state transition, and only allow skipping the animation if the user consciously decides to do so — i.e. the design tenet of the API should be to make The Right Thing™ by default, and make it really hard (or even impossible) to do The Wrong Thing™. So we should identify "animatable" properties, i.e. those properties that should be implicitly animated by ClutterActor, and use the animation framework we provide to tween the transitions between the current state and the desired state; the implicit animation should happen when setting these properties using the public accessors, and not through some added functionality. For instance, the following: clutter_actor_set_position (actor, newX, newY); should not make the actor jump to the (newX, newY) point; it should tween the actor's position between the current point and the desired point. Since we have to maintain backward compatibility with existing applications, we still need to mark the transitions explicitly, but we can be smart about it, and treat transition states as a stack that can be pushed and popped, e.g.: clutter_actor_save_easing_state (actor); clutter_actor_set_easing_duration (actor, 500); clutter_actor_set_position (actor, newX, newY); clutter_actor_set_opacity (actor, newOpacity); clutter_actor_restore_easing_state (actor); And we can even start stacking animations, e.g.: clutter_actor_save_easing_state (actor); clutter_actor_set_easing_duration (actor, 500); clutter_actor_set_position (actor, newX, newY); clutter_actor_save_easing_state (actor); clutter_actor_set_easing_duration (actor, 500); clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); clutter_actor_set_opacity (actor, newOpacity); clutter_actor_set_depth (actor, newDepth); clutter_actor_restore_easing_state (actor); clutter_actor_restore_easing_state (actor); And so on, and so forth. The implementation takes advantage of the newly added Transition API, which uses only ClutterTimeline sub-classes and ClutterInterval, to cut down the amount of signal emissions and memory management of object instances; as well of using the ClutterAnimatable interface for custom properties and interpolation of values.
This commit is contained in:
parent
40bcbf9c0d
commit
67113ed690
@ -113,6 +113,7 @@ typedef struct _SizeRequest SizeRequest;
|
||||
|
||||
typedef struct _ClutterLayoutInfo ClutterLayoutInfo;
|
||||
typedef struct _ClutterTransformInfo ClutterTransformInfo;
|
||||
typedef struct _ClutterAnimationInfo ClutterAnimationInfo;
|
||||
|
||||
/* Internal helper struct to represent a point that can be stored in
|
||||
either direct pixel coordinates or as a fraction of the actor's
|
||||
@ -202,11 +203,39 @@ struct _ClutterTransformInfo
|
||||
|
||||
/* anchor point */
|
||||
AnchorCoord anchor;
|
||||
|
||||
/* depth */
|
||||
gfloat depth;
|
||||
};
|
||||
|
||||
const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self);
|
||||
ClutterTransformInfo * _clutter_actor_get_transform_info (ClutterActor *self);
|
||||
|
||||
typedef struct _AState {
|
||||
guint easing_duration;
|
||||
ClutterAnimationMode easing_mode;
|
||||
} AState;
|
||||
|
||||
struct _ClutterAnimationInfo
|
||||
{
|
||||
GArray *states;
|
||||
AState *cur_state;
|
||||
|
||||
GHashTable *transitions;
|
||||
};
|
||||
|
||||
const ClutterAnimationInfo * _clutter_actor_get_animation_info_or_defaults (ClutterActor *self);
|
||||
ClutterAnimationInfo * _clutter_actor_get_animation_info (ClutterActor *self);
|
||||
|
||||
ClutterTransition * _clutter_actor_create_transition (ClutterActor *self,
|
||||
GParamSpec *pspec,
|
||||
...);
|
||||
ClutterTransition * _clutter_actor_get_transition (ClutterActor *self,
|
||||
GParamSpec *pspec);
|
||||
void _clutter_actor_update_transition (ClutterActor *self,
|
||||
GParamSpec *pspec,
|
||||
...);
|
||||
|
||||
gboolean _clutter_actor_foreach_child (ClutterActor *self,
|
||||
ClutterForeachCallback callback,
|
||||
gpointer user_data);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -642,6 +642,18 @@ void clutter_actor_apply_relative_transform_to_point
|
||||
void clutter_actor_get_transformation_matrix (ClutterActor *self,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
/* Implicit animations */
|
||||
void clutter_actor_save_easing_state (ClutterActor *self);
|
||||
void clutter_actor_restore_easing_state (ClutterActor *self);
|
||||
void clutter_actor_set_easing_mode (ClutterActor *self,
|
||||
ClutterAnimationMode mode);
|
||||
ClutterAnimationMode clutter_actor_get_easing_mode (ClutterActor *self);
|
||||
void clutter_actor_set_easing_duration (ClutterActor *self,
|
||||
guint msecs);
|
||||
guint clutter_actor_get_easing_duration (ClutterActor *self);
|
||||
ClutterTransition * clutter_actor_get_transition (ClutterActor *self,
|
||||
const char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ACTOR_H__ */
|
||||
|
@ -75,6 +75,8 @@ typedef struct _ClutterMainContext ClutterMainContext;
|
||||
#define CLUTTER_PARAM_WRITABLE (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)
|
||||
#define CLUTTER_PARAM_READWRITE (G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)
|
||||
|
||||
#define CLUTTER_PARAM_ANIMATABLE (1 << G_PARAM_USER_SHIFT)
|
||||
|
||||
/* automagic interning of a static string */
|
||||
#define I_(str) (g_intern_static_string ((str)))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user