Compare commits

...

2 Commits

Author SHA1 Message Date
Marcel Hollerbach dd75a89561 efl_ui_spotlight: Introduce animation manager
the manager is basically not new, its just the moved fade manager, with
a little bit more utilization. The manager now can be equipt with 3
animaton objects that are played when the correct reason happens.

For now the fade manager is the only thing that uses that.

Differential Revision: https://phab.enlightenment.org/D11358
2020-02-16 16:20:31 +01:00
Marcel Hollerbach 2267a07a8e efl_ui_spotlight_manager: introduce a reason for switch_to
This is preparation work for a later commit. This brings a flag that
indicates what the reason for a switch to call is, either a jump a push
or a pop.

Differential Revision: https://phab.enlightenment.org/D11357
2020-02-16 13:36:58 +01:00
12 changed files with 485 additions and 223 deletions

View File

@ -398,7 +398,7 @@ void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_stack(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_plain(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_scroll(void *data, Evas_Object *obj, void *event_info);
void test_ui_spotlight_animation(void *data, Evas_Object *obj, void *event_info);
void test_ui_relative_container(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_radio(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_collection_list(void *data, Evas_Object *obj, void *event_info);
@ -1173,6 +1173,7 @@ add_tests:
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Plain", test_ui_spotlight_plain);
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Scroll", test_ui_spotlight_scroll);
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Stack", test_ui_spotlight_stack);
ADD_TEST_EO(NULL, "Spotlight", "Efl.Ui.Spotlight Custom animation", test_ui_spotlight_animation);
ADD_TEST_EO(NULL, "Spotlight", "Navigation stack", test_ui_stack);
//------------------------------//
ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup);

View File

@ -1129,3 +1129,118 @@ test_ui_spotlight_scroll(void *data EINA_UNUSED,
efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
}
void
test_ui_spotlight_animation(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Eo *win, *panes, *navi, *list, *layout, *spotlight, *view, *custom_animation_manager;
Efl_Canvas_Animation *jump_animation, *push_animation, *pop_animation;
Params *params = NULL;
char buf[PATH_MAX];
int i;
win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(),
efl_text_set(efl_added, "Efl.Ui.Spotlight Scroll"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
panes = efl_add(EFL_UI_PANES_CLASS, win,
efl_gfx_hint_weight_set(efl_added, 1, 1),
efl_ui_panes_split_ratio_set(efl_added, 0.3),
efl_content_set(win, efl_added));
navi = elm_naviframe_add(panes);
evas_object_show(navi);
efl_content_set(efl_part(panes, "first"), navi);
list = elm_list_add(navi);
elm_list_horizontal_set(list, EINA_FALSE);
elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS);
elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL);
evas_object_show(list);
snprintf(buf, sizeof(buf), "%s/objects/test_pager.edj",
elm_app_data_dir_get());
layout = efl_add(EFL_UI_LAYOUT_CLASS, panes,
efl_file_set(efl_added, buf),
efl_file_key_set(efl_added, "pager"),
efl_file_load(efl_added),
efl_content_set(efl_part(panes, "second"), efl_added));
jump_animation = efl_new(EFL_CANVAS_ALPHA_ANIMATION_CLASS);
efl_animation_alpha_set(jump_animation, 0.0, 1.0);
efl_animation_duration_set(jump_animation, 0.5);
push_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
efl_animation_translate_set(push_animation, EINA_POSITION2D(0, 100), EINA_POSITION2D(0, 0));
efl_animation_duration_set(push_animation, 0.5);
pop_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
efl_animation_translate_set(pop_animation, EINA_POSITION2D(0, -100), EINA_POSITION2D(0, 0));
efl_animation_duration_set(pop_animation, 0.5);
custom_animation_manager = efl_new(EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS,
efl_ui_spotlight_manager_animation_push_setup_set(efl_added, push_animation),
efl_ui_spotlight_manager_animation_pop_setup_set(efl_added, pop_animation),
efl_ui_spotlight_manager_animation_jump_setup_set(efl_added, jump_animation, jump_animation));
spotlight = efl_add(EFL_UI_SPOTLIGHT_CONTAINER_CLASS, layout,
efl_ui_spotlight_manager_set(efl_added, custom_animation_manager),
efl_content_set(efl_part(layout, "pager"), efl_added),
efl_ui_spotlight_size_set(efl_added, EINA_SIZE2D(200, 300)));
efl_add(EFL_UI_BUTTON_CLASS, layout,
efl_text_set(efl_added, "Pop"),
efl_event_callback_add(efl_added,
EFL_INPUT_EVENT_CLICKED, pop_btn_cb, spotlight),
efl_content_set(efl_part(layout, "prev_btn"), efl_added));
efl_add(EFL_UI_BUTTON_CLASS, layout,
efl_text_set(efl_added, "Push"),
efl_event_callback_add(efl_added,
EFL_INPUT_EVENT_CLICKED, push_btn_cb, spotlight),
efl_content_set(efl_part(layout, "next_btn"), efl_added));
params = calloc(1, sizeof(Params));
if (!params) return;
params->navi = navi;
params->spotlight = spotlight;
params->indicator = NULL;
params->w = 200;
params->h = 300;
params->wfill = EINA_FALSE;
params->hfill = EINA_FALSE;
elm_list_item_append(list, "View Size", NULL, NULL, spotlight_size, params);
elm_list_item_append(list, "Pack / Unpack", NULL, NULL, pack_cb, params);
elm_list_item_append(list, "Active Index", NULL, NULL, active_index_cb, params);
elm_list_item_append(list, "Indicator", NULL, NULL, indicator_cb, params);
elm_list_item_append(list, "Animation", NULL, NULL, view_animation_cb, params);
elm_list_item_append(list, "Scroll Block", NULL, NULL, scroll_block_cb, params);
elm_list_go(list);
efl_event_callback_add(list, EFL_EVENT_DEL, list_del_cb, params);
for (i = 0; i < PAGE_NUM; i++) {
switch (i % 3)
{
case 0:
view = view_add(LAYOUT, spotlight);
break;
case 1:
view = view_add(LIST, spotlight);
break;
case 2:
view = view_add(BUTTON, spotlight);
break;
}
efl_pack_end(spotlight, view);
}
efl_gfx_entity_size_set(win, EINA_SIZE2D(580, 320));
}

View File

@ -269,6 +269,7 @@ typedef Eo Efl_Ui_Spotlight_Indicator;
# include <efl_ui_spotlight_icon_indicator.eo.h>
# include <efl_ui_spotlight_scroll_manager.eo.h>
# include <efl_ui_spotlight_fade_manager.eo.h>
# include <efl_ui_spotlight_animation_manager.eo.h>
# include <efl_ui_spotlight_util.eo.h>
# include <efl_ui_stack.eo.h>
# include <efl_ui_pager.eo.h>

View File

@ -0,0 +1,260 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Efl_Ui.h>
#include "elm_priv.h"
typedef struct {
Efl_Ui_Spotlight_Container * container;
Efl_Canvas_Animation *jump_anim[2], *push_anim, *pop_anim;
Efl_Gfx_Entity *content[2];
Efl_Gfx_Entity *clipper;
int ids[2]; //only used when in animation
Eina_Size2D page_size;
Eina_Bool animation;
} Efl_Ui_Spotlight_Animation_Manager_Data;
#define MY_CLASS EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS
static void
_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
{
Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->container);
Eina_Rect goal = EINA_RECT_EMPTY();
goal.size = pd->page_size;
goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
efl_gfx_entity_geometry_set(pd->clipper, group_pos);
for (int i = 0; i < 2; ++i)
{
if (pd->content[i])
efl_gfx_entity_geometry_set(pd->content[i], goal);
}
}
static void
_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Efl_Ui_Spotlight_Animation_Manager_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
double absolut_position;
EINA_SAFETY_ON_NULL_RETURN(pd);
//calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
absolut_position = pd->ids[0] + (pd->ids[1] - pd->ids[0])*(efl_canvas_object_animation_progress_get(ev->object));
efl_event_callback_call(data, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &absolut_position);
}
static void
_hide_object_cb(void *data, const Efl_Event *ev)
{
if (!ev->info)
{
efl_gfx_entity_visible_set(ev->object, EINA_FALSE);
efl_event_callback_del(ev->object, ev->desc, _hide_object_cb, data);
efl_event_callback_del(ev->object, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, data);
}
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_bind(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
{
if (spotlight)
{
pd->container = spotlight;
pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
evas_object_evas_get(pd->container));
evas_object_static_clip_set(pd->clipper, EINA_TRUE);
efl_canvas_group_member_add(spotlight, pd->clipper);
for (int i = 0; i < efl_content_count(spotlight) ; ++i) {
Efl_Gfx_Entity *elem = efl_pack_content_get(spotlight, i);
efl_key_data_set(elem, "_elm_leaveme", spotlight);
efl_canvas_object_clipper_set(elem, pd->clipper);
efl_canvas_group_member_add(pd->container, elem);
efl_gfx_entity_visible_set(elem, EINA_FALSE);
}
if (efl_ui_spotlight_active_element_get(spotlight))
{
pd->content[0] = efl_ui_spotlight_active_element_get(spotlight);
efl_gfx_entity_visible_set(pd->content[0], EINA_TRUE);
_geom_sync(obj, pd);
}
}
}
static void
_update_ids(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, int avoid_index)
{
for (int i = 0; i < 2; ++i)
{
if (pd->ids[i] != -1 && pd->ids[i] != avoid_index)
pd->ids[i] = efl_pack_index_get(pd->container, pd->content[i]);
}
double pos = pd->ids[1];
efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
{
efl_key_data_set(subobj, "_elm_leaveme", pd->container);
efl_canvas_object_clipper_set(subobj, pd->clipper);
efl_canvas_group_member_add(pd->container, subobj);
efl_gfx_entity_visible_set(subobj, EINA_FALSE);
_update_ids(obj, pd, -1);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index)
{
efl_key_data_set(subobj, "_elm_leaveme", NULL);
efl_canvas_object_clipper_set(subobj, NULL);
efl_canvas_group_member_remove(pd->container, subobj);
for (int i = 0; i < 2; ++i)
{
if (pd->content[i] == subobj)
pd->content[i] = NULL;
}
_update_ids(obj, pd, index);
}
static Eina_Bool
is_valid(Eo *obj, int index)
{
if (index < 0) return EINA_FALSE;
if (index >= efl_content_count(obj)) return EINA_FALSE;
return EINA_TRUE;
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd,
int from, int to,
Efl_Ui_Spotlight_Manager_Switch_Reason reason EINA_UNUSED)
{
if (efl_pack_content_get(pd->container, to) == pd->content[1])
return;
if (is_valid(pd->container, to) && is_valid(pd->container, from))
{
int tmp[2] = {from, to};
for (int i = 0; i < 2; ++i)
{
Efl_Canvas_Animation *animation = NULL;
pd->ids[i] = tmp[i];
pd->content[i] = efl_pack_content_get(pd->container, pd->ids[i]);
//when pushing, animate the *pushed in* content with the push animation
if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_PUSH && i == 1)
animation = pd->push_anim;
//when popping, animate the *popped in* content with the pop animation
else if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_POP && i == 0)
animation = pd->pop_anim;
if (!animation)
animation = pd->jump_anim[i];
if (pd->animation)
efl_canvas_object_animation_start(pd->content[i], animation, -1.0+2.0*i, 0.0);
efl_gfx_entity_visible_set(pd->content[i], EINA_TRUE);
}
if (pd->animation)
{
efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _hide_object_cb, obj);
efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, obj);
efl_gfx_stack_above(pd->content[1], pd->content[0]); //Stack the "to content" above the "from content"
}
}
else
{
double pos = to;
pd->ids[0] = -1;
pd->content[0] = NULL;
pd->ids[1] = to;
pd->content[1] = efl_pack_content_get(pd->container, to);
efl_gfx_entity_visible_set(pd->content[1], EINA_TRUE);
efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
}
_geom_sync(obj, pd);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_size_set(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Eina_Size2D size)
{
pd->page_size = size;
_geom_sync(obj, pd);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_object_invalidate(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
{
efl_invalidate(efl_super(obj, MY_CLASS));
efl_del(pd->clipper);
for (int i = 0; i < efl_content_count(pd->container); ++i)
{
Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
for (int d = 0; d < 4; d++)
{
efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
}
efl_canvas_object_clipper_set(elem, NULL);
}
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_animated_transition_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Eina_Bool animation)
{
for (int i = 0; i < 2; ++i)
{
if (pd->content[i])
efl_canvas_object_animation_stop(pd->content[i]);
}
pd->animation = animation;
}
EOLIAN static Eina_Bool
_efl_ui_spotlight_animation_manager_efl_ui_spotlight_manager_animated_transition_get(const Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
{
return pd->animation;
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_push_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *animation)
{
efl_replace(&pd->push_anim, animation);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_pop_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *animation)
{
efl_replace(&pd->pop_anim, animation);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_jump_setup_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Animation_Manager_Data *pd, Efl_Canvas_Animation *in, Efl_Canvas_Animation *out)
{
EINA_SAFETY_ON_NULL_RETURN(out);
EINA_SAFETY_ON_NULL_RETURN(in);
efl_replace(&pd->jump_anim[0], out);
efl_replace(&pd->jump_anim[1], in);
}
EOLIAN static Efl_Object*
_efl_ui_spotlight_animation_manager_efl_object_finalize(Eo *obj, Efl_Ui_Spotlight_Animation_Manager_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->jump_anim[0], NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->jump_anim[1], NULL);
return efl_finalize(efl_super(obj, MY_CLASS));
}
#include "efl_ui_spotlight_animation_manager.eo.c"

View File

@ -0,0 +1,66 @@
class @beta Efl.Ui.Spotlight.Animation_Manager extends Efl.Ui.Spotlight.Manager
{
[[A spotlight manager that uses animation objects to react to different @Efl.Ui.Spotlight.Manager.switch_to situations.
Animations are played forward when they are on the $to argument, they are played backward when they are on the $from argument.
Pop animations are always played backwards, Push animations are always played forward.
Reason for this is, the reusability. You should be able to pass in 1 animation to all sitatuations, which should cover the turn arround effect that "moving in" and "moving out" has. This means, when you have a alpha channel animation, the pop animation can be the same as the jump-in and out animation, and both will look like fading out.
]]
c_prefix: efl_ui_spotlight_manager_animation;
methods {
@property push_setup{
[[Animation that is used to animate the $to argument of a switch_to request when the passed $reason is push.
If this animation is $null, the in animation of @.jump_setup will be taken instead.
]]
values {
animation : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
}
set { }
}
@property pop_setup{
[[Animation that is used to animate the $from argument of a switch_to request when the passed $reason is pop.
Note: this animations is always played backwards, see the class documentation for the reasoning.
If this animation is $null, the out animation of @.jump_setup will be taken instead.
]]
values {
animation : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
}
set { }
}
@property jump_setup{
[[Set the animation objects you want to play on a jump in or jump out.
When a switch to request is issued, two arguments are getting animated. The $from object, and the $to objects. The $from object will be playing the out animation. The $pop object will be playing the in animation.
The out animation will always be played backwards, this is to support passing the same animation object to both parameters. (A fade animation will fade in the new object, and fade out the old object).
]]
values {
jump_in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
jump_out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
}
set {
}
}
}
constructors {
.jump_setup;
}
implements {
Efl.Ui.Spotlight.Manager.bind;
Efl.Ui.Spotlight.Manager.content_add;
Efl.Ui.Spotlight.Manager.content_del;
Efl.Ui.Spotlight.Manager.switch_to;
Efl.Ui.Spotlight.Manager.size {set;}
Efl.Ui.Spotlight.Manager.animated_transition {set; get;}
Efl.Object.finalize;
Efl.Object.invalidate;
}
}

View File

@ -437,10 +437,8 @@ _efl_ui_spotlight_container_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
return eina_list_data_idx(pd->content_list, (void *)subobj);
}
EOLIAN static void
_efl_ui_spotlight_container_active_element_set(Eo *obj EINA_UNUSED,
Efl_Ui_Spotlight_Container_Data *pd,
Efl_Ui_Widget *new_page)
static void
_active_element_set(Eo *obj, Efl_Ui_Spotlight_Container_Data *pd, Efl_Ui_Widget *new_page, Efl_Ui_Spotlight_Manager_Switch_Reason reason)
{
int before = -1;
int index;
@ -463,7 +461,16 @@ _efl_ui_spotlight_container_active_element_set(Eo *obj EINA_UNUSED,
}
pd->curr.page = new_page;
efl_ui_spotlight_manager_switch_to(pd->transition, before, index);
efl_ui_spotlight_manager_switch_to(pd->transition, before, index, reason);
}
EOLIAN static void
_efl_ui_spotlight_container_active_element_set(Eo *obj EINA_UNUSED,
Efl_Ui_Spotlight_Container_Data *pd,
Efl_Ui_Widget *new_page)
{
_active_element_set(obj, pd, new_page, EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_JUMP);
}
EOLIAN static Efl_Ui_Widget*
@ -724,8 +731,7 @@ _efl_ui_spotlight_container_push(Eo *obj, Efl_Ui_Spotlight_Container_Data *pd EI
if (!efl_pack_end(obj, view))
return;
}
efl_ui_spotlight_active_element_set(obj, view);
_active_element_set(obj, pd, view, EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_PUSH);
}
static Eina_Value
@ -780,7 +786,7 @@ _efl_ui_spotlight_container_pop(Eo *obj, Efl_Ui_Spotlight_Container_Data *pd, Ei
if (del)
transition_done = eina_future_then(transition_done, _delete_obj, NULL);
efl_ui_spotlight_active_element_set(obj, efl_pack_content_get(obj, new_index));
_active_element_set(obj, pd, efl_pack_content_get(obj, new_index), EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_POP);
return transition_done;
}

View File

@ -5,216 +5,25 @@
#include <Efl_Ui.h>
#include "elm_priv.h"
typedef struct {
Efl_Ui_Spotlight_Container * container;
Efl_Canvas_Animation *alpha_anim;
Efl_Gfx_Entity *content[2];
Efl_Gfx_Entity *clipper;
int ids[2]; //only used when in animation
Eina_Size2D page_size;
Eina_Bool animation;
} Efl_Ui_Spotlight_Fade_Manager_Data;
#define MY_CLASS EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS
static void
_geom_sync(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
EOLIAN static Efl_Object*
_efl_ui_spotlight_fade_manager_efl_object_constructor(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd EINA_UNUSED)
{
Eina_Rect group_pos = efl_gfx_entity_geometry_get(pd->container);
Eina_Rect goal = EINA_RECT_EMPTY();
goal.size = pd->page_size;
goal.y = (group_pos.y + group_pos.h/2)-pd->page_size.h/2;
goal.x = (group_pos.x + group_pos.w/2)-pd->page_size.w/2;
efl_gfx_entity_geometry_set(pd->clipper, goal);
for (int i = 0; i < 2; ++i)
{
if (pd->content[i])
efl_gfx_entity_geometry_set(pd->content[i], goal);
}
}
Efl_Canvas_Animation *animation;
static void
_running_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Efl_Ui_Spotlight_Fade_Manager_Data *pd = efl_data_scope_safe_get(data, MY_CLASS);
double absolut_position;
obj = efl_constructor(efl_super(obj, EFL_UI_SPOTLIGHT_FADE_MANAGER_CLASS));
EINA_SAFETY_ON_NULL_RETURN(pd);
//calculate absolut position, multiply pos with 2.0 because duration is only 0.5)
absolut_position = pd->ids[0] + (pd->ids[1] - pd->ids[0])*(efl_canvas_object_animation_progress_get(ev->object));
efl_event_callback_call(data, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &absolut_position);
}
animation = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
efl_animation_alpha_set(animation, 0.0, 1.0);
efl_animation_duration_set(animation, 0.5);
static void
_hide_object_cb(void *data, const Efl_Event *ev)
{
if (!ev->info)
{
efl_gfx_entity_visible_set(ev->object, EINA_FALSE);
efl_event_callback_del(ev->object, ev->desc, _hide_object_cb, data);
efl_event_callback_del(ev->object, EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, data);
}
}
efl_ui_spotlight_manager_animation_jump_setup_set(obj, animation, animation);
efl_unref(animation);
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_bind(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Ui_Spotlight_Container *spotlight)
{
if (spotlight)
{
pd->container = spotlight;
pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS,
evas_object_evas_get(pd->container));
evas_object_static_clip_set(pd->clipper, EINA_TRUE);
efl_canvas_group_member_add(spotlight, pd->clipper);
pd->alpha_anim = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
efl_animation_alpha_set(pd->alpha_anim, 0.0, 1.0);
efl_animation_duration_set(pd->alpha_anim, 0.5);
for (int i = 0; i < efl_content_count(spotlight) ; ++i) {
Efl_Gfx_Entity *elem = efl_pack_content_get(spotlight, i);
efl_key_data_set(elem, "_elm_leaveme", spotlight);
efl_canvas_object_clipper_set(elem, pd->clipper);
efl_canvas_group_member_add(pd->container, elem);
efl_gfx_entity_visible_set(elem, EINA_FALSE);
}
if (efl_ui_spotlight_active_element_get(spotlight))
{
pd->content[0] = efl_ui_spotlight_active_element_get(spotlight);
efl_gfx_entity_visible_set(pd->content[0], EINA_TRUE);
_geom_sync(obj, pd);
}
}
}
static void
_update_ids(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, int avoid_index)
{
for (int i = 0; i < 2; ++i)
{
if (pd->ids[i] != -1 && pd->ids[i] != avoid_index)
pd->ids[i] = efl_pack_index_get(pd->container, pd->content[i]);
}
double pos = pd->ids[1];
efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_content_add(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index EINA_UNUSED)
{
efl_key_data_set(subobj, "_elm_leaveme", pd->container);
efl_canvas_object_clipper_set(subobj, pd->clipper);
efl_canvas_group_member_add(pd->container, subobj);
efl_gfx_entity_visible_set(subobj, EINA_FALSE);
_update_ids(obj, pd, -1);
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_content_del(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Efl_Gfx_Entity *subobj, int index)
{
efl_key_data_set(subobj, "_elm_leaveme", NULL);
efl_canvas_object_clipper_set(subobj, NULL);
efl_canvas_group_member_remove(pd->container, subobj);
for (int i = 0; i < 2; ++i)
{
if (pd->content[i] == subobj)
pd->content[i] = NULL;
}
_update_ids(obj, pd, index);
}
static Eina_Bool
is_valid(Eo *obj, int index)
{
if (index < 0) return EINA_FALSE;
if (index >= efl_content_count(obj)) return EINA_FALSE;
return EINA_TRUE;
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, int from, int to)
{
if (efl_pack_content_get(pd->container, to) == pd->content[1])
return;
if (is_valid(pd->container, to) && is_valid(pd->container, from))
{
int tmp[2] = {from, to};
for (int i = 0; i < 2; ++i)
{
pd->ids[i] = tmp[i];
pd->content[i] = efl_pack_content_get(pd->container, pd->ids[i]);
if (pd->animation)
efl_canvas_object_animation_start(pd->content[i], pd->alpha_anim, -1.0+2.0*i, 0.0);
efl_gfx_entity_visible_set(pd->content[i], EINA_TRUE);
}
if (pd->animation)
{
efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_CHANGED, _hide_object_cb, obj);
efl_event_callback_add(pd->content[0], EFL_CANVAS_OBJECT_ANIMATION_EVENT_ANIMATION_PROGRESS_UPDATED, _running_cb, obj);
efl_gfx_stack_above(pd->content[1], pd->content[0]); //Stack the "to content" above the "from content"
}
}
else
{
double pos = to;
pd->ids[0] = -1;
pd->content[0] = NULL;
pd->ids[1] = to;
pd->content[1] = efl_pack_content_get(pd->container, to);
efl_gfx_entity_visible_set(pd->content[1], EINA_TRUE);
efl_event_callback_call(obj, EFL_UI_SPOTLIGHT_MANAGER_EVENT_POS_UPDATE, &pos);
}
_geom_sync(obj, pd);
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_size_set(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Eina_Size2D size)
{
pd->page_size = size;
_geom_sync(obj, pd);
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_object_invalidate(Eo *obj, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
{
efl_invalidate(efl_super(obj, MY_CLASS));
efl_del(pd->clipper);
for (int i = 0; i < efl_content_count(pd->container); ++i)
{
Efl_Gfx_Stack *elem = efl_pack_content_get(pd->container, i);
for (int d = 0; d < 4; d++)
{
efl_gfx_mapping_color_set(elem, d, 255, 255, 255, 255);
}
efl_canvas_object_clipper_set(elem, NULL);
}
}
EOLIAN static void
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_animated_transition_set(Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd, Eina_Bool animation)
{
for (int i = 0; i < 2; ++i)
{
if (pd->content[i])
efl_canvas_object_animation_stop(pd->content[i]);
}
pd->animation = animation;
}
EOLIAN static Eina_Bool
_efl_ui_spotlight_fade_manager_efl_ui_spotlight_manager_animated_transition_get(const Eo *obj EINA_UNUSED, Efl_Ui_Spotlight_Fade_Manager_Data *pd)
{
return pd->animation;
return obj;
}

View File

@ -1,13 +1,7 @@
class @beta Efl.Ui.Spotlight.Fade_Manager extends Efl.Ui.Spotlight.Manager
class @beta Efl.Ui.Spotlight.Fade_Manager extends Efl.Ui.Spotlight.Animation_Manager
{
c_prefix: efl_ui_spotlight_manager_fade;
implements {
Efl.Ui.Spotlight.Manager.bind;
Efl.Ui.Spotlight.Manager.content_add;
Efl.Ui.Spotlight.Manager.content_del;
Efl.Ui.Spotlight.Manager.switch_to;
Efl.Ui.Spotlight.Manager.size {set;}
Efl.Ui.Spotlight.Manager.animated_transition {set; get;}
Efl.Object.invalidate;
Efl.Object.constructor;
}
}

View File

@ -1,3 +1,10 @@
enum @beta Efl.Ui.Spotlight.Manager_Switch_Reason {
[[Indicator for the reason of a @Efl.Ui.Spotlight.Manager.switch_to call]]
jump, [[The Reason for this switch is a casual jump caused by @Efl.Ui.Spotlight.Container.active_element]]
push, [[The Reason for this switch is a casual jump caused by @Efl.Ui.Spotlight.Container.push]]
pop [[The Reason for this switch is a casual jump caused by @Efl.Ui.Spotlight.Container.pop]]
}
abstract @beta Efl.Ui.Spotlight.Manager extends Efl.Object {
[[Manager object used by @Efl.Ui.Spotlight.Container to handle rendering and animation of its sub-widgets,
and user interaction.
@ -41,6 +48,7 @@ abstract @beta Efl.Ui.Spotlight.Manager extends Efl.Object {
params {
from : int; [[Index of the starting sub-widget in the container's list. Might be -1 if unknown.]]
to : int; [[Index of the target sub-widget in the container's list.]]
reason : Efl.Ui.Spotlight.Manager_Switch_Reason; [[The reason for this switch to call]]
}
}
@property size @pure_virtual {

View File

@ -108,7 +108,7 @@ _efl_ui_spotlight_plain_manager_efl_ui_spotlight_manager_content_del(Eo *obj, Ef
_content_changed(obj, pd);
}
EOLIAN static void
_efl_ui_spotlight_plain_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Plain_Manager_Data *pd, int from EINA_UNUSED, int to)
_efl_ui_spotlight_plain_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Plain_Manager_Data *pd, int from EINA_UNUSED, int to, Efl_Ui_Spotlight_Manager_Switch_Reason reason EINA_UNUSED)
{
Efl_Gfx_Entity *to_obj, *from_obj;
to_obj = efl_pack_content_get(pd->container, to);

View File

@ -276,7 +276,7 @@ _animation_request_switch(Eo *obj, Efl_Ui_Spotlight_Scroll_Manager_Data *pd, int
}
EOLIAN static void
_efl_ui_spotlight_scroll_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Scroll_Manager_Data *pd, int from, int to)
_efl_ui_spotlight_scroll_manager_efl_ui_spotlight_manager_switch_to(Eo *obj, Efl_Ui_Spotlight_Scroll_Manager_Data *pd, int from, int to, Efl_Ui_Spotlight_Manager_Switch_Reason reason EINA_UNUSED)
{
if (pd->animation)
{

View File

@ -189,7 +189,8 @@ pub_eo_files = [
'efl_ui_grid_view.eo',
'efl_ui_pager.eo',
'efl_ui_stack.eo',
'efl_ui_separator.eo'
'efl_ui_separator.eo',
'efl_ui_spotlight_animation_manager.eo',
]
foreach eo_file : pub_eo_files
@ -947,7 +948,8 @@ elementary_src = [
'efl_ui_collection_view.c',
'efl_ui_pager.c',
'efl_ui_stack.c',
'efl_ui_separator.c'
'efl_ui_separator.c',
'efl_ui_spotlight_animation_manager.c',
]
elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, dl, intl]