#include <Elementary.h>
#include "elm_priv.h"
-/**
- *
- * @defgroup Transit Transit
- * @ingroup Elementary
- *
- * Transit is designed to set the various effects for the Evas_Object such like translation,
- * rotation, etc. For using Effects, Create transit and insert the some of effects which are
- * interested. Each effects has the type of Elm_Effect and those can be inserted into transit.
- * Once effects are inserted into transit, transit will manage those effects.(ex) deleting).
-*/
-struct _transit
-{
- Evas_Object *parent;
- Elm_Animator *animator;
- Eina_List *effect_list;
- Evas_Object *block_rect;
- void (*completion_op) (void *data, Elm_Transit *transit);
- void *completion_arg;
- Eina_Bool reserved_del:1;
+#define ELM_TRANSIT_CHECK_OR_RETURN(transit, ...) \
+ do { \
+ if (!transit) { \
+ CRITICAL("Elm_Transit " # transit " is NULL!"); \
+ return __VA_ARGS__; \
+ } \
+ if (!EINA_MAGIC_CHECK(transit, ELM_TRANSIT_MAGIC)) { \
+ EINA_MAGIC_FAIL(transit, ELM_TRANSIT_MAGIC); \
+ return __VA_ARGS__; \
+ } \
+ if (transit->deleted){ \
+ ERR("Elm_Transit " # transit " has already been deleted!"); \
+ return __VA_ARGS__; \
+ } \
+ } while (0)
+
+
+#define _TRANSIT_FOCAL 2000
+
+struct _Elm_Transit
+{
+#define ELM_TRANSIT_MAGIC 0xd27f190a
+ EINA_MAGIC;
+
+ Ecore_Animator *animator;
+ Eina_Inlist *effect_list;
+ Eina_List *objs;
+ Elm_Transit *prev_chain_transit;
+ Eina_List *next_chain_transits;
+ Elm_Transit_Tween_Mode tween_mode;
+ struct {
+ Elm_Transit_Del_Cb func;
+ void *arg;
+ } del_data;
+ struct {
+ double delayed;
+ double paused;
+ double duration;
+ double begin;
+ double current;
+ } time;
+ struct {
+ int count;
+ int current;
+ Eina_Bool reverse;
+ } repeat;
+ double progress;
+ unsigned int effects_pending_del;
+ int walking;
+ Eina_Bool auto_reverse : 1;
+ Eina_Bool event_enabled : 1;
+ Eina_Bool deleted : 1;
+ Eina_Bool state_keep : 1;
+ Eina_Bool finished : 1;
};
-struct _effect
+struct _Elm_Transit_Effect_Module
{
- void (*animation_op) (void *data, Elm_Animator *animator, double frame);
- void (*begin_op) (void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
- void (*end_op) (void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
- void (*del_op) (void* data);
- unsigned int shared_cnt;
- void *user_data;
+ EINA_INLIST;
+ Elm_Transit_Effect_Transition_Cb transition_cb;
+ Elm_Transit_Effect_End_Cb end_cb;
+ Elm_Transit_Effect *effect;
+ Eina_Bool deleted : 1;
};
-static Evas_Object *_create_block_rect(Evas_Object *parent);
-static void _transit_animate_cb(void *data, Elm_Animator *animator,
- double frame);
-static void _transit_fx_begin(Elm_Transit *transit);
-static void _transit_fx_end(Elm_Transit *transit);
-static void _transit_complete_cb(void *data);
-static void _transit_fx_del(Elm_Effect *effect);
-//static void _transit_parent_del(void *data);
-
-/*
-static void
-_animator_parent_del(void *data)
+struct _Elm_Transit_Obj_State
{
- Elm_Transit *transit = data;
- elm_transit_del(data);
-}
-*/
+ Evas_Coord x, y, w, h;
+ int r,g,b,a;
+ Evas_Map *map;
+ Eina_Bool map_enabled : 1;
+ Eina_Bool visible : 1;
+};
-static Evas_Object *
-_create_block_rect(Evas_Object *parent)
+struct _Elm_Transit_Obj_Data
{
- Evas_Object *rect;
+ struct _Elm_Transit_Obj_State *state;
+ Eina_Bool freeze_events : 1;
+};
- Evas_Coord w, h;
+typedef struct _Elm_Transit_Effect_Module Elm_Transit_Effect_Module;
+typedef struct _Elm_Transit_Obj_Data Elm_Transit_Obj_Data;
+typedef struct _Elm_Transit_Obj_State Elm_Transit_Obj_State;
- rect = evas_object_rectangle_add(evas_object_evas_get(parent));
- evas_output_size_get(evas_object_evas_get(parent), &w, &h);
- evas_object_resize(rect, w, h);
- evas_object_color_set(rect, 0, 0, 0, 0);
- return rect;
-}
+static void _transit_obj_data_update(Elm_Transit *transit, Evas_Object *obj);
+static void _transit_obj_data_recover(Elm_Transit *transit, Evas_Object *obj);
+static void _transit_obj_states_save(Evas_Object *obj, Elm_Transit_Obj_Data *obj_data);
+static void _transit_obj_remove_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__);
+static void _transit_obj_remove(Elm_Transit *transit, Evas_Object *obj);
+static void _transit_effect_del(Elm_Transit *transit, Elm_Transit_Effect_Module *effect_module);
+static void _transit_remove_dead_effects(Elm_Transit *transit);
+static void _transit_chain_go(Elm_Transit *transit);
+static void _transit_del(Elm_Transit *transit);
+static Eina_Bool _transit_animate_op(Elm_Transit *transit, double progress);
+static Eina_Bool _transit_animate_cb(void *data);
+
+static char *_transit_key= "_elm_transit_key";
static void
-_transit_animate_cb(void *data, Elm_Animator *animator, double frame)
+_transit_obj_data_update(Elm_Transit *transit, Evas_Object *obj)
{
- Eina_List *elist;
+ Elm_Transit_Obj_Data *obj_data = evas_object_data_get(obj, _transit_key);
- Elm_Effect *effect;
+ if (!obj_data)
+ obj_data = ELM_NEW(Elm_Transit_Obj_Data);
- Elm_Transit *transit = data;
+ obj_data->freeze_events = evas_object_freeze_events_get(obj);
- EINA_LIST_FOREACH(transit->effect_list, elist, effect)
- {
- effect->animation_op(effect->user_data, animator, frame);
- }
+ if ((!transit->state_keep) && (obj_data->state))
+ {
+ free(obj_data->state);
+ obj_data->state = NULL;
+ }
+ else
+ {
+ _transit_obj_states_save(obj, obj_data);
+ }
+
+ evas_object_data_set(obj, _transit_key, obj_data);
}
static void
-_transit_fx_begin(Elm_Transit *transit)
+_transit_obj_states_save(Evas_Object *obj, Elm_Transit_Obj_Data *obj_data)
{
- Eina_List *elist;
+ Elm_Transit_Obj_State *state = obj_data->state;
- Elm_Effect *effect;
+ if (!state)
+ state = calloc(1, sizeof(Elm_Transit_Obj_State));
+ if (!state) return;
- Eina_Bool auto_reverse;
-
- unsigned int repeat_cnt;
+ evas_object_geometry_get(obj, &state->x, &state->y, &state->w, &state->h);
+ evas_object_color_get(obj, &state->r, &state->g, &state->b, &state->a);
+ state->visible = evas_object_visible_get(obj);
+ state->map_enabled = evas_object_map_enable_get(obj);
+ if (evas_object_map_get(obj))
+ state->map = evas_map_dup(evas_object_map_get(obj));
+ obj_data->state = state;
+}
- auto_reverse = elm_animator_auto_reverse_get(transit->animator);
- repeat_cnt = elm_animator_repeat_get(transit->animator);
+static void
+_remove_obj_from_list(Elm_Transit *transit, Evas_Object *obj)
+{
+ //Remove duplicated objects
+ //TODO: Need to consider about optimizing here
+ while(1)
+ {
+ if (!eina_list_data_find_list(transit->objs, obj))
+ break;
+ transit->objs = eina_list_remove(transit->objs, obj);
+ evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL,
+ _transit_obj_remove_cb,
+ transit);
+ }
+}
- EINA_LIST_FOREACH(transit->effect_list, elist, effect)
- {
- if (effect->begin_op)
- effect->begin_op(effect->user_data, auto_reverse, repeat_cnt);
- }
+static void
+_transit_obj_remove_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Elm_Transit *transit = data;
+ Elm_Transit_Obj_Data *obj_data = evas_object_data_get(obj, _transit_key);
+ if (obj_data)
+ {
+ if (obj_data->state)
+ free(obj_data->state);
+ free(obj_data);
+ }
+ _remove_obj_from_list(transit, obj);
+ if (!transit->objs) elm_transit_del(transit);
}
static void
-_transit_fx_end(Elm_Transit *transit)
+_transit_obj_data_recover(Elm_Transit *transit, Evas_Object *obj)
{
- Eina_List *elist;
+ Elm_Transit_Obj_Data *obj_data;
+ Elm_Transit_Obj_State *state;
- Elm_Effect *effect;
+ obj_data = evas_object_data_get(obj, _transit_key);
+ if (!obj_data) return;
+ evas_object_data_del(obj, _transit_key);
+ evas_object_freeze_events_set(obj, obj_data->freeze_events);
+ state = obj_data->state;
+ if (state)
+ {
+ //recover the states of the object.
+ if (!transit->state_keep)
+ {
+ evas_object_move(obj, state->x, state->y);
+ evas_object_resize(obj, state->w, state->h);
+ evas_object_color_set(obj, state->r, state->g, state->b, state->a);
+ if (state->visible) evas_object_show(obj);
+ else evas_object_hide(obj);
+ if (state->map_enabled)
+ evas_object_map_enable_set(obj, EINA_TRUE);
+ else
+ evas_object_map_enable_set(obj, EINA_FALSE);
+ if (state->map)
+ evas_object_map_set(obj, state->map);
+ }
+ free(state);
+ }
+ free(obj_data);
+}
- Eina_Bool auto_reverse;
+static void
+_transit_obj_remove(Elm_Transit *transit, Evas_Object *obj)
+{
+ _remove_obj_from_list(transit, obj);
+ _transit_obj_data_recover(transit, obj);
+}
- unsigned int repeat_cnt;
+static void
+_transit_effect_del(Elm_Transit *transit, Elm_Transit_Effect_Module *effect_module)
+{
+ if (effect_module->end_cb)
+ effect_module->end_cb(effect_module->effect, transit);
+ free(effect_module);
+}
- auto_reverse = elm_animator_auto_reverse_get(transit->animator);
- repeat_cnt = elm_animator_repeat_get(transit->animator);
+static void
+_transit_remove_dead_effects(Elm_Transit *transit)
+{
+ Elm_Transit_Effect_Module *effect_module;
- EINA_LIST_FOREACH(transit->effect_list, elist, effect)
- {
- if (effect->end_op)
- effect->end_op(effect->user_data, auto_reverse, repeat_cnt);
- }
+ EINA_INLIST_FOREACH(transit->effect_list, effect_module)
+ {
+ if (effect_module->deleted)
+ {
+ _transit_effect_del(transit, effect_module);
+ transit->effects_pending_del--;
+ if (!transit->effects_pending_del) return;
+ }
+ }
}
static void
-_transit_complete_cb(void *data)
+_transit_chain_go(Elm_Transit *transit)
{
- Elm_Transit *transit = (Elm_Transit *) data;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ elm_transit_go(transit);
+ _transit_animate_cb(transit);
+}
- evas_render(evas_object_evas_get(transit->parent));
+static void
+_transit_del(Elm_Transit *transit)
+{
+ Elm_Transit_Effect_Module *effect_module;
+ Elm_Transit *chain_transit;
+ Eina_List *elist, *elist_next;
- _transit_fx_end(transit);
+ if (transit->animator)
+ ecore_animator_del(transit->animator);
- if (transit->block_rect)
- evas_object_hide(transit->block_rect);
+ //remove effects
+ while (transit->effect_list)
+ {
+ effect_module = EINA_INLIST_CONTAINER_GET(transit->effect_list, Elm_Transit_Effect_Module);
+ transit->effect_list = eina_inlist_remove(transit->effect_list, transit->effect_list);
+ _transit_effect_del(transit, effect_module);
+ }
+
+ //remove objects.
+ while (transit->objs)
+ _transit_obj_remove(transit, eina_list_data_get(transit->objs));
+
+ transit->deleted = EINA_TRUE;
+
+ if (transit->del_data.func)
+ transit->del_data.func(transit->del_data.arg, transit);
- if (transit->completion_op)
- transit->completion_op(transit->completion_arg, transit);
+ //cut off the chain transit relationship
+ EINA_LIST_FOREACH_SAFE(transit->next_chain_transits, elist, elist_next, chain_transit)
+ chain_transit->prev_chain_transit = NULL;
- if (transit->reserved_del)
+ if (transit->prev_chain_transit)
+ transit->prev_chain_transit->next_chain_transits =
+ eina_list_remove(transit->prev_chain_transit->next_chain_transits, transit);
+
+ // run chain transits
+ if (transit->finished && transit->next_chain_transits)
{
- transit->reserved_del = EINA_FALSE;
- elm_transit_del(transit);
+ EINA_LIST_FOREACH_SAFE(transit->next_chain_transits, elist, elist_next, chain_transit)
+ _transit_chain_go(chain_transit);
+
}
+
+ eina_list_free(transit->next_chain_transits);
+
+ EINA_MAGIC_SET(transit, EINA_MAGIC_NONE);
+ free(transit);
}
-static void
-_transit_fx_del(Elm_Effect *effect)
+//If the transit is deleted then EINA_FALSE is retruned.
+static Eina_Bool
+_transit_animate_op(Elm_Transit *transit, double progress)
{
- if (!effect)
- return;
+ Elm_Transit_Effect_Module *effect_module;
- --effect->shared_cnt;
+ transit->walking++;
+ EINA_INLIST_FOREACH(transit->effect_list, effect_module)
+ {
+ if (transit->deleted) break;
+ if (!effect_module->deleted)
+ effect_module->transition_cb(effect_module->effect, transit, progress);
+ }
+ transit->walking--;
- if (effect->shared_cnt > 0)
- return;
+ if (transit->walking) return EINA_TRUE;
- if(effect->del_op)
- (*effect->del_op)(effect->user_data);
+ if (transit->deleted)
+ {
+ _transit_del(transit);
+ return EINA_FALSE;
+ }
- if (effect->user_data)
- free(effect->user_data);
- free(effect);
+ else if (transit->effects_pending_del) _transit_remove_dead_effects(transit);
+
+ return EINA_TRUE;
}
-/**
- * Set the event blocked when transit is operating.
- *
- * @param[in] transit Transit object
- * @param[in] disabled Disable or enable
- *
- * @ingroup Transit
- */
-EAPI void
-elm_transit_event_block_disabled_set(Elm_Transit *transit, Eina_Bool disabled)
+static Eina_Bool
+_transit_animate_cb(void *data)
{
- if (!transit)
- return;
+ Elm_Transit *transit = data;
+ double elapsed_time, duration;
+
+ transit->time.current = ecore_loop_time_get();
+ elapsed_time = transit->time.current - transit->time.begin;
+ duration = transit->time.duration + transit->time.delayed;
+
+ if (elapsed_time > duration)
+ elapsed_time = duration;
- if (disabled)
+ transit->progress = elapsed_time / duration;
+ switch (transit->tween_mode)
{
- if (transit->block_rect)
- {
- evas_object_del(transit->block_rect);
- transit->block_rect = NULL;
- }
+ case ELM_TRANSIT_TWEEN_MODE_LINEAR:
+ transit->progress = ecore_animator_pos_map(transit->progress,
+ ECORE_POS_MAP_LINEAR,
+ 0, 0);
+ case ELM_TRANSIT_TWEEN_MODE_ACCELERATE:
+ transit->progress = ecore_animator_pos_map(transit->progress,
+ ECORE_POS_MAP_ACCELERATE,
+ 0, 0);
+ break;
+ case ELM_TRANSIT_TWEEN_MODE_DECELERATE:
+ transit->progress = ecore_animator_pos_map(transit->progress,
+ ECORE_POS_MAP_DECELERATE,
+ 0, 0);
+ break;
+ case ELM_TRANSIT_TWEEN_MODE_SINUSOIDAL:
+ transit->progress = ecore_animator_pos_map(transit->progress,
+ ECORE_POS_MAP_SINUSOIDAL,
+ 0, 0);
+ break;
+ default:
+ break;
}
- else
+
+ /* Reverse? */
+ if (transit->repeat.reverse) transit->progress = 1 - transit->progress;
+
+ if (transit->time.duration > 0)
+ {
+ if (!_transit_animate_op(transit, transit->progress))
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ /* Not end. Keep going. */
+ if (elapsed_time < duration) return ECORE_CALLBACK_RENEW;
+
+ /* Repeat and reverse and time done! */
+ if ((transit->repeat.count >= 0) &&
+ (transit->repeat.current == transit->repeat.count) &&
+ ((!transit->auto_reverse) || transit->repeat.reverse))
+ {
+ transit->finished = EINA_TRUE;
+ elm_transit_del(transit);
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ /* Repeat Case */
+ if (!transit->auto_reverse || transit->repeat.reverse)
{
- if (!transit->block_rect)
- transit->block_rect = _create_block_rect(transit->parent);
+ transit->repeat.current++;
+ transit->repeat.reverse = EINA_FALSE;
}
+ else transit->repeat.reverse = EINA_TRUE;
+
+ transit->time.begin = ecore_loop_time_get();
+
+ return ECORE_CALLBACK_RENEW;
}
-/**
- * Get the value of event blockd status.
- *
- * @param[in] transit Transit
- * @return EINA_TRUE, when event block is disabled
- *
- * @ingroup Transit
- */
-EAPI Eina_Bool
-elm_transit_event_block_disabled_get(Elm_Transit *transit)
+EAPI Elm_Transit *
+elm_transit_add(void)
{
+ Elm_Transit *transit = ELM_NEW(Elm_Transit);
if (!transit)
- return EINA_FALSE;
- return transit->block_rect ? EINA_TRUE : EINA_FALSE;
-}
-
-/**
- * Remove effect from transit.
- *
- * @param[in] transit Transit
- * @param[in] effect Effect to be removed
- * @return EINA_TRUE, if the effect is removed
- * @warning If removed effect does not inserted in any transit, it will be deleted.
- *
- * @ingroup Transit
- */
-EAPI Eina_Bool
-elm_transit_fx_remove(Elm_Transit *transit, Elm_Effect *effect)
-{
- Eina_List *elist;
+ {
+ ERR("Failed to allocate a elm_transit object!");
+ return NULL;
+ }
- Elm_Effect *_effect;
+ EINA_MAGIC_SET(transit, ELM_TRANSIT_MAGIC);
+
+ elm_transit_tween_mode_set(transit, ELM_TRANSIT_TWEEN_MODE_LINEAR);
+
+ return transit;
+}
- if (!transit)
- return EINA_FALSE;
-
- EINA_LIST_FOREACH(transit->effect_list, elist, _effect)
- {
- if (_effect == effect)
- {
- transit->effect_list =
- eina_list_remove(transit->effect_list, _effect);
- _transit_fx_del(_effect);
- return EINA_TRUE;
- }
- }
- return EINA_FALSE;
-}
-
-/**
- * Remove all current inserted effects.
- *
- * @param[in] transit Transit
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_fx_clear(Elm_Transit *transit)
+elm_transit_del(Elm_Transit *transit)
{
- Eina_List *elist;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
- Elm_Effect *effect;
+ if (transit->walking) transit->deleted = EINA_TRUE;
+ else _transit_del(transit);
+}
- if (!transit)
- return;
-
- EINA_LIST_FOREACH(transit->effect_list, elist, effect)
- {
- transit->effect_list = eina_list_remove(transit->effect_list, effect);
- _transit_fx_del(effect);
- }
-}
-
-/**
- * Get the list of current inseted effects.
- *
- * @param[in] transit Transit
- * @return Effect list
- *
- * @ingroup Transit
- */
-EAPI const Eina_List *
-elm_transit_fx_get(Elm_Transit *transit)
-{
- if (!transit)
- return NULL;
- return transit->effect_list;
-}
-
-/**
- * Set the user-callback function when the transit operation is done.
- *
- * @param[in] transit Transit
- * @param[in] op Callback function pointer
- * @param[in] data Callback funtion user data
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_completion_callback_set(Elm_Transit *transit,
- void (*op) (void *data,
- Elm_Transit *transit),
- void *data)
+elm_transit_effect_add(Elm_Transit *transit, Elm_Transit_Effect_Transition_Cb transition_cb, Elm_Transit_Effect *effect, Elm_Transit_Effect_End_Cb end_cb)
{
- if (!transit)
- return;
- transit->completion_op = op;
- transit->completion_arg = data;
-}
-
-/**
- * Delete transit.
- *
- * @param[in] transit Transit to be deleted
- *
- * @ingroup Transit
- */
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ EINA_SAFETY_ON_NULL_RETURN(transition_cb);
+ Elm_Transit_Effect_Module *effect_module;
+
+ EINA_INLIST_FOREACH(transit->effect_list, effect_module)
+ if ((effect_module->transition_cb == transition_cb) && (effect_module->effect == effect))
+ {
+ WRN("elm_transit does not allow to add the duplicated effect! : transit=%p", transit);
+ return;
+ }
+
+ effect_module = ELM_NEW(Elm_Transit_Effect_Module);
+ if (!effect_module)
+ {
+ ERR("Failed to allocate a new effect!: transit=%p", transit);
+ return;
+ }
+
+ effect_module->end_cb = end_cb;
+ effect_module->transition_cb = transition_cb;
+ effect_module->effect = effect;
+
+ transit->effect_list = eina_inlist_append(transit->effect_list, (Eina_Inlist*) effect_module);
+}
+
EAPI void
-elm_transit_del(Elm_Transit *transit)
+elm_transit_effect_del(Elm_Transit *transit, Elm_Transit_Effect_Transition_Cb transition_cb, Elm_Transit_Effect *effect)
{
- if (!transit)
- return;
- if (elm_animator_operating_get(transit->animator))
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ EINA_SAFETY_ON_NULL_RETURN(transition_cb);
+ Elm_Transit_Effect_Module *effect_module;
+
+ EINA_INLIST_FOREACH(transit->effect_list, effect_module)
{
- transit->reserved_del = EINA_TRUE;
- return;
+ if ((effect_module->transition_cb == transition_cb) && (effect_module->effect == effect))
+ {
+ if (transit->walking)
+ {
+ effect_module->deleted = EINA_TRUE;
+ transit->effects_pending_del++;
+ }
+ else
+ {
+ _transit_effect_del(transit, effect_module);
+ if (!transit->effect_list) elm_transit_del(transit);
+ }
+ return;
+ }
}
+}
- if (transit->block_rect)
- evas_object_del(transit->block_rect);
+EAPI void
+elm_transit_object_add(Elm_Transit *transit, Evas_Object *obj)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ EINA_SAFETY_ON_NULL_RETURN(obj);
- elm_animator_del(transit->animator);
- elm_transit_fx_clear(transit);
+ if (transit->animator)
+ {
+ if (!evas_object_data_get(obj, _transit_key))
+ {
+ _transit_obj_data_update(transit, obj);
+ evas_object_freeze_events_set(obj, EINA_TRUE);
+ }
+ }
-// if(transit->parent)
-// {
-// evas_object_event_callback_del(transit->parent, EVAS_CALLBACK_DEL, _transit_parent_del);
-// }
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+ _transit_obj_remove_cb,
+ transit);
- free(transit);
+ transit->objs = eina_list_append(transit->objs, obj);
}
-/**
- * Set the transit animation acceleration style.
- *
- * @param transit Transit
- * @param cs Curve style(Please refer elm_animator_curve_style_set)
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_curve_style_set(Elm_Transit *transit, Elm_Animator_Curve_Style cs)
+elm_transit_object_remove(Elm_Transit *transit, Evas_Object *obj)
{
- if (!transit)
- return;
- elm_animator_curve_style_set(transit->animator, cs);
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ EINA_SAFETY_ON_NULL_RETURN(obj);
+
+ _transit_obj_remove(transit, obj);
+ if (!transit->objs) elm_transit_del(transit);
}
+EAPI const Eina_List *
+elm_transit_objects_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ return transit->objs;
+}
-/**
- * Add new transit.
- *
- * @param[in] parent Parent object
- * @return transit
- *
- * @ingroup Transit
- */
-EAPI Elm_Transit *
-elm_transit_add(Evas_Object *parent)
+EAPI void
+elm_transit_event_enabled_set(Elm_Transit *transit, Eina_Bool enabled)
{
- Elm_Transit *transit = calloc(1, sizeof(Elm_Transit));
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
- if (!transit)
- return NULL;
+ Eina_List *list;
+ Evas_Object *obj;
- transit->animator = elm_animator_add(parent);
+ if (transit->event_enabled == enabled) return;
+ transit->event_enabled = !!enabled;
+ if (!transit->animator) return;
- if (!transit->animator)
- {
- free(transit);
- return NULL;
- }
+ EINA_LIST_FOREACH(transit->objs, list, obj)
+ evas_object_freeze_events_set(obj, enabled);
+}
- transit->parent = parent;
- elm_animator_operation_callback_set(transit->animator, _transit_animate_cb,
- transit);
- elm_animator_completion_callback_set(transit->animator, _transit_complete_cb,
- transit);
- elm_transit_event_block_disabled_set(transit, EINA_FALSE);
-/*
- if(parent)
- {
- evas_object_event_callback_add(parent, EVAS_CALLBACK_DEL, _transit_parent_del,
- transit);
- }
-*/
- return transit;
+EAPI Eina_Bool
+elm_transit_event_enabled_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
+ return transit->event_enabled;
+}
+
+EAPI void
+elm_transit_del_cb_set(Elm_Transit *transit, void (*cb) (void *data, Elm_Transit *transit), void *data)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ transit->del_data.func = cb;
+ transit->del_data.arg = data;
}
-/**
- * Set reverse effect automatically.
- *
- * @param[in] transit Transit
- * @param[in] reverse EINA_TRUE is reverse.
- *
- * @ingroup Transit
- */
EAPI void
elm_transit_auto_reverse_set(Elm_Transit *transit, Eina_Bool reverse)
{
- if (!transit)
- return;
- elm_animator_auto_reverse_set(transit->animator, reverse);
-}
-
-/**
- * Insert an effect into the transit.
- *
- * @param[in] transit Transit
- * @param[in] effect Effect to be inserted
- * @return EINA_TRUE is success
- *
- * @ingroup Transit
- */
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ transit->auto_reverse = reverse;
+}
+
EAPI Eina_Bool
-elm_transit_fx_insert(Elm_Transit *transit, Elm_Effect *effect)
+elm_transit_auto_reverse_get(const Elm_Transit *transit)
{
- Eina_List *elist;
-
- Elm_Effect *_effect;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
+ return transit->auto_reverse;
+}
- if (!transit)
- return EINA_FALSE;
+EAPI void
+elm_transit_repeat_times_set(Elm_Transit *transit, int repeat)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ transit->repeat.count = repeat;
+ transit->repeat.current = 0;
+}
- EINA_LIST_FOREACH(transit->effect_list, elist, _effect)
- {
- if (_effect == effect)
- return EINA_FALSE;
- }
+EAPI int
+elm_transit_repeat_times_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, 0);
+ return transit->repeat.count;
+}
- ++effect->shared_cnt;
- transit->effect_list = eina_list_append(transit->effect_list, effect);
+EAPI void
+elm_transit_tween_mode_set(Elm_Transit *transit, Elm_Transit_Tween_Mode tween_mode)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ transit->tween_mode = tween_mode;
+}
- return EINA_TRUE;
+EAPI Elm_Transit_Tween_Mode
+elm_transit_tween_mode_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, ELM_TRANSIT_TWEEN_MODE_LINEAR);
+ return transit->tween_mode;
}
-/**
- * Set the transit repeat count. Effect will be repeated by repeat count.
- *
- * @param[in] transit Transit
- * @param[in] repeat Repeat count
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_repeat_set(Elm_Transit *transit, unsigned int repeat)
+elm_transit_duration_set(Elm_Transit *transit, double duration)
{
- if (!transit)
- return;
- elm_animator_repeat_set(transit->animator, repeat);
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ if (transit->animator)
+ {
+ WRN("elm_transit does not allow to set the duration time in operating! : transit=%p", transit);
+ return;
+ }
+ transit->time.duration = duration;
}
-/**
- * Stop the current transit, if the transit is operating.
- *
- * @param[in] transit Transit
- *
- * @ingroup Transit
- */
-EAPI void
-elm_transit_stop(Elm_Transit *transit)
+EAPI double
+elm_transit_duration_get(const Elm_Transit *transit)
{
- if (!transit)
- return;
- elm_animator_stop(transit->animator);
-}
-
-/**
- * Run the all the inserted effects.
- *
- * @param[in] transit Transit
- * @param[in] duration Transit time in seconds
- *
- * @ingroup Transit
- */
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, 0.0);
+ return transit->time.duration;
+}
+
EAPI void
-elm_transit_run(Elm_Transit *transit, double duration)
+elm_transit_go(Elm_Transit *transit)
{
- if (!transit)
- return;
- _transit_fx_begin(transit);
- elm_animator_duration_set(transit->animator, duration);
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
- //Block to Top
- if (transit->block_rect)
- evas_object_show(transit->block_rect);
+ Eina_List *elist;
+ Evas_Object *obj;
+
+ if (transit->animator)
+ ecore_animator_del(transit->animator);
- elm_animator_animate(transit->animator);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ _transit_obj_data_update(transit, obj);
- //If failed to animate.
- if (!elm_animator_operating_get(transit->animator))
+ if (!transit->event_enabled)
{
- if (transit->block_rect)
- evas_object_hide(transit->block_rect);
- _transit_fx_end(transit);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ evas_object_freeze_events_set(obj, EINA_TRUE);
}
+
+ transit->time.paused = 0;
+ transit->time.delayed = 0;
+ transit->time.begin = ecore_loop_time_get();
+ transit->animator = ecore_animator_add(_transit_animate_cb, transit);
}
-/**
- * Pause the transit
- *
- * @param[in] transit Transit
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_pause(Elm_Transit *transit)
+elm_transit_paused_set(Elm_Transit *transit, Eina_Bool paused)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+
+ if (!transit->animator) return;
+
+ if (paused)
+ {
+ if (transit->time.paused > 0)
+ return;
+ ecore_animator_freeze(transit->animator);
+ transit->time.paused = ecore_loop_time_get();
+ }
+ else
+ {
+ if (transit->time.paused == 0)
+ return;
+ ecore_animator_thaw(transit->animator);
+ transit->time.delayed += (ecore_loop_time_get() - transit->time.paused);
+ transit->time.paused = 0;
+ }
+}
+
+EAPI Eina_Bool
+elm_transit_paused_get(const Elm_Transit *transit)
{
- if(!transit)
- return;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
- elm_animator_pause(transit->animator);
+ if (transit->time.paused == 0)
+ return EINA_FALSE;
+
+ return EINA_TRUE;
+}
+
+EAPI double
+elm_transit_progress_value_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, 0);
+
+ return transit->progress;
}
-/**
- * Resume the transit
- *
- * @param[in] transit Transit
- *
- * @ingroup Transit
- */
EAPI void
-elm_transit_resume(Elm_Transit *transit)
+elm_transit_objects_final_state_keep_set(Elm_Transit *transit, Eina_Bool state_keep)
{
- if(!transit)
- return;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
- elm_animator_resume(transit->animator);
+ if (transit->state_keep == state_keep) return;
+ if (transit->animator)
+ {
+ WRN("elm_transit does not allow to change final state keep mode in operating! : transit=%p", transit);
+ return;
+ }
+ transit->state_keep = !!state_keep;
}
+EAPI Eina_Bool
+elm_transit_objects_final_state_keep_get(const Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, EINA_FALSE);
+ return transit->state_keep;
+}
+
+EAPI void
+elm_transit_chain_transit_add(Elm_Transit *transit, Elm_Transit *chain_transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ ELM_TRANSIT_CHECK_OR_RETURN(chain_transit);
+ if (transit == chain_transit)
+ {
+ WRN("You add a same transit as a chain transit! : transit=%p, chain_transit=%p", transit, chain_transit);
+ return;
+ }
+ if (transit == chain_transit->prev_chain_transit)
+ return;
-/////////////////////////////////////////////////////////////////////////////////////
-//Resizing FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _resizing Elm_Fx_Resizing;
-static void _elm_fx_resizing_op(void *data, Elm_Animator *animator,
- double frame);
-static void _elm_fx_resizing_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
+ if (chain_transit->prev_chain_transit)
+ chain_transit->prev_chain_transit->next_chain_transits = eina_list_remove(chain_transit->prev_chain_transit->next_chain_transits, chain_transit);
-struct _resizing
+ chain_transit->prev_chain_transit = transit;
+ transit->next_chain_transits = eina_list_append(transit->next_chain_transits, chain_transit);
+}
+
+EAPI void
+elm_transit_chain_transit_del(Elm_Transit *transit, Elm_Transit *chain_transit)
{
- Evas_Object *obj;
- struct _size
- {
+ ELM_TRANSIT_CHECK_OR_RETURN(transit);
+ ELM_TRANSIT_CHECK_OR_RETURN(chain_transit);
+
+ if (chain_transit->prev_chain_transit != transit)
+ {
+ WRN("A pair of transits does not have the chain relationship! : transit=%p, chain_transit=%p", transit, chain_transit);
+ return;
+ }
+
+ chain_transit->prev_chain_transit = NULL;
+ transit->next_chain_transits = eina_list_remove(transit->next_chain_transits, chain_transit);
+}
+
+EAPI Eina_List *
+elm_transit_chain_transits_get(const Elm_Transit * transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ return transit->next_chain_transits;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//Resizing Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Resizing Elm_Transit_Effect_Resizing;
+
+struct _Elm_Transit_Effect_Resizing
+{
+ struct _size {
Evas_Coord w, h;
} from, to;
};
static void
-_elm_fx_resizing_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+_transit_effect_resizing_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Resizing *resizing = data;
-
- evas_object_show(resizing->obj);
- evas_object_resize(resizing->obj, resizing->from.w, resizing->from.h);
+ Elm_Transit_Effect_Resizing *resizing = effect;
+ free(resizing);
}
static void
-_elm_fx_resizing_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_resizing_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
Evas_Coord w, h;
+ Evas_Object *obj;
+ Eina_List *elist;
+ Elm_Transit_Effect_Resizing *resizing = effect;
- Elm_Fx_Resizing *resizing = data;
+ w = resizing->from.w + (resizing->to.w * progress);
+ h = resizing->from.h + (resizing->to.h * progress);
- w = resizing->from.w + (Evas_Coord) ((float)resizing->to.h * (float)frame);
- h = resizing->from.h + (Evas_Coord) ((float)resizing->to.w * (float)frame);
- evas_object_resize(resizing->obj, w, h);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ evas_object_resize(obj, w, h);
}
-/**
- * Add Resizing effect.
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from_w Object width size when effect begins
- * @param[in] from_h Object height size when effect begins
- * @param[in] to_w Object width size when effect ends
- * @param[in] to_h Object height size when effect ends
- * @return Resizing effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_resizing_add(Evas_Object *obj, Evas_Coord from_w, Evas_Coord from_h,
- Evas_Coord to_w, Evas_Coord to_h)
+static Elm_Transit_Effect *
+_transit_effect_resizing_context_new(Evas_Coord from_w, Evas_Coord from_h, Evas_Coord to_w, Evas_Coord to_h)
{
- Elm_Effect *effect;
-
- Elm_Fx_Resizing *resizing;
-
- if (!obj)
- return NULL;
-
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ Elm_Transit_Effect_Resizing *resizing;
- resizing = calloc(1, sizeof(Elm_Fx_Resizing));
- if (!resizing)
- {
- free(effect);
- return NULL;
- }
+ resizing = ELM_NEW(Elm_Transit_Effect_Resizing);
+ if (!resizing) return NULL;
- resizing->obj = obj;
resizing->from.w = from_w;
resizing->from.h = from_h;
resizing->to.w = to_w - from_w;
resizing->to.h = to_h - from_h;
- effect->begin_op = _elm_fx_resizing_begin;
- effect->animation_op = _elm_fx_resizing_op;
- effect->user_data = resizing;
+ return resizing;
+}
+EAPI Elm_Transit_Effect *
+elm_transit_effect_resizing_add(Elm_Transit *transit, Evas_Coord from_w, Evas_Coord from_h, Evas_Coord to_w, Evas_Coord to_h)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_resizing_context_new(from_w, from_h, to_w, to_h);
+
+ if (!effect)
+ {
+ ERR("Failed to allocate resizing effect! : transit=%p", transit);
+ return NULL;
+ }
+ elm_transit_effect_add(transit,
+ _transit_effect_resizing_op, effect,
+ _transit_effect_resizing_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Translation FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _translation Elm_Fx_Translation;
-static void _elm_fx_translation_op(void *data, Elm_Animator *animator,
- double frame);
-static void _elm_fx_translation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_translation_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
+///////////////////////////////////////////////////////////////////////////
+//Translation Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Translation Elm_Transit_Effect_Translation;
+typedef struct _Elm_Transit_Effect_Translation_Node Elm_Transit_Effect_Translation_Node;
-struct _translation
+struct _Elm_Transit_Effect_Translation_Node
{
Evas_Object *obj;
- struct _point
- {
- Evas_Coord x, y;
+ Evas_Coord x, y;
+};
+
+struct _Elm_Transit_Effect_Translation
+{
+ struct _position_variation {
+ Evas_Coord dx, dy;
} from, to;
+ Eina_List *nodes;
};
static void
-_elm_fx_translation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+_translation_object_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Elm_Fx_Translation *translation = data;
+ Elm_Transit_Effect_Translation *translation = data;
+ Eina_List *elist;
+ Elm_Transit_Effect_Translation_Node *translation_node;
- evas_object_show(translation->obj);
- evas_object_move(translation->obj, translation->from.x, translation->from.y);
+ EINA_LIST_FOREACH(translation->nodes, elist, translation_node)
+ {
+ if (translation_node->obj != obj) continue;
+ translation->nodes = eina_list_remove_list(translation->nodes, elist);
+ free(translation_node);
+ break;
+ }
}
-static void
-_elm_fx_translation_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+static Eina_List *
+_translation_nodes_build(Elm_Transit *transit, Elm_Transit_Effect_Translation *translation)
{
- Elm_Fx_Translation *translation = data;
+ Elm_Transit_Effect_Translation_Node *translation_node;
+ const Eina_List *elist;
+ Evas_Object *obj;
+ Eina_List *data_list = NULL;
+ const Eina_List *objs = elm_transit_objects_get(transit);
- evas_object_move(translation->obj, translation->from.x + translation->to.x,
- translation->from.y + translation->to.y);
+ EINA_LIST_FOREACH(objs, elist, obj)
+ {
+ translation_node = ELM_NEW(Elm_Transit_Effect_Translation_Node);
+ if (!translation_node)
+ {
+ eina_list_free(data_list);
+ return NULL;
+ }
+ translation_node->obj = obj;
+ evas_object_geometry_get(obj, &(translation_node->x),
+ &(translation_node->y), NULL, NULL);
+ data_list = eina_list_append(data_list, translation_node);
+ evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
+ _translation_object_del_cb, translation);
+ }
+ return data_list;
}
-static void
-_elm_fx_translation_op(void *data, Elm_Animator *animator, double frame)
+void
+_transit_effect_translation_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Elm_Transit_Effect_Translation *translation = effect;
+ Eina_List *elist, *elist_next;
+ Elm_Transit_Effect_Translation_Node *translation_node;
+
+ EINA_LIST_FOREACH_SAFE(translation->nodes,
+ elist, elist_next, translation_node)
+ {
+ evas_object_event_callback_del(translation_node->obj,
+ EVAS_CALLBACK_DEL, _translation_object_del_cb);
+ translation->nodes = eina_list_remove_list(translation->nodes, elist);
+ free(translation_node);
+ }
+ free(translation);
+}
+
+void
+_transit_effect_translation_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress __UNUSED__)
+{
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
Evas_Coord x, y;
+ Elm_Transit_Effect_Translation *translation = effect;
+ Elm_Transit_Effect_Translation_Node *translation_node;
+ Eina_List *elist;
- Elm_Fx_Translation *translation = data;
+ if (!translation->nodes)
+ translation->nodes = _translation_nodes_build(transit, translation);
- x = translation->from.x +
- (Evas_Coord) ((float)translation->to.x * (float)frame);
- y = translation->from.y +
- (Evas_Coord) ((float)translation->to.y * (float)frame);
- evas_object_move(translation->obj, x, y);
+ EINA_LIST_FOREACH(translation->nodes, elist, translation_node)
+ {
+ x = translation_node->x + translation->from.dx
+ + (translation->to.dx * progress);
+ y = translation_node->y + translation->from.dy
+ + (translation->to.dy * progress);
+ evas_object_move(translation_node->obj, x, y);
+ }
}
-/**
- * Add Translation effect.
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from_x Position X when effect begins
- * @param[in] from_y Position Y when effect begins
- * @param[in] to_x Position X when effect ends
- * @param[in] to_y Position Y when effect ends
- * @return Translation effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_translation_add(Evas_Object *obj, Evas_Coord from_x, Evas_Coord from_y,
- Evas_Coord to_x, Evas_Coord to_y)
+static Elm_Transit_Effect *
+_transit_effect_translation_context_new(Evas_Coord from_dx, Evas_Coord from_dy, Evas_Coord to_dx, Evas_Coord to_dy)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Translation *translation;
- Elm_Fx_Translation *translation;
+ translation = ELM_NEW(Elm_Transit_Effect_Translation);
+ if (!translation) return NULL;
- if (!obj)
- return NULL;
+ translation->from.dx = from_dx;
+ translation->from.dy = from_dy;
+ translation->to.dx = to_dx - from_dx;
+ translation->to.dy = to_dy - from_dy;
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ return translation;
+}
- translation = calloc(1, sizeof(Elm_Fx_Translation));
+EAPI Elm_Transit_Effect *
+elm_transit_effect_translation_add(Elm_Transit *transit, Evas_Coord from_dx, Evas_Coord from_dy, Evas_Coord to_dx, Evas_Coord to_dy)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_translation_context_new(from_dx, from_dy, to_dx, to_dy);
- if (!translation)
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate translation effect! : transit=%p", transit);
+ return NULL;
}
-
- translation->obj = obj;
- translation->from.x = from_x;
- translation->from.y = from_y;
- translation->to.x = to_x - from_x;
- translation->to.y = to_y - from_y;
-
- effect->begin_op = _elm_fx_translation_begin;
- effect->end_op = _elm_fx_translation_end;
- effect->animation_op = _elm_fx_translation_op;
- effect->user_data = translation;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_translation_op, effect,
+ _transit_effect_translation_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Zoom FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _zoom Elm_Fx_Zoom;
-static void _elm_fx_zoom_op(void *data, Elm_Animator * animator,
- double frame);
-static void _elm_fx_zoom_begin(void *data, Eina_Bool reverse,
- unsigned int repeat);
-static void _elm_fx_zoom_end(void *data, Eina_Bool reverse,
- unsigned int repeat);
+///////////////////////////////////////////////////////////////////////////
+//Zoom Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Zoom Elm_Transit_Effect_Zoom;
-struct _zoom
+struct _Elm_Transit_Effect_Zoom
{
- Evas_Object *obj;
float from, to;
};
-static void
-_elm_fx_zoom_begin(void *data, Eina_Bool reverse, unsigned int repeat)
+void
+_transit_effect_zoom_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Zoom *zoom = data;
-
- evas_object_show(zoom->obj);
- _elm_fx_zoom_op(data, NULL, 0);
+ Elm_Transit_Effect_Zoom *zoom = effect;
+ free(zoom);
}
static void
-_elm_fx_zoom_end(void *data, Eina_Bool reverse, unsigned int repeat)
+_transit_effect_zoom_op(Elm_Transit_Effect *effect, Elm_Transit *transit , double progress)
{
- Elm_Fx_Zoom *zoom = data;
-
- evas_object_map_enable_set(zoom->obj, EINA_FALSE);
-}
-
-static void
-_elm_fx_zoom_op(void *data, Elm_Animator *animator, double frame)
-{
- Elm_Fx_Zoom *zoom;
-
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Evas_Object *obj;
+ Eina_List *elist;
+ Elm_Transit_Effect_Zoom *zoom = effect;
Evas_Map *map;
-
Evas_Coord x, y, w, h;
map = evas_map_new(4);
- if (!map)
- return;
-
- zoom = data;
- evas_object_geometry_get(zoom->obj, &x, &y, &w, &h);
- evas_map_smooth_set(map, EINA_TRUE);
- evas_map_util_points_populate_from_object_full(map, zoom->obj,
- zoom->from +
- (frame * zoom->to));
- evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
- evas_object_map_set(zoom->obj, map);
- evas_object_map_enable_set(zoom->obj, EINA_TRUE);
+ if (!map) return;
+
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ {
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
+ evas_map_util_points_populate_from_object_full(map, obj, zoom->from +
+ (progress * zoom->to));
+ evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, _TRANSIT_FOCAL);
+ evas_object_map_set(obj, map);
+ evas_object_map_enable_set(obj, EINA_TRUE);
+ }
evas_map_free(map);
}
-/**
- * Add Zoom effect.
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from_rate Scale rate when effect begins (1 is current rate)
- * @param[in] to_rate Scale rate when effect ends
- * @return Zoom effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_zoom_add(Evas_Object *obj, float from_rate, float to_rate)
+static Elm_Transit_Effect *
+_transit_effect_zoom_context_new(float from_rate, float to_rate)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Zoom *zoom;
- Elm_Fx_Zoom *zoom;
+ zoom = ELM_NEW(Elm_Transit_Effect_Zoom);
+ if (!zoom) return NULL;
- if (!obj)
- return NULL;
+ zoom->from = (_TRANSIT_FOCAL - (from_rate * _TRANSIT_FOCAL)) * (1 / from_rate);
+ zoom->to = ((_TRANSIT_FOCAL - (to_rate * _TRANSIT_FOCAL)) * (1 / to_rate)) - zoom->from;
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ return zoom;
+}
- zoom = calloc(1, sizeof(Elm_Fx_Zoom));
- if (!zoom)
+EAPI Elm_Transit_Effect *
+elm_transit_effect_zoom_add(Elm_Transit *transit, float from_rate, float to_rate)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_zoom_context_new(from_rate, to_rate);
+
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate zoom effect! : transit=%p", transit);
+ return NULL;
}
-
- zoom->obj = obj;
- zoom->from = (10000 - (from_rate * 10000)) * (1 / from_rate);
- zoom->to = ((10000 - (to_rate * 10000)) * (1 / to_rate)) - zoom->from;
- effect->begin_op = _elm_fx_zoom_begin;
- effect->end_op = _elm_fx_zoom_end;
- effect->animation_op = _elm_fx_zoom_op;
- effect->user_data = zoom;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_zoom_op, effect,
+ _transit_effect_zoom_context_free);
return effect;
-
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Flip FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _flip Elm_Fx_Flip;
-static void _elm_fx_flip_op(void *data, Elm_Animator *animator,
- double frame);
-static void _elm_fx_flip_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
+///////////////////////////////////////////////////////////////////////////
+//Flip Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Flip Elm_Transit_Effect_Flip;
-struct _flip
+struct _Elm_Transit_Effect_Flip
{
- Evas_Object *front;
- Evas_Object *back;
- Elm_Fx_Flip_Axis axis;
- Eina_Bool cw:1;
+ Elm_Transit_Effect_Flip_Axis axis;
+ Eina_Bool cw : 1;
};
static void
-_elm_fx_flip_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+_transit_effect_flip_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit)
{
- Elm_Fx_Flip *flip = data;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Elm_Transit_Effect_Flip *flip = effect;
+ Evas_Object *front, *back;
+ int i;
+ int count = eina_list_count(transit->objs);
- evas_object_map_enable_set(flip->front, EINA_FALSE);
- evas_object_map_enable_set(flip->back, EINA_FALSE);
+ for (i = 0; i < (count - 1); i += 2)
+ {
+ front = eina_list_nth(transit->objs, i);
+ back = eina_list_nth(transit->objs, i+1);
+ evas_object_map_enable_set(front, EINA_FALSE);
+ evas_object_map_enable_set(back, EINA_FALSE);
+ }
+ free(flip);
}
static void
-_elm_fx_flip_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_flip_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- Elm_Fx_Flip *flip;
-
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Evas_Object *obj, *front, *back;
+ int count, i;
+ Elm_Transit_Effect_Flip *flip = effect;
Evas_Map *map;
-
float degree;
-
- Evas_Object *obj;
-
Evas_Coord x, y, w, h;
map = evas_map_new(4);
- if (!map)
- return;
-
- flip = data;
-
- if (flip->cw)
- degree = (float)(frame * 180);
- else
- degree = (float)(frame * -180);
-
- if (degree < 90 && degree > -90)
- {
- obj = flip->front;
- if(flip->back != flip->front) {
- evas_object_hide(flip->back);
- evas_object_show(flip->front);
- }
- }
- else
- {
- obj = flip->back;
- if(flip->back != flip->front) {
- evas_object_hide(flip->front);
- evas_object_show(flip->back);
- }
- }
+ if (!map) return;
- evas_map_smooth_set(map, EINA_TRUE);
- evas_map_util_points_populate_from_object_full(map, obj, 0);
- evas_object_geometry_get(obj, &x, &y, &w, &h);
- Evas_Coord half_w = (w / 2);
+ if (flip->cw) degree = (float)(progress * 180);
+ else degree = (float)(progress * -180);
- Evas_Coord half_h = (h / 2);
+ count = eina_list_count(transit->objs);
- if (flip->axis == ELM_FX_FLIP_AXIS_Y)
+ for (i = 0; i < (count - 1); i += 2)
{
- if ((degree >= 90) || (degree <= -90))
- {
- evas_map_point_image_uv_set(map, 0, w, 0);
- evas_map_point_image_uv_set(map, 1, 0, 0);
- evas_map_point_image_uv_set(map, 2, 0, h);
- evas_map_point_image_uv_set(map, 3, w, h);
- }
- evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
+ Evas_Coord half_w, half_h;
+
+ front = eina_list_nth(transit->objs, i);
+ back = eina_list_nth(transit->objs, i+1);
+
+ if ((degree < 90) && (degree > -90))
+ {
+ obj = front;
+ if (front != back)
+ {
+ evas_object_hide(back);
+ evas_object_show(front);
+ }
+ }
+ else
+ {
+ obj = back;
+ if (front != back)
+ {
+ evas_object_hide(front);
+ evas_object_show(back);
+ }
+ }
+
+ evas_map_util_points_populate_from_object_full(map, obj, 0);
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
+ half_w = (w / 2);
+ half_h = (h / 2);
+
+ if (flip->axis == ELM_TRANSIT_EFFECT_FLIP_AXIS_Y)
+ {
+ if ((degree >= 90) || (degree <= -90))
+ {
+ evas_map_point_image_uv_set(map, 0, w, 0);
+ evas_map_point_image_uv_set(map, 1, 0, 0);
+ evas_map_point_image_uv_set(map, 2, 0, h);
+ evas_map_point_image_uv_set(map, 3, w, h);
+ }
+ evas_map_util_3d_rotate(map, 0, degree,
+ 0, x + half_w, y + half_h, 0);
+ }
+ else
+ {
+ if ((degree >= 90) || (degree <= -90))
+ {
+ evas_map_point_image_uv_set(map, 0, 0, h);
+ evas_map_point_image_uv_set(map, 1, w, h);
+ evas_map_point_image_uv_set(map, 2, w, 0);
+ evas_map_point_image_uv_set(map, 3, 0, 0);
+ }
+ evas_map_util_3d_rotate(map, degree,
+ 0, 0, x + half_w, y + half_h, 0);
+ }
+ evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, _TRANSIT_FOCAL);
+ evas_object_map_enable_set(front, EINA_TRUE);
+ evas_object_map_enable_set(back, EINA_TRUE);
+ evas_object_map_set(obj, map);
}
- else
- {
- if ((degree >= 90) || (degree <= -90))
- {
- evas_map_point_image_uv_set(map, 0, 0, h);
- evas_map_point_image_uv_set(map, 1, w, h);
- evas_map_point_image_uv_set(map, 2, w, 0);
- evas_map_point_image_uv_set(map, 3, 0, 0);
- }
- evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
- }
- evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
- evas_object_map_enable_set(flip->front, EINA_TRUE);
- evas_object_map_enable_set(flip->back, EINA_TRUE);
- evas_object_map_set(obj, map);
evas_map_free(map);
}
-/**
- * Add Flip effect.
- *
- * @param[in] front Front surface object
- * @param[in] back Back surface object
- * @param[in] axis Flipping Axis(X or Y)
- * @param[in] cw Flipping Direction. EINA_TRUE is clock-wise
- * @return Flip effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_flip_add(Evas_Object *front, Evas_Object *back, Elm_Fx_Flip_Axis axis,
- Eina_Bool cw)
+static Elm_Transit_Effect *
+_transit_effect_flip_context_new(Elm_Transit_Effect_Flip_Axis axis, Eina_Bool cw)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Flip *flip;
- Elm_Fx_Flip *flip;
+ flip = ELM_NEW(Elm_Transit_Effect_Flip);
+ if (!flip) return NULL;
- if ((!front) || (!back))
- return NULL;
+ flip->cw = cw;
+ flip->axis = axis;
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ return flip;
+}
- flip = calloc(1, sizeof(Elm_Fx_Flip));
+EAPI Elm_Transit_Effect *
+elm_transit_effect_flip_add(Elm_Transit *transit, Elm_Transit_Effect_Flip_Axis axis, Eina_Bool cw)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_flip_context_new(axis, cw);
- if (!flip)
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate flip effect! : transit=%p", transit);
+ return NULL;
}
-
- flip->front = front;
- flip->back = back;
- flip->cw = cw;
- flip->axis = axis;
- effect->end_op = _elm_fx_flip_end;
- effect->animation_op = _elm_fx_flip_op;
- effect->user_data = flip;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_flip_op, effect,
+ _transit_effect_flip_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//ResizableFlip FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _resizable_flip Elm_Fx_ResizableFlip;
-static void _elm_fx_resizable_flip_begin(void *data, Eina_Bool reverse,
- unsigned int repeat);
-static void _elm_fx_resizable_flip_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_resizable_flip_op(void *data, Elm_Animator *animator,
- double frame);
-static void _set_image_uv_by_axis_y(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
- float degree);
-static void _set_image_uv_by_axis_x(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
- float degree);
+///////////////////////////////////////////////////////////////////////////
+//ResizableFlip Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Resizable_Flip Elm_Transit_Effect_ResizableFlip;
+typedef struct _Elm_Transit_Effect_Resizable_Flip_Node Elm_Transit_Effect_ResizableFlip_Node;
-struct _resizable_flip
+struct _Elm_Transit_Effect_Resizable_Flip_Node
{
Evas_Object *front;
Evas_Object *back;
- Elm_Fx_Flip_Axis axis;
- struct _vector2d
- {
+ struct _vector2d {
float x, y;
} from_pos, from_size, to_pos, to_size;
- Eina_Bool cw:1;
+};
+
+struct _Elm_Transit_Effect_Resizable_Flip
+{
+ Eina_List *nodes;
+ Eina_Bool cw : 1;
+ Elm_Transit_Effect_Flip_Axis axis;
};
static void
-_elm_fx_resizable_flip_begin(void *data, Eina_Bool reverse, unsigned int repeat)
+_resizable_flip_object_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Elm_Fx_ResizableFlip *resizable_flip = data;
+ Elm_Transit_Effect_ResizableFlip *resizable_flip = data;
+ Eina_List *elist;
+ Elm_Transit_Effect_ResizableFlip_Node *resizable_flip_node;
- evas_object_show(resizable_flip->front);
- _elm_fx_resizable_flip_op(data, NULL, 0);
+ EINA_LIST_FOREACH(resizable_flip->nodes, elist, resizable_flip_node)
+ {
+ if (resizable_flip_node->front == obj)
+ evas_object_event_callback_del(resizable_flip_node->back,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb);
+ else if (resizable_flip_node->back == obj)
+ evas_object_event_callback_del(resizable_flip_node->front,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb);
+ else continue;
+
+ resizable_flip->nodes = eina_list_remove_list(resizable_flip->nodes,
+ elist);
+ free(resizable_flip_node);
+ break;
+ }
}
-static void
-_elm_fx_resizable_flip_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+static Eina_List *
+_resizable_flip_nodes_build(Elm_Transit *transit, Elm_Transit_Effect_ResizableFlip *resizable_flip)
{
- Elm_Fx_ResizableFlip *resizable_flip = data;
+ Elm_Transit_Effect_ResizableFlip_Node *resizable_flip_node;
+ Eina_List *data_list = NULL;
+ Evas_Coord front_x, front_y, front_w, front_h;
+ Evas_Coord back_x, back_y, back_w, back_h;
+ int i, count;
+
+ count = eina_list_count(transit->objs);
+ for (i = 0; i < (count - 1); i += 2)
+ {
+ resizable_flip_node = ELM_NEW(Elm_Transit_Effect_ResizableFlip_Node);
+ if (!resizable_flip_node)
+ {
+ eina_list_free(data_list);
+ return NULL;
+ }
+
+ resizable_flip_node->front = eina_list_nth(transit->objs, i);
+ resizable_flip_node->back = eina_list_nth(transit->objs, i+1);
+
+ evas_object_geometry_get(resizable_flip_node->front,
+ &front_x, &front_y, &front_w, &front_h);
+ evas_object_geometry_get(resizable_flip_node->back,
+ &back_x, &back_y, &back_w, &back_h);
+
+ resizable_flip_node->from_pos.x = front_x;
+ resizable_flip_node->from_pos.y = front_y;
+ resizable_flip_node->to_pos.x = back_x - front_x;
+ resizable_flip_node->to_pos.y = back_y - front_y;
+
+ resizable_flip_node->from_size.x = front_w;
+ resizable_flip_node->from_size.y = front_h;
+ resizable_flip_node->to_size.x = back_w - front_w;
+ resizable_flip_node->to_size.y = back_h - front_h;
+
+ data_list = eina_list_append(data_list, resizable_flip_node);
+
+ evas_object_event_callback_add(resizable_flip_node->back,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb, resizable_flip);
+ evas_object_event_callback_add(resizable_flip_node->front,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb, resizable_flip);
+ }
- evas_object_map_enable_set(resizable_flip->front, EINA_FALSE);
- evas_object_map_enable_set(resizable_flip->back, EINA_FALSE);
+ return data_list;
}
static void
-_set_image_uv_by_axis_y(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
- float degree)
+_set_image_uv_by_axis_y(Evas_Map *map, Elm_Transit_Effect_ResizableFlip_Node *flip, float degree)
{
if ((degree >= 90) || (degree <= -90))
{
- evas_map_point_image_uv_set(map, 0,
- (flip->from_size.x * 2) + flip->to_size.x,
- 0);
- evas_map_point_image_uv_set(map, 1, 0, 0);
- evas_map_point_image_uv_set(map, 2, 0,
- (flip->from_size.y * 2) + flip->to_size.y);
- evas_map_point_image_uv_set(map, 3,
- (flip->from_size.x * 2) + flip->to_size.x,
- (flip->from_size.y * 2) + flip->to_size.y);
+ evas_map_point_image_uv_set(map, 0,
+ (flip->from_size.x * 2) + flip->to_size.x,
+ 0);
+ evas_map_point_image_uv_set(map, 1, 0, 0);
+ evas_map_point_image_uv_set(map, 2, 0,
+ (flip->from_size.y * 2) + flip->to_size.y);
+ evas_map_point_image_uv_set(map, 3,
+ (flip->from_size.x * 2) + flip->to_size.x,
+ (flip->from_size.y * 2) + flip->to_size.y);
}
else
{
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
- evas_map_point_image_uv_set(map, 2, flip->from_size.x,
- flip->from_size.y);
- evas_map_point_image_uv_set(map, 3, 0, flip->from_size.y);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
+ evas_map_point_image_uv_set(map, 2, flip->from_size.x,
+ flip->from_size.y);
+ evas_map_point_image_uv_set(map, 3, 0, flip->from_size.y);
}
}
static void
-_set_image_uv_by_axis_x(Evas_Map *map, Elm_Fx_ResizableFlip *flip,
- float degree)
+_set_image_uv_by_axis_x(Evas_Map *map, Elm_Transit_Effect_ResizableFlip_Node *flip, float degree)
{
if ((degree >= 90) || (degree <= -90))
{
- evas_map_point_image_uv_set(map, 0, 0,
- (flip->from_size.y * 2) + flip->to_size.y);
- evas_map_point_image_uv_set(map, 1,
- (flip->from_size.x * 2) + flip->to_size.x,
- (flip->from_size.y * 2) + flip->to_size.y);
- evas_map_point_image_uv_set(map, 2,
- (flip->from_size.x * 2) + flip->to_size.x,
- 0);
- evas_map_point_image_uv_set(map, 3, 0, 0);
+ evas_map_point_image_uv_set(map, 0, 0,
+ (flip->from_size.y * 2) + flip->to_size.y);
+ evas_map_point_image_uv_set(map, 1,
+ (flip->from_size.x * 2) + flip->to_size.x,
+ (flip->from_size.y * 2) + flip->to_size.y);
+ evas_map_point_image_uv_set(map, 2,
+ (flip->from_size.x * 2) + flip->to_size.x,
+ 0);
+ evas_map_point_image_uv_set(map, 3, 0, 0);
}
else
{
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
- evas_map_point_image_uv_set(map, 2, flip->from_size.x,
- flip->from_size.y);
- evas_map_point_image_uv_set(map, 3, 0, flip->to_size.y);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, flip->from_size.x, 0);
+ evas_map_point_image_uv_set(map, 2, flip->from_size.x,
+ flip->from_size.y);
+ evas_map_point_image_uv_set(map, 3, 0, flip->from_size.y);
}
}
-static void
-_elm_fx_resizable_flip_op(void *data, Elm_Animator *animator, double frame)
+void
+_transit_effect_resizable_flip_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_ResizableFlip *resizable_flip;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
- Evas_Map *map;
+ Elm_Transit_Effect_ResizableFlip *resizable_flip = effect;
+ Eina_List *elist, *elist_next;
+ Elm_Transit_Effect_ResizableFlip_Node *resizable_flip_node;
- float degree;
+ EINA_LIST_FOREACH_SAFE(resizable_flip->nodes,
+ elist, elist_next, resizable_flip_node)
+ {
+ evas_object_map_enable_set(resizable_flip_node->front, EINA_FALSE);
+ evas_object_map_enable_set(resizable_flip_node->back, EINA_FALSE);
- Evas_Object *obj;
+ resizable_flip->nodes = eina_list_remove_list(resizable_flip->nodes,
+ elist);
- float x, y, w, h;
+ evas_object_event_callback_del(resizable_flip_node->back,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb);
+ evas_object_event_callback_del(resizable_flip_node->front,
+ EVAS_CALLBACK_DEL, _resizable_flip_object_del_cb);
+ free(resizable_flip_node);
+ }
+ free(resizable_flip);
+}
+void
+_transit_effect_resizable_flip_op(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__, double progress)
+{
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Evas_Map *map;
+ Evas_Object *obj;
+ float x, y, w, h;
+ float degree;
Evas_Coord half_w, half_h;
+ Elm_Transit_Effect_ResizableFlip *resizable_flip = effect;
+ Elm_Transit_Effect_ResizableFlip_Node *resizable_flip_node;
+ Eina_List *elist;
map = evas_map_new(4);
- if (!map)
- return;
+ if (!map) return;
- resizable_flip = data;
+ if (resizable_flip->cw) degree = (float)(progress * 180);
+ else degree = (float)(progress * -180);
- if (resizable_flip->cw)
- degree = (float)(frame * 180);
- else
- degree = (float)(frame * -180);
-
- if ((degree < 90) && (degree > -90))
- {
- obj = resizable_flip->front;
- if(resizable_flip->back != resizable_flip->front) {
- evas_object_hide(resizable_flip->back);
- evas_object_show(resizable_flip->front);
- }
- }
- else
- {
- obj = resizable_flip->back;
- if(resizable_flip->back != resizable_flip->front) {
- evas_object_hide(resizable_flip->front);
- evas_object_show(resizable_flip->back);
- }
- }
- evas_map_smooth_set(map, EINA_TRUE);
-
- x = resizable_flip->from_pos.x + (resizable_flip->to_pos.x * frame);
- y = resizable_flip->from_pos.y + (resizable_flip->to_pos.y * frame);
- w = resizable_flip->from_size.x + (resizable_flip->to_size.x * frame);
- h = resizable_flip->from_size.y + (resizable_flip->to_size.y * frame);
- evas_map_point_coord_set(map, 0, x, y, 0);
- evas_map_point_coord_set(map, 1, x + w, y, 0);
- evas_map_point_coord_set(map, 2, x + w, y + h, 0);
- evas_map_point_coord_set(map, 3, x, y + h, 0);
-
- half_w = (Evas_Coord) (w / 2);
- half_h = (Evas_Coord) (h / 2);
+ if (!resizable_flip->nodes)
+ resizable_flip->nodes = _resizable_flip_nodes_build(transit,
+ resizable_flip);
- if (resizable_flip->axis == ELM_FX_FLIP_AXIS_Y)
+ EINA_LIST_FOREACH(resizable_flip->nodes, elist, resizable_flip_node)
{
- _set_image_uv_by_axis_y(map, resizable_flip, degree);
- evas_map_util_3d_rotate(map, 0, degree, 0, x + half_w, y + half_h, 0);
+ if ((degree < 90) && (degree > -90))
+ {
+ obj = resizable_flip_node->front;
+ if (resizable_flip_node->front != resizable_flip_node->back)
+ {
+ evas_object_hide(resizable_flip_node->back);
+ evas_object_show(resizable_flip_node->front);
+ }
+ }
+ else
+ {
+ obj = resizable_flip_node->back;
+ if (resizable_flip_node->front != resizable_flip_node->back)
+ {
+ evas_object_hide(resizable_flip_node->front);
+ evas_object_show(resizable_flip_node->back);
+ }
+ }
+
+ x = resizable_flip_node->from_pos.x +
+ (resizable_flip_node->to_pos.x * progress);
+ y = resizable_flip_node->from_pos.y +
+ (resizable_flip_node->to_pos.y * progress);
+ w = resizable_flip_node->from_size.x +
+ (resizable_flip_node->to_size.x * progress);
+ h = resizable_flip_node->from_size.y +
+ (resizable_flip_node->to_size.y * progress);
+ evas_map_point_coord_set(map, 0, x, y, 0);
+ evas_map_point_coord_set(map, 1, x + w, y, 0);
+ evas_map_point_coord_set(map, 2, x + w, y + h, 0);
+ evas_map_point_coord_set(map, 3, x, y + h, 0);
+
+ half_w = (Evas_Coord)(w / 2);
+ half_h = (Evas_Coord)(h / 2);
+
+ if (resizable_flip->axis == ELM_TRANSIT_EFFECT_FLIP_AXIS_Y)
+ {
+ _set_image_uv_by_axis_y(map, resizable_flip_node, degree);
+ evas_map_util_3d_rotate(map, 0, degree,
+ 0, x + half_w, y + half_h, 0);
+ }
+ else
+ {
+ _set_image_uv_by_axis_x(map, resizable_flip_node, degree);
+ evas_map_util_3d_rotate(map, degree, 0,
+ 0, x + half_w, y + half_h, 0);
+ }
+
+ evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, _TRANSIT_FOCAL);
+ evas_object_map_enable_set(resizable_flip_node->front, EINA_TRUE);
+ evas_object_map_enable_set(resizable_flip_node->back, EINA_TRUE);
+ evas_object_map_set(obj, map);
}
- else
- {
- _set_image_uv_by_axis_x(map, resizable_flip, degree);
- evas_map_util_3d_rotate(map, degree, 0, 0, x + half_w, y + half_h, 0);
- }
-
- evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
- evas_object_map_enable_set(resizable_flip->front, EINA_TRUE);
- evas_object_map_enable_set(resizable_flip->back, EINA_TRUE);
- evas_object_map_set(obj, map);
evas_map_free(map);
}
-/**
- * Add ResizbleFlip effect. the size of each surface objects are interpolated automatically.
- *
- * @param[in] front Front surface object
- * @param[in] back Back surface object
- * @param[in] axis Flipping Axis.(X or Y)
- * @param[in] cw Flipping Direction. EINA_TRUE is clock-wise
- * @return Flip effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_resizable_flip_add(Evas_Object *front, Evas_Object *back,
- Elm_Fx_Flip_Axis axis, Eina_Bool cw)
+static Elm_Transit_Effect *
+_transit_effect_resizable_flip_context_new(Elm_Transit_Effect_Flip_Axis axis, Eina_Bool cw)
{
- Elm_Fx_ResizableFlip *resizable_flip;
+ Elm_Transit_Effect_ResizableFlip *resizable_flip;
- Elm_Effect *effect;
+ resizable_flip = ELM_NEW(Elm_Transit_Effect_ResizableFlip);
+ if (!resizable_flip) return NULL;
- Evas_Coord front_x, front_y, front_w, front_h;
+ resizable_flip->cw = cw;
+ resizable_flip->axis = axis;
- Evas_Coord back_x, back_y, back_w, back_h;
+ return resizable_flip;
+}
- if (!front || !back)
- return NULL;
+EAPI Elm_Transit_Effect *
+elm_transit_effect_resizable_flip_add(Elm_Transit *transit, Elm_Transit_Effect_Flip_Axis axis, Eina_Bool cw)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_resizable_flip_context_new(axis, cw);
- effect = calloc(1, sizeof(Elm_Effect));
if (!effect)
- return NULL;
-
- resizable_flip = calloc(1, sizeof(Elm_Fx_ResizableFlip));
-
- if (!resizable_flip)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate resizable_flip effect! : transit=%p", transit);
+ return NULL;
}
-
- resizable_flip->front = front;
- resizable_flip->back = back;
- resizable_flip->cw = cw;
- resizable_flip->axis = axis;
-
- evas_object_geometry_get(resizable_flip->front, &front_x, &front_y, &front_w,
- &front_h);
- evas_object_geometry_get(resizable_flip->back, &back_x, &back_y, &back_w,
- &back_h);
-
- resizable_flip->from_pos.x = front_x;
- resizable_flip->from_pos.y = front_y;
- resizable_flip->to_pos.x = back_x - front_x;
- resizable_flip->to_pos.y = back_y - front_y;
-
- resizable_flip->from_size.x = front_w;
- resizable_flip->from_size.y = front_h;
- resizable_flip->to_size.x = back_w - front_w;
- resizable_flip->to_size.y = back_h - front_h;
-
- effect->begin_op = _elm_fx_resizable_flip_begin;
- effect->end_op = _elm_fx_resizable_flip_end;
- effect->animation_op = _elm_fx_resizable_flip_op;
- effect->user_data = resizable_flip;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_resizable_flip_op, effect,
+ _transit_effect_resizable_flip_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Wipe FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _wipe Elm_Fx_Wipe;
-static void _elm_fx_wipe_op(void *data, Elm_Animator *animator,
- double frame);
-static void _elm_fx_wipe_begin(void *data, Eina_Bool auto_repeat,
- unsigned int repeat_cnt);
-static void _elm_fx_wipe_end(void *data, Eina_Bool auto_repeat,
- unsigned int repeat_cnt);
-static void _elm_fx_wipe_hide(Evas_Map * map, Elm_Fx_Wipe_Dir dir,
- float x, float y, float w, float h, float frame);
-static void _elm_fx_wipe_show(Evas_Map *map, Elm_Fx_Wipe_Dir dir,
- float x, float y, float w, float h, float frame);
+///////////////////////////////////////////////////////////////////////////
+//Wipe Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Wipe Elm_Transit_Effect_Wipe;
-struct _wipe
+struct _Elm_Transit_Effect_Wipe
{
- Evas_Object *obj;
- Elm_Fx_Wipe_Type type;
- Elm_Fx_Wipe_Dir dir;
+ Elm_Transit_Effect_Wipe_Type type;
+ Elm_Transit_Effect_Wipe_Dir dir;
};
static void
-_elm_fx_wipe_begin(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt)
-{
- Elm_Fx_Wipe *wipe = data;
-
- evas_object_show(wipe->obj);
- _elm_fx_wipe_op(data, NULL, 0);
-}
-
-static void
-_elm_fx_wipe_end(void *data, Eina_Bool auto_repeat, unsigned int repeat_cnt)
+_elm_fx_wipe_hide(Evas_Map * map, Elm_Transit_Effect_Wipe_Dir dir, float x, float y, float w, float h, float progress)
{
- Elm_Fx_Wipe *wipe = data;
+ float w2, h2;
- evas_object_map_enable_set(wipe->obj, EINA_FALSE);
+ switch (dir)
+ {
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_LEFT:
+ w2 = w - (w * progress);
+ h2 = (y + h);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, w2, 0);
+ evas_map_point_image_uv_set(map, 2, w2, h);
+ evas_map_point_image_uv_set(map, 3, 0, h);
+ evas_map_point_coord_set(map, 0, x, y, 0);
+ evas_map_point_coord_set(map, 1, x + w2, y, 0);
+ evas_map_point_coord_set(map, 2, x + w2, h2, 0);
+ evas_map_point_coord_set(map, 3, x, h2, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT:
+ w2 = (w * progress);
+ h2 = (y + h);
+ evas_map_point_image_uv_set(map, 0, w2, 0);
+ evas_map_point_image_uv_set(map, 1, w, 0);
+ evas_map_point_image_uv_set(map, 2, w, h);
+ evas_map_point_image_uv_set(map, 3, w2, h);
+ evas_map_point_coord_set(map, 0, x + w2, y, 0);
+ evas_map_point_coord_set(map, 1, x + w, y, 0);
+ evas_map_point_coord_set(map, 2, x + w, h2, 0);
+ evas_map_point_coord_set(map, 3, x + w2, h2, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_UP:
+ w2 = (x + w);
+ h2 = h - (h * progress);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, w, 0);
+ evas_map_point_image_uv_set(map, 2, w, h2);
+ evas_map_point_image_uv_set(map, 3, 0, h2);
+ evas_map_point_coord_set(map, 0, x, y, 0);
+ evas_map_point_coord_set(map, 1, w2, y, 0);
+ evas_map_point_coord_set(map, 2, w2, y+h2, 0);
+ evas_map_point_coord_set(map, 3, x, y+h2, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_DOWN:
+ w2 = (x + w);
+ h2 = (h * progress);
+ evas_map_point_image_uv_set(map, 0, 0, h2);
+ evas_map_point_image_uv_set(map, 1, w, h2);
+ evas_map_point_image_uv_set(map, 2, w, h);
+ evas_map_point_image_uv_set(map, 3, 0, h);
+ evas_map_point_coord_set(map, 0, x, y + h2, 0);
+ evas_map_point_coord_set(map, 1, w2, y + h2, 0);
+ evas_map_point_coord_set(map, 2, w2, y + h, 0);
+ evas_map_point_coord_set(map, 3, x, y + h, 0);
+ break;
+ default:
+ break;
+ }
+ evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, _TRANSIT_FOCAL);
}
static void
-_elm_fx_wipe_hide(Evas_Map * map, Elm_Fx_Wipe_Dir dir, float x, float y,
- float w, float h, float frame)
+_elm_fx_wipe_show(Evas_Map *map, Elm_Transit_Effect_Wipe_Dir dir, float x, float y, float w, float h, float progress)
{
float w2, h2;
switch (dir)
{
- case ELM_FX_WIPE_DIR_UP:
- w2 = (x + w);
- h2 = h-(h * frame);
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, w, 0);
- evas_map_point_image_uv_set(map, 2, w, h2);
- evas_map_point_image_uv_set(map, 3, 0, h2);
- evas_map_point_coord_set(map, 0, x, y, 0);
- evas_map_point_coord_set(map, 1, w2, y, 0);
- evas_map_point_coord_set(map, 2, w2, y+h2, 0);
- evas_map_point_coord_set(map, 3, x, y+h2, 0);
- break;
- case ELM_FX_WIPE_DIR_LEFT:
- w2 = w - (w * frame);
- h2 = (y + h);
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, w2, 0);
- evas_map_point_image_uv_set(map, 2, w2, h);
- evas_map_point_image_uv_set(map, 3, 0, h);
- evas_map_point_coord_set(map, 0, x, y, 0);
- evas_map_point_coord_set(map, 1, x + w2, y, 0);
- evas_map_point_coord_set(map, 2, x + w2, h2, 0);
- evas_map_point_coord_set(map, 3, x, h2, 0);
- break;
- case ELM_FX_WIPE_DIR_RIGHT:
- w2 = (w * frame);
- h2 = (y + h);
- evas_map_point_image_uv_set(map, 0, w2, 0);
- evas_map_point_image_uv_set(map, 1, w, 0);
- evas_map_point_image_uv_set(map, 2, w, h);
- evas_map_point_image_uv_set(map, 3, w2, h);
- evas_map_point_coord_set(map, 0, x + w2, y, 0);
- evas_map_point_coord_set(map, 1, x + w, y, 0);
- evas_map_point_coord_set(map, 2, x + w, h2, 0);
- evas_map_point_coord_set(map, 3, x + w2, h2, 0);
- break;
- case ELM_FX_WIPE_DIR_DOWN:
- w2 = (x + w);
- h2 = (h * frame);
- evas_map_point_image_uv_set(map, 0, 0, h2);
- evas_map_point_image_uv_set(map, 1, w, h2);
- evas_map_point_image_uv_set(map, 2, w, h);
- evas_map_point_image_uv_set(map, 3, 0, h);
- evas_map_point_coord_set(map, 0, x, y + h2, 0);
- evas_map_point_coord_set(map, 1, w2, y + h2, 0);
- evas_map_point_coord_set(map, 2, w2, y + h, 0);
- evas_map_point_coord_set(map, 3, x, y + h, 0);
- break;
- default:
- break;
- }
-
- evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_LEFT:
+ w2 = (w - (w * progress));
+ h2 = (y + h);
+ evas_map_point_image_uv_set(map, 0, w2, 0);
+ evas_map_point_image_uv_set(map, 1, w, 0);
+ evas_map_point_image_uv_set(map, 2, w, h);
+ evas_map_point_image_uv_set(map, 3, w2, h);
+ evas_map_point_coord_set(map, 0, x + w2, y, 0);
+ evas_map_point_coord_set(map, 1, w, y, 0);
+ evas_map_point_coord_set(map, 2, w, h2, 0);
+ evas_map_point_coord_set(map, 3, x + w2, h2, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT:
+ w2 = (w * progress);
+ h2 = (y + h);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, w2, 0);
+ evas_map_point_image_uv_set(map, 2, w2, h);
+ evas_map_point_image_uv_set(map, 3, 0, h);
+ evas_map_point_coord_set(map, 0, x, y, 0);
+ evas_map_point_coord_set(map, 1, x + w2, y, 0);
+ evas_map_point_coord_set(map, 2, x + w2, h2, 0);
+ evas_map_point_coord_set(map, 3, x, h2, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_UP:
+ w2 = (x + w);
+ h2 = (h - (h * progress));
+ evas_map_point_image_uv_set(map, 0, 0, h2);
+ evas_map_point_image_uv_set(map, 1, w, h2);
+ evas_map_point_image_uv_set(map, 2, w, h);
+ evas_map_point_image_uv_set(map, 3, 0, h);
+ evas_map_point_coord_set(map, 0, x, y + h2, 0);
+ evas_map_point_coord_set(map, 1, w2, y + h2, 0);
+ evas_map_point_coord_set(map, 2, w2, y + h, 0);
+ evas_map_point_coord_set(map, 3, x, y + h, 0);
+ break;
+ case ELM_TRANSIT_EFFECT_WIPE_DIR_DOWN:
+ w2 = (x + w);
+ h2 = (h * progress);
+ evas_map_point_image_uv_set(map, 0, 0, 0);
+ evas_map_point_image_uv_set(map, 1, w, 0);
+ evas_map_point_image_uv_set(map, 2, w, h2);
+ evas_map_point_image_uv_set(map, 3, 0, h2);
+ evas_map_point_coord_set(map, 0, x, y, 0);
+ evas_map_point_coord_set(map, 1, w2, y, 0);
+ evas_map_point_coord_set(map, 2, w2, y + h2, 0);
+ evas_map_point_coord_set(map, 3, x, y + h2, 0);
+ break;
+ default:
+ break;
+ }
+ evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, _TRANSIT_FOCAL);
}
static void
-_elm_fx_wipe_show(Evas_Map *map, Elm_Fx_Wipe_Dir dir, float x, float y,
- float w, float h, float frame)
+_transit_effect_wipe_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit)
{
- float w2, h2;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Eina_List *elist;
+ Evas_Object *obj;
+ Elm_Transit_Effect_Wipe *wipe = effect;
+ Eina_Bool reverse = elm_transit_auto_reverse_get(transit);
- switch (dir)
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
{
- case ELM_FX_WIPE_DIR_UP:
- w2 = (x + w);
- h2 = (h - (h * frame));
- evas_map_point_image_uv_set(map, 0, 0, h2);
- evas_map_point_image_uv_set(map, 1, w, h2);
- evas_map_point_image_uv_set(map, 2, w, h);
- evas_map_point_image_uv_set(map, 3, 0, h);
- evas_map_point_coord_set(map, 0, x, y + h2, 0);
- evas_map_point_coord_set(map, 1, w2, y + h2, 0);
- evas_map_point_coord_set(map, 2, w2, y + h, 0);
- evas_map_point_coord_set(map, 3, x, y + h, 0);
- break;
- case ELM_FX_WIPE_DIR_LEFT:
- w2 = (w - (w * frame));
- h2 = (y + h);
- evas_map_point_image_uv_set(map, 0, w2, 0);
- evas_map_point_image_uv_set(map, 1, w, 0);
- evas_map_point_image_uv_set(map, 2, w, h);
- evas_map_point_image_uv_set(map, 3, w2, h);
- evas_map_point_coord_set(map, 0, x + w2, y, 0);
- evas_map_point_coord_set(map, 1, x + w, y, 0);
- evas_map_point_coord_set(map, 2, x +w, h2, 0);
- evas_map_point_coord_set(map, 3, x + w2, h2, 0);
- break;
- case ELM_FX_WIPE_DIR_RIGHT:
- w2 = (w * frame);
- h2 = (y + h);
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, w2, 0);
- evas_map_point_image_uv_set(map, 2, w2, h);
- evas_map_point_image_uv_set(map, 3, 0, h);
- evas_map_point_coord_set(map, 0, x, y, 0);
- evas_map_point_coord_set(map, 1, x + w2, y, 0);
- evas_map_point_coord_set(map, 2, x + w2, h2, 0);
- evas_map_point_coord_set(map, 3, x, h2, 0);
- break;
- case ELM_FX_WIPE_DIR_DOWN:
- w2 = (x + w);
- h2 = (h * frame);
- evas_map_point_image_uv_set(map, 0, 0, 0);
- evas_map_point_image_uv_set(map, 1, w, 0);
- evas_map_point_image_uv_set(map, 2, w, h2);
- evas_map_point_image_uv_set(map, 3, 0, h2);
- evas_map_point_coord_set(map, 0, x, y, 0);
- evas_map_point_coord_set(map, 1, w2, y, 0);
- evas_map_point_coord_set(map, 2, w2, y + h2, 0);
- evas_map_point_coord_set(map, 3, x, y + h2, 0);
- break;
- default:
- break;
- }
-
- evas_map_util_3d_perspective(map, x + (w / 2), y + (h / 2), 0, 10000);
+ if ((wipe->type == ELM_TRANSIT_EFFECT_WIPE_TYPE_SHOW && !reverse)
+ || (wipe->type == ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE && reverse))
+ evas_object_show(obj);
+ else evas_object_hide(obj);
+ evas_object_map_enable_set(obj, EINA_FALSE);
+ }
+
+ free(wipe);
}
static void
-_elm_fx_wipe_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_wipe_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- Elm_Fx_Wipe *wipe;
-
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Elm_Transit_Effect_Wipe *wipe = effect;
Evas_Map *map;
-
Evas_Coord _x, _y, _w, _h;
+ Eina_List *elist;
+ Evas_Object *obj;
map = evas_map_new(4);
- if (!map)
- return;
+ if (!map) return;
- wipe = data;
- evas_map_smooth_set(map, EINA_TRUE);
- evas_object_geometry_get(wipe->obj, &_x, &_y, &_w, &_h);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ {
+ evas_object_geometry_get(obj, &_x, &_y, &_w, &_h);
- if (wipe->type == ELM_FX_WIPE_TYPE_SHOW)
- _elm_fx_wipe_show(map, wipe->dir, _x, _y, _w, _h, (float)frame);
- else
- _elm_fx_wipe_hide(map, wipe->dir, _x, _y, _w, _h, (float)frame);
+ if (wipe->type == ELM_TRANSIT_EFFECT_WIPE_TYPE_SHOW)
+ _elm_fx_wipe_show(map, wipe->dir, _x, _y, _w, _h, (float)progress);
+ else
+ _elm_fx_wipe_hide(map, wipe->dir, _x, _y, _w, _h, (float)progress);
- evas_object_map_enable_set(wipe->obj, EINA_TRUE);
- evas_object_map_set(wipe->obj, map);
+ evas_object_map_enable_set(obj, EINA_TRUE);
+ evas_object_map_set(obj, map);
+ }
evas_map_free(map);
}
-/**
- * Add Wipe effect.
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] type Wipe type. Hide or show
- * @param[in] dir Wipe Direction
- * @return Wipe effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_wipe_add(Evas_Object *obj, Elm_Fx_Wipe_Type type, Elm_Fx_Wipe_Dir dir)
+static Elm_Transit_Effect *
+_transit_effect_wipe_context_new(Elm_Transit_Effect_Wipe_Type type, Elm_Transit_Effect_Wipe_Dir dir)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Wipe *wipe;
- Elm_Fx_Wipe *wipe;
+ wipe = ELM_NEW(Elm_Transit_Effect_Wipe);
+ if (!wipe) return NULL;
- if (!obj)
- return NULL;
+ wipe->type = type;
+ wipe->dir = dir;
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ return wipe;
+}
- wipe = calloc(1, sizeof(Elm_Fx_Wipe));
- if (!wipe)
+EAPI void *
+elm_transit_effect_wipe_add(Elm_Transit *transit, Elm_Transit_Effect_Wipe_Type type, Elm_Transit_Effect_Wipe_Dir dir)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ void *effect = _transit_effect_wipe_context_new(type, dir);
+
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate wipe effect! : transit=%p", transit);
+ return NULL;
}
-
- wipe->obj = obj;
- wipe->type = type;
- wipe->dir = dir;
- effect->begin_op = _elm_fx_wipe_begin;
- effect->end_op = _elm_fx_wipe_end;
- effect->animation_op = _elm_fx_wipe_op;
- effect->user_data = wipe;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_wipe_op, effect,
+ _transit_effect_wipe_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Color FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _color Elm_Fx_Color;
-static void _elm_fx_color_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt);
-static void _elm_fx_color_op(void *data, Elm_Animator *animator, double frame);
+///////////////////////////////////////////////////////////////////////////
+//Color Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Color Elm_Transit_Effect_Color;
-struct _color
+struct _Elm_Transit_Effect_Color
{
- Evas_Object *obj;
- struct _unsigned_color
- {
+ struct _unsigned_color {
unsigned int r, g, b, a;
} from;
- struct _signed_color
- {
+ struct _signed_color {
int r, g, b, a;
} to;
};
static void
-_elm_fx_color_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+_transit_effect_color_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Color *color = data;
-
- evas_object_show(color->obj);
+ Elm_Transit_Effect_Color *color = effect;
+ free(color);
}
static void
-_elm_fx_color_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_color_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- Elm_Fx_Color *color;
-
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Elm_Transit_Effect_Color *color = effect;
+ Evas_Object *obj;
+ Eina_List *elist;
unsigned int r, g, b, a;
- color = data;
- r = (color->from.r + (int)((float)color->to.r * frame));
- g = (color->from.g + (int)((float)color->to.g * frame));
- b = (color->from.b + (int)((float)color->to.b * frame));
- a = (color->from.a + (int)((float)color->to.a * frame));
-
- evas_object_color_set(color->obj, r, g, b, a);
-}
-
-/**
- * Add Color effect.
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from_r RGB R when effect begins
- * @param[in] from_g RGB G when effect begins
- * @param[in] from_b RGB B when effect begins
- * @param[in] from_a RGB A when effect begins
- * @param[in] to_r RGB R when effect ends
- * @param[in] to_g RGB G when effect ends
- * @param[in] to_b RGB B when effect ends
- * @param[in] to_a RGB A when effect ends
- * @return Color Effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_color_add(Evas_Object *obj, unsigned int from_r, unsigned int from_g,
- unsigned int from_b, unsigned int from_a, unsigned int to_r,
- unsigned int to_g, unsigned int to_b, unsigned int to_a)
-{
- Elm_Effect *effect;
-
- Elm_Fx_Color *color;
-
- if (!obj)
- return NULL;
-
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ r = (color->from.r + (int)((float)color->to.r * progress));
+ g = (color->from.g + (int)((float)color->to.g * progress));
+ b = (color->from.b + (int)((float)color->to.b * progress));
+ a = (color->from.a + (int)((float)color->to.a * progress));
- color = calloc(1, sizeof(Elm_Fx_Color));
- if (!color)
- {
- free(effect);
- return NULL;
- }
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ evas_object_color_set(obj, r, g, b, a);
+}
+
+static Elm_Transit_Effect *
+_transit_effect_color_context_new(unsigned int from_r, unsigned int from_g, unsigned int from_b, unsigned int from_a, unsigned int to_r, unsigned int to_g, unsigned int to_b, unsigned int to_a)
+{
+ Elm_Transit_Effect_Color *color;
+
+ color = ELM_NEW(Elm_Transit_Effect_Color);
+ if (!color) return NULL;
- color->obj = obj;
color->from.r = from_r;
color->from.g = from_g;
color->from.b = from_b;
color->to.b = to_b - from_b;
color->to.a = to_a - from_a;
- effect->begin_op = _elm_fx_color_begin;
- effect->animation_op = _elm_fx_color_op;
- effect->user_data = color;
+ return color;
+}
+
+EAPI Elm_Transit_Effect *
+elm_transit_effect_color_add(Elm_Transit *transit, unsigned int from_r, unsigned int from_g, unsigned int from_b, unsigned int from_a, unsigned int to_r, unsigned int to_g, unsigned int to_b, unsigned int to_a)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_color_context_new(from_r, from_g, from_b, from_a, to_r, to_g, to_b, to_a);
+ if (!effect)
+ {
+ ERR("Failed to allocate color effect! : transit=%p", transit);
+ return NULL;
+ }
+ elm_transit_effect_add(transit,
+ _transit_effect_color_op, effect,
+ _transit_effect_color_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Fade FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _fade Elm_Fx_Fade;
-static void _elm_fx_fade_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_fade_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_fade_op(void *data, Elm_Animator *animator,
- double frame);
+///////////////////////////////////////////////////////////////////////////
+//Fade Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Fade Elm_Transit_Effect_Fade;
+typedef struct _Elm_Transit_Effect_Fade_Node Elm_Transit_Effect_Fade_Node;
-struct _fade
+struct _Elm_Transit_Effect_Fade_Node
{
Evas_Object *before;
Evas_Object *after;
struct _signed_color before_color, after_color;
int before_alpha;
int after_alpha;
- Eina_Bool inversed:1;
+ Eina_Bool inversed : 1;
+};
+
+struct _Elm_Transit_Effect_Fade
+{
+ Eina_List *nodes;
};
static void
-_elm_fx_fade_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+_fade_object_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Elm_Fx_Fade *fade = data;
+ Elm_Transit_Effect_Fade *fade = data;
+ Eina_List *elist;
+ Elm_Transit_Effect_Fade_Node *fade_node;
- fade->inversed = EINA_FALSE;
+ EINA_LIST_FOREACH(fade->nodes, elist, fade_node)
+ {
+ if (fade_node->before == obj)
+ evas_object_event_callback_del(fade_node->after,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb);
+ else if (fade_node->after == obj)
+ evas_object_event_callback_del(fade_node->before,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb);
+ else continue;
+
+ fade->nodes = eina_list_remove_list(fade->nodes, elist);
+ free(fade_node);
+ break;
+ }
}
-static void
-_elm_fx_fade_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+static Eina_List *
+_fade_nodes_build(Elm_Transit *transit, Elm_Transit_Effect_Fade *fade_data)
{
- Elm_Fx_Fade *fade = data;
+ Elm_Transit_Effect_Fade_Node *fade;
+ Eina_List *data_list = NULL;
+ int i, count;
- evas_object_color_set(fade->before, fade->before_color.r,
- fade->before_color.g, fade->before_color.b,
- fade->before_color.a);
- evas_object_color_set(fade->after, fade->after_color.r, fade->after_color.g,
- fade->after_color.b, fade->after_color.a);
+ count = eina_list_count(transit->objs);
+ for (i = 0; i < count; i += 2)
+ {
+ fade = ELM_NEW(Elm_Transit_Effect_Fade_Node);
+ if (!fade)
+ {
+ eina_list_free(data_list);
+ return NULL;
+ }
+
+ fade->before = eina_list_nth(transit->objs, i);
+ fade->after = eina_list_nth(transit->objs, i+1);
+
+ evas_object_color_get(fade->before,
+ &fade->before_color.r, &fade->before_color.g,
+ &fade->before_color.b, &fade->before_color.a);
+ evas_object_color_get(fade->after,
+ &fade->after_color.r, &fade->after_color.g,
+ &fade->after_color.b, &fade->after_color.a);
+
+ fade->before_alpha = (255 - fade->before_color.a);
+ fade->after_alpha = (255 - fade->after_color.a);
+
+ data_list = eina_list_append(data_list, fade);
+
+ evas_object_event_callback_add(fade->before,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb, fade_data);
+ evas_object_event_callback_add(fade->after,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb, fade_data);
+ }
+ return data_list;
}
static void
-_elm_fx_fade_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_fade_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Fade *fade;
-
- float _frame;
-
- fade = data;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Elm_Transit_Effect_Fade *fade = effect;
+ Elm_Transit_Effect_Fade_Node *fade_node;
+ Eina_List *elist, *elist_next;
- if (frame < 0.5)
+ EINA_LIST_FOREACH_SAFE(fade->nodes, elist, elist_next, fade_node)
{
- if (!fade->inversed)
- {
- evas_object_hide(fade->after);
- evas_object_show(fade->before);
- fade->inversed = EINA_TRUE;
- }
+ evas_object_color_set(fade_node->before, fade_node->before_color.r,
+ fade_node->before_color.g,
+ fade_node->before_color.b,
+ fade_node->before_color.a);
+ evas_object_color_set(fade_node->after, fade_node->after_color.r,
+ fade_node->after_color.g,
+ fade_node->after_color.b,
+ fade_node->after_color.a);
+
+ fade->nodes = eina_list_remove_list(fade->nodes, elist);
+ evas_object_event_callback_del(fade_node->before,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb);
+ evas_object_event_callback_del(fade_node->after,
+ EVAS_CALLBACK_DEL, _fade_object_del_cb);
+ free(fade_node);
+ }
- _frame = (1 - (frame * 2));
+ free(fade);
+}
- evas_object_color_set(fade->before, fade->before_color.r * _frame,
- fade->before_color.g * _frame,
- fade->before_color.b * _frame,
- fade->before_color.a + fade->before_alpha * (1 -
- _frame));
- }
- else
- {
- if (fade->inversed)
- {
- evas_object_hide(fade->before);
- evas_object_show(fade->after);
- fade->inversed = EINA_FALSE;
- }
+static void
+_transit_effect_fade_op(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__, double progress)
+{
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Elm_Transit_Effect_Fade *fade = effect;
+ Eina_List *elist;
+ Elm_Transit_Effect_Fade_Node *fade_node;
+ float _progress;
- _frame = ((frame - 0.5) * 2);
+ if (!fade->nodes)
+ fade->nodes = _fade_nodes_build(transit, fade);
- evas_object_color_set(fade->after, fade->after_color.r * _frame,
- fade->after_color.g * _frame,
- fade->after_color.b * _frame,
- fade->after_color.a + fade->after_alpha * (1 -
- _frame));
+ EINA_LIST_FOREACH(fade->nodes, elist, fade_node)
+ {
+ if (progress < 0.5)
+ {
+ if (!fade_node->inversed)
+ {
+ evas_object_hide(fade_node->after);
+ evas_object_show(fade_node->before);
+ fade_node->inversed = EINA_TRUE;
+ }
+
+ _progress = (1 - (progress * 2));
+
+ evas_object_color_set(fade_node->before,
+ fade_node->before_color.r * _progress,
+ fade_node->before_color.g * _progress,
+ fade_node->before_color.b * _progress,
+ fade_node->before_color.a +
+ fade_node->before_alpha * (1 - _progress));
+ }
+ else
+ {
+ if (fade_node->inversed)
+ {
+ evas_object_hide(fade_node->before);
+ evas_object_show(fade_node->after);
+ fade_node->inversed = EINA_FALSE;
+ }
+
+ _progress = ((progress - 0.5) * 2);
+
+ evas_object_color_set(fade_node->after,
+ fade_node->after_color.r * _progress,
+ fade_node->after_color.g * _progress,
+ fade_node->after_color.b * _progress,
+ fade_node->after_color.a +
+ fade_node->after_alpha * (1 - _progress));
+ }
}
-
}
-/**
- * Add Fade effect
- *
- * @param[in] before Evas Object before fade in
- * @param[in] after Evas Object after fade out
- * @return Fade effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_fade_add(Evas_Object *before, Evas_Object *after)
+static Elm_Transit_Effect *
+_transit_effect_fade_context_new(void)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Fade *fade;
+ fade = ELM_NEW(Elm_Transit_Effect_Fade);
+ if (!fade) return NULL;
+ return fade;
+}
- Elm_Fx_Fade *fade;
+EAPI Elm_Transit_Effect *
+elm_transit_effect_fade_add(Elm_Transit *transit)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
- if ((!before) && (!after))
- return NULL;
+ Elm_Transit_Effect *effect = _transit_effect_fade_context_new();
- effect = calloc(1, sizeof(Elm_Effect));
if (!effect)
- return NULL;
-
- fade = calloc(1, sizeof(Elm_Fx_Fade));
-
- if (!fade)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate fade effect! : transit=%p", transit);
+ return NULL;
}
-
- evas_object_color_get(before, &fade->before_color.r, &fade->before_color.g,
- &fade->before_color.b, &fade->before_color.a);
- evas_object_color_get(after, &fade->after_color.r, &fade->after_color.g,
- &fade->after_color.b, &fade->after_color.a);
-
- fade->before = before;
- fade->after = after;
- fade->before_alpha = (255 - fade->before_color.a);
- fade->after_alpha = (255 - fade->after_color.a);
-
- effect->begin_op = _elm_fx_fade_begin;
- effect->end_op = _elm_fx_fade_end;
- effect->animation_op = _elm_fx_fade_op;
- effect->user_data = fade;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_fade_op, effect,
+ _transit_effect_fade_context_free);
return effect;
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Blend FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _blend Elm_Fx_Blend;
-static void _elm_fx_blend_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_blend_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_blend_op(void *data, Elm_Animator *animator,
- double frame);
+///////////////////////////////////////////////////////////////////////////
+//Blend Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Blend Elm_Transit_Effect_Blend;
+typedef struct _Elm_Transit_Effect_Blend_Node Elm_Transit_Effect_Blend_Node;
-struct _blend
+struct _Elm_Transit_Effect_Blend_Node
{
Evas_Object *before;
Evas_Object *after;
struct _signed_color from, to;
};
-static void
-_elm_fx_blend_begin(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+struct _Elm_Transit_Effect_Blend
{
- Elm_Fx_Blend *blend = data;
-
- evas_object_show(blend->before);
-}
+ Eina_List *nodes;
+};
static void
-_elm_fx_blend_end(void *data, Eina_Bool auto_reverse, unsigned int repeat_cnt)
+_blend_object_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Elm_Fx_Blend *blend = data;
+ Elm_Transit_Effect_Blend *blend = data;
+ Eina_List *elist;
+ Elm_Transit_Effect_Blend_Node *blend_node;
- evas_object_color_set(blend->before, blend->from.r, blend->from.g,
- blend->from.b, blend->from.a);
- evas_object_color_set(blend->after, blend->to.r, blend->to.g, blend->to.b,
- blend->to.a);
- if (!auto_reverse)
- evas_object_hide(blend->before);
- else
- evas_object_hide(blend->after);
+ EINA_LIST_FOREACH(blend->nodes, elist, blend_node)
+ {
+ if (blend_node->after == obj)
+ evas_object_event_callback_del(blend_node->before,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb);
+ else if (blend_node->before == obj)
+ evas_object_event_callback_del(blend_node->after,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb);
+ else continue;
+
+ blend->nodes = eina_list_remove_list(blend->nodes, elist);
+ free(blend_node);
+ break;
+ }
}
-static void
-_elm_fx_blend_op(void *data, Elm_Animator *animator, double frame)
+static Eina_List *
+_blend_nodes_build(Elm_Transit *transit, Elm_Transit_Effect_Blend *blend)
{
- Elm_Fx_Blend *blend = data;
+ Elm_Transit_Effect_Blend_Node *blend_node;
+ Eina_List *data_list = NULL;
+ int i, count;
- evas_object_show(blend->after);
- evas_object_color_set(blend->before, (int)(blend->from.r * (1 - frame)),
- (int)(blend->from.g * (1 - frame)),
- (int)(blend->from.b * (1 - frame)),
- (int)(blend->from.a * (1 - frame)));
- evas_object_color_set(blend->after, (int)(blend->to.r * frame),
- (int)(blend->to.g * frame), (int)(blend->to.b * frame),
- (int)(blend->to.a * frame));
+ count = eina_list_count(transit->objs);
+ for (i = 0; i < (count - 1); i += 2)
+ {
+ blend_node = ELM_NEW(Elm_Transit_Effect_Blend_Node);
+ if (!blend_node)
+ {
+ eina_list_free(data_list);
+ return NULL;
+ }
+
+ blend_node->before = eina_list_nth(transit->objs, i);
+ blend_node->after = eina_list_nth(transit->objs, i + 1);
+ evas_object_show(blend_node->before);
+ evas_object_show(blend_node->after);
+
+ evas_object_color_get(blend_node->before, &blend_node->from.r,
+ &blend_node->from.g, &blend_node->from.b,
+ &blend_node->from.a);
+ evas_object_color_get(blend_node->after, &blend_node->to.r,
+ &blend_node->to.g, &blend_node->to.b,
+ &blend_node->to.a);
+
+ data_list = eina_list_append(data_list, blend_node);
+
+ evas_object_event_callback_add(blend_node->before,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb, blend);
+ evas_object_event_callback_add(blend_node->after,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb, blend);
+ }
+ return data_list;
}
-/**
- * Add Blend effect
- *
- * @param[in] before Evas Object before blending
- * @param[in] after Evas Object after blending
- * @return Blend effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_blend_add(Evas_Object *before, Evas_Object *after)
+void
+_transit_effect_blend_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Effect *effect;
-
- Elm_Fx_Blend *blend;
-
- if ((!before) && (!after))
- return NULL;
-
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Elm_Transit_Effect_Blend *blend = effect;
+ Elm_Transit_Effect_Blend_Node *blend_node;
+ Eina_List *elist, *elist_next;
- blend = calloc(1, sizeof(Elm_Fx_Blend));
- if (!blend)
+ EINA_LIST_FOREACH_SAFE(blend->nodes, elist, elist_next, blend_node)
{
- free(effect);
- return NULL;
+ evas_object_color_set(blend_node->before,
+ blend_node->from.r, blend_node->from.g,
+ blend_node->from.b, blend_node->from.a);
+ evas_object_color_set(blend_node->after, blend_node->to.r,
+ blend_node->to.g, blend_node->to.b,
+ blend_node->to.a);
+
+ if (elm_transit_auto_reverse_get(transit))
+ evas_object_hide(blend_node->after);
+ else
+ evas_object_hide(blend_node->before);
+
+ blend->nodes = eina_list_remove_list(blend->nodes, elist);
+
+ evas_object_event_callback_del(blend_node->before,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb);
+ evas_object_event_callback_del(blend_node->after,
+ EVAS_CALLBACK_DEL, _blend_object_del_cb);
+ free(blend_node);
}
-
- blend->before = before;
- blend->after = after;
- evas_object_color_get(before, &blend->from.r, &blend->from.g, &blend->from.b,
- &blend->from.a);
- evas_object_color_get(after, &blend->to.r, &blend->to.g, &blend->to.b,
- &blend->to.a);
-
- effect->begin_op = _elm_fx_blend_begin;
- effect->end_op = _elm_fx_blend_end;
- effect->animation_op = _elm_fx_blend_op;
- effect->user_data = blend;
-
- return effect;
+ free(blend);
}
-/////////////////////////////////////////////////////////////////////////////////////
-//Rotation FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _rotation Elm_Fx_Rotation;
-static void _elm_fx_rotation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_rotation_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_rotation_op(void *data, Elm_Animator *animator,
- double frame);
-
-struct _rotation
-{
- Evas_Object *obj;
- Eina_Bool cw;
- float from, to;
-};
-
-static void
-_elm_fx_rotation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+void
+_transit_effect_blend_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- Elm_Fx_Rotation *rotation = data;
-
- evas_object_show(rotation->obj);
-}
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Elm_Transit_Effect_Blend *blend = effect;
+ Elm_Transit_Effect_Blend_Node *blend_node;
+ Eina_List *elist;
-static void
-_elm_fx_rotation_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
-{
- Elm_Fx_Rotation *rotation = data;
+ if (!blend->nodes) blend->nodes = _blend_nodes_build(transit, blend);
- evas_object_map_enable_set(rotation->obj, EINA_FALSE);
+ EINA_LIST_FOREACH(blend->nodes, elist, blend_node)
+ {
+ evas_object_color_set(blend_node->before,
+ (int)(blend_node->from.r * (1 - progress)),
+ (int)(blend_node->from.g * (1 - progress)),
+ (int)(blend_node->from.b * (1 - progress)),
+ (int)(blend_node->from.a * (1 - progress)));
+ evas_object_color_set(blend_node->after,
+ (int)(blend_node->to.r * progress),
+ (int)(blend_node->to.g * progress),
+ (int)(blend_node->to.b * progress),
+ (int)(blend_node->to.a * progress));
+ }
}
-static void
-_elm_fx_rotation_op(void *data, Elm_Animator *animator, double frame)
+static Elm_Transit_Effect *
+_transit_effect_blend_context_new(void)
{
- Elm_Fx_Rotation *rotation;
-
- Evas_Map *map;
-
- Evas_Coord x, y, w, h;
-
- float degree;
-
- float half_w, half_h;
-
- map = evas_map_new(4);
- if (!map)
- return;
-
- rotation = data;
-
- evas_map_smooth_set(map, EINA_TRUE);
- evas_map_util_points_populate_from_object_full(map, rotation->obj, 0);
- degree = rotation->from + (float)(frame * rotation->to);
-
- if (!rotation->cw)
- degree *= -1;
-
- evas_object_geometry_get(rotation->obj, &x, &y, &w, &h);
-
- half_w = (float)w *0.5;
-
- half_h = (float)h *0.5;
+ Elm_Transit_Effect_Blend *blend;
- evas_map_util_3d_rotate(map, 0, 0, degree, x + half_w, y + half_h, 0);
- evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 10000);
- evas_object_map_enable_set(rotation->obj, EINA_TRUE);
- evas_object_map_set(rotation->obj, map);
- evas_map_free(map);
+ blend = ELM_NEW(Elm_Transit_Effect_Blend);
+ if (!blend) return NULL;
+ return blend;
}
-/**
- * Add Rotation effect
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from degree Degree when effect begins
- * @param[in] to_degree Degree when effect is ends
- * @param[in] cw Rotation direction. EINA_TRUE is clock wise
- * @return Rotation effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_rotation_add(Evas_Object *obj, float from_degree, float to_degree,
- Eina_Bool cw)
+EAPI Elm_Transit_Effect *
+elm_transit_effect_blend_add(Elm_Transit *transit)
{
- Elm_Effect *effect;
-
- Elm_Fx_Rotation *rotation;
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_blend_context_new();
- if (!obj)
- return NULL;
-
- effect = calloc(1, sizeof(Elm_Effect));
if (!effect)
- return NULL;
-
- rotation = calloc(1, sizeof(Elm_Fx_Rotation));
-
- if (!rotation)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate blend effect! : transit=%p", transit);
+ return NULL;
}
-
- rotation->obj = obj;
- rotation->from = from_degree;
- rotation->to = to_degree - from_degree;
- rotation->cw = cw;
-
- effect->begin_op = _elm_fx_rotation_begin;
- effect->end_op = _elm_fx_rotation_end;
- effect->animation_op = _elm_fx_rotation_op;
- effect->user_data = rotation;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_blend_op, effect,
+ _transit_effect_blend_context_free);
return effect;
}
+///////////////////////////////////////////////////////////////////////////
+//Rotation Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Rotation Elm_Transit_Effect_Rotation;
-
-
-/////////////////////////////////////////////////////////////////////////////////////
-//Rotation3d FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _rotation3d Elm_Fx_Rotation3d;
-static void _elm_fx_rotation3d_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_rotation3d_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_rotation3d_op(void *data, Elm_Animator *animator,
- double frame);
-
-struct _rotation3d
+struct _Elm_Transit_Effect_Rotation
{
- Evas_Object *obj;
- float from[3];
- float to[3];
- float axis_pos[3];
+ float from, to;
};
static void
-_elm_fx_rotation3d_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
-{
- Elm_Fx_Rotation3d *rotation = data;
- evas_object_show(rotation->obj);
-}
-
-static void
-_elm_fx_rotation3d_end(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+_transit_effect_rotation_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Rotation3d *rotation = data;
- evas_object_map_enable_set(rotation->obj, EINA_FALSE);
+ Elm_Transit_Effect_Rotation *rotation = effect;
+ free(rotation);
}
static void
-_elm_fx_rotation3d_op(void *data, Elm_Animator *animator, double frame)
+_transit_effect_rotation_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- Elm_Fx_Rotation3d *rotation;
-
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Elm_Transit_Effect_Rotation *rotation = effect;
Evas_Map *map;
-
Evas_Coord x, y, w, h;
-
- float degree[3];
-
+ float degree;
float half_w, half_h;
+ Eina_List *elist;
+ Evas_Object *obj;
map = evas_map_new(4);
- if (!map)
- return;
-
- rotation = data;
-
- evas_map_smooth_set(map, EINA_TRUE);
- evas_map_util_points_populate_from_object_full(map, rotation->obj, 0);
- degree[0] = rotation->from[0] + (float)(frame * rotation->to[0]);
- degree[1] = rotation->from[1] + (float)(frame * rotation->to[1]);
- degree[2] = rotation->from[2] + (float)(frame * rotation->to[2]);
+ if (!map) return;
- evas_object_geometry_get(rotation->obj, &x, &y, &w, &h);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ {
+ evas_map_util_points_populate_from_object_full(map, obj, 0);
+ degree = rotation->from + (float)(progress * rotation->to);
- half_w = (float)w *0.5;
+ evas_object_geometry_get(obj, &x, &y, &w, &h);
- half_h = (float)h *0.5;
+ half_w = (float)w * 0.5;
+ half_h = (float)h * 0.5;
- evas_map_util_3d_rotate(map, degree[0], degree[1], degree[2], rotation->axis_pos[0], rotation->axis_pos[1], rotation->axis_pos[2]);
- evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, 1000);
- evas_object_map_enable_set(rotation->obj, EINA_TRUE);
- evas_object_map_set(rotation->obj, map);
+ evas_map_util_rotate(map, degree, x + half_w, y + half_h);
+ evas_map_util_3d_perspective(map, x + half_w, y + half_h, 0, _TRANSIT_FOCAL);
+ evas_object_map_enable_set(obj, EINA_TRUE);
+ evas_object_map_set(obj, map);
+ }
evas_map_free(map);
}
-/**
- * Add Rotation3d effect
- *
- * @param[in] obj Evas_Object that effect is applying to
- * @param[in] from degree Degree when effect begins
- * @param[in] to_degree Degree when effect is ends
- * @param[in] axis_dir[3] rotation axis vector. it should be normalized.
- * @param[in] axis_pos[3] rotation axis origin position.
- * @param[in] cw Rotation direction. EINA_TRUE is clock wise
- * @return Rotation effect
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_rotation3d_add(Evas_Object *obj, float from_degree, float to_degree,
- float* axis_dir, float* axis_pos)
+static Elm_Transit_Effect *
+_transit_effect_rotation_context_new(float from_degree, float to_degree)
{
- Elm_Effect *effect;
+ Elm_Transit_Effect_Rotation *rotation;
- Elm_Fx_Rotation3d *rotation;
+ rotation = ELM_NEW(Elm_Transit_Effect_Rotation);
+ if (!rotation) return NULL;
- if (!obj)
- return NULL;
+ rotation->from = from_degree;
+ rotation->to = to_degree - from_degree;
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ return rotation;
+}
- rotation = calloc(1, sizeof(Elm_Fx_Rotation3d));
+EAPI Elm_Transit_Effect *
+elm_transit_effect_rotation_add(Elm_Transit *transit, float from_degree, float to_degree)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_rotation_context_new(from_degree, to_degree);
- if (!rotation)
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate rotation effect! : transit=%p", transit);
+ return NULL;
}
-
- rotation->obj = obj;
- rotation->from[0] = from_degree * axis_dir[0];
- rotation->from[1] = from_degree * axis_dir[1];
- rotation->from[2] = from_degree * axis_dir[2];
- rotation->to[0] = (to_degree * axis_dir[0]) - rotation->from[0];
- rotation->to[1] = (to_degree * axis_dir[1]) - rotation->from[1];
- rotation->to[2] = (to_degree * axis_dir[2]) - rotation->from[2];
- rotation->axis_pos[0] = axis_pos[0];
- rotation->axis_pos[1] = axis_pos[1];
- rotation->axis_pos[2] = axis_pos[2];
-
- effect->begin_op = _elm_fx_rotation3d_begin;
- effect->end_op = _elm_fx_rotation3d_end;
- effect->animation_op = _elm_fx_rotation3d_op;
- effect->user_data = rotation;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_rotation_op, effect,
+ _transit_effect_rotation_context_free);
return effect;
}
+///////////////////////////////////////////////////////////////////////////
+//ImageAnimation Effect
+///////////////////////////////////////////////////////////////////////////
+typedef struct _Elm_Transit_Effect_Image_Animation Elm_Transit_Effect_Image_Animation;
-
-/////////////////////////////////////////////////////////////////////////////////////
-// ImageAnimation FX
-/////////////////////////////////////////////////////////////////////////////////////
-typedef struct _image_animation Elm_Fx_Image_Animation;
-static void _elm_fx_image_animation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt);
-static void _elm_fx_image_animation_op(void *data, Elm_Animator *animator,
- double frame);
-EAPI Elm_Effect *elm_fx_image_animation_add(Evas_Object *obj, const char **images,
- unsigned int item_num);
-
-struct _image_animation
+struct _Elm_Transit_Effect_Image_Animation
{
- Evas_Object *obj;
- char **images;
- int img_cnt;
+ Eina_List *images;
};
-
static void
-_elm_fx_image_animation_begin(void *data, Eina_Bool auto_reverse,
- unsigned int repeat_cnt)
+_transit_effect_image_animation_context_free(Elm_Transit_Effect *effect, Elm_Transit *transit __UNUSED__)
{
- Elm_Fx_Image_Animation *image_animation = data;
- evas_object_show(image_animation->obj);
-}
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ Elm_Transit_Effect_Image_Animation *image_animation = effect;
+ const char *image;
+ Eina_List *elist, *elist_next;
+ EINA_LIST_FOREACH_SAFE(image_animation->images, elist, elist_next, image)
+ {
+ image_animation->images =
+ eina_list_remove_list(image_animation->images, elist);
+ eina_stringshare_del(image);
+ }
-static void
-_elm_fx_image_animation_op(void *data, Elm_Animator *animator, double frame)
-{
- Elm_Fx_Image_Animation *image_animation = (Elm_Fx_Image_Animation *) data;
-
- elm_icon_file_set(image_animation->obj,
- image_animation->images[ (int) floor(frame * (image_animation->img_cnt-1)) ], NULL);
+ free(image_animation);
}
static void
-_elm_fx_image_animation_del(void *data)
+_transit_effect_image_animation_op(Elm_Transit_Effect *effect, Elm_Transit *transit, double progress)
{
- int idx;
- Elm_Fx_Image_Animation *image_animation = data;
+ EINA_SAFETY_ON_NULL_RETURN(effect);
+ EINA_SAFETY_ON_NULL_RETURN(transit);
+ Eina_List *elist;
+ Evas_Object *obj;
+ const char *type;
+ Elm_Transit_Effect_Image_Animation *image_animation = effect;
+ unsigned int count = 0;
+ int len;
+
+ type = eina_stringshare_add("icon");
+ len = eina_list_count(image_animation->images);
- for(idx = 0; idx < image_animation->img_cnt; ++idx ) {
- eina_stringshare_del(image_animation->images[ idx ]);
- }
+ if (!len) count = floor(progress * len);
+ else count = floor(progress * (len - 1));
- free(image_animation->images);
+ EINA_LIST_FOREACH(transit->objs, elist, obj)
+ {
+ if (elm_widget_type_check(obj, type, __func__))
+ elm_icon_file_set(obj,
+ eina_list_nth(image_animation->images, count), NULL);
+ }
+
+ eina_stringshare_del(type);
}
-/**
- * Add image_animation effect.
- *
- * @param[in] obj Icon object
- * @param[in] images Array of image file path.
- * @param[in] img_cnt Count of image.
- * @return ImageAnimation effect.
- *
- * @ingroup Transit
- */
-EAPI Elm_Effect *
-elm_fx_image_animation_add(Evas_Object *obj, const char **images,
- unsigned int img_cnt)
+static Elm_Transit_Effect *
+_transit_effect_image_animation_context_new(Eina_List *images)
{
- Elm_Effect *effect;
- Elm_Fx_Image_Animation *image_animation;
- int idx;
-
- if ((!obj) || !images || !(*images))
- return NULL;
+ Elm_Transit_Effect_Image_Animation *image_animation;
+ image_animation = ELM_NEW(Elm_Transit_Effect_Image_Animation);
- effect = calloc(1, sizeof(Elm_Effect));
- if (!effect)
- return NULL;
+ if (!image_animation) return NULL;
+ image_animation->images = images;
+ return image_animation;
+}
- image_animation = calloc(1, sizeof(Elm_Fx_Image_Animation));
+EAPI Elm_Transit_Effect *
+elm_transit_effect_image_animation_add(Elm_Transit *transit, Eina_List *images)
+{
+ ELM_TRANSIT_CHECK_OR_RETURN(transit, NULL);
+ Elm_Transit_Effect *effect = _transit_effect_image_animation_context_new(images);
- if (!image_animation)
+ if (!effect)
{
- free(effect);
- return NULL;
+ ERR("Failed to allocate image_animation effect! : transit=%p", transit);
+ return NULL;
}
-
- image_animation->obj = obj;
- image_animation->images = calloc( img_cnt, sizeof(char*));
- for(idx = 0; idx < img_cnt; ++idx )
- image_animation->images[ idx ] = eina_stringshare_add( images[ idx ] );
-
- image_animation->img_cnt = img_cnt;
-
- effect->begin_op = _elm_fx_image_animation_begin;
- effect->animation_op = _elm_fx_image_animation_op;
- effect->del_op = _elm_fx_image_animation_del;
- effect->user_data = image_animation;
-
+ elm_transit_effect_add(transit,
+ _transit_effect_image_animation_op, effect,
+ _transit_effect_image_animation_context_free);
return effect;
}