Compare commits

...

3 Commits

Author SHA1 Message Date
Jaehyun Cho 72da9ec8c6 efl_ui_spotlight: Introduce forward and backward animations
forward_animation and backward_animation are introduced instead of
push_setup, pop_setup, and jump_setup.

forward_animation is started when active element is changed from lower
index to higher index. This includes push() case.
e.g. current active index is 0 and new active index becomes 1.

backward_animation is started when active element is changed from higher
index to lower index. This includes pop() case.
e.g. current active index is 1 and new active index becomes 0.
2020-03-11 13:21:20 +09:00
Marcel Hollerbach 6fd2435c9e efl_ui_spotlight: Introduce animation manager
Summary:
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.
Depends on D11357

Reviewers: Jaehyun_Cho, zmike, segfaultxavi

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D11358
2020-03-11 12:10:09 +09: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 483 additions and 222 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,121 @@ 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 *forward_in_animation, *forward_out_animation;
Efl_Canvas_Animation *backward_in_animation, *backward_out_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));
forward_in_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
efl_animation_translate_set(forward_in_animation, EINA_POSITION2D(0, 100), EINA_POSITION2D(0, 0));
efl_animation_duration_set(forward_in_animation, 0.5);
forward_out_animation = efl_new(EFL_CANVAS_ALPHA_ANIMATION_CLASS);
efl_animation_alpha_set(forward_out_animation, 1.0, 0.0);
efl_animation_duration_set(forward_out_animation, 0.5);
backward_in_animation = efl_new(EFL_CANVAS_ALPHA_ANIMATION_CLASS);
efl_animation_alpha_set(backward_in_animation, 0.0, 1.0);
efl_animation_duration_set(backward_in_animation, 0.5);
backward_out_animation = efl_new(EFL_CANVAS_TRANSLATE_ANIMATION_CLASS);
efl_animation_translate_set(backward_out_animation, EINA_POSITION2D(0, 0), EINA_POSITION2D(0, 100));
efl_animation_duration_set(backward_out_animation, 0.5);
custom_animation_manager = efl_new(EFL_UI_SPOTLIGHT_ANIMATION_MANAGER_CLASS,
efl_ui_spotlight_manager_animation_forward_animation_set(efl_added, forward_in_animation, forward_out_animation),
efl_ui_spotlight_manager_animation_backward_animation_set(efl_added, backward_in_animation, backward_out_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,265 @@
#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 *forward_anim[2], *backward_anim[2];
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* content with the forward animation
if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_PUSH)
animation = pd->forward_anim[i];
//when popping, animate the *popped* content with the backward animation
else if (reason == EFL_UI_SPOTLIGHT_MANAGER_SWITCH_REASON_POP)
animation = pd->backward_anim[i];
if (!animation)
{
if (to > from)
animation = pd->forward_anim[i];
else
animation = pd->backward_anim[i];
}
if (pd->animation)
efl_canvas_object_animation_start(pd->content[i], animation, 1.0, 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_forward_animation_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->forward_anim[0], out);
efl_replace(&pd->forward_anim[1], in);
}
EOLIAN static void
_efl_ui_spotlight_animation_manager_backward_animation_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->backward_anim[0], out);
efl_replace(&pd->backward_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->forward_anim[0], NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->forward_anim[1], NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->backward_anim[0], NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->backward_anim[1], NULL);
return efl_finalize(efl_super(obj, MY_CLASS));
}
#include "efl_ui_spotlight_animation_manager.eo.c"

View File

@ -0,0 +1,51 @@
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 forward_animation {
[[Set the animation objects you want to play on going forward. (going from lower index page to higher index page)
]]
values {
in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
}
set {
}
}
@property backward_animation {
[[Set the animation objects you want to play on going backward. (going from higher index page to lower index page)
]]
values {
in : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference]]
out : Efl.Canvas.Animation; [[The animation to play, the implementation will take an additional reference. Can be the same as $in.]]
}
set {
}
}
}
constructors {
.forward_animation;
.backward_animation;
}
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,31 @@
#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 *in_animation, *out_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);
}
in_animation = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
efl_animation_alpha_set(in_animation, 0.0, 1.0);
efl_animation_duration_set(in_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);
}
}
out_animation = efl_add(EFL_CANVAS_ALPHA_ANIMATION_CLASS, obj);
efl_animation_alpha_set(out_animation, 0.0, 1.0);
efl_animation_duration_set(out_animation, 0.5);
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;
efl_ui_spotlight_manager_animation_forward_animation_set(obj, in_animation, out_animation);
efl_ui_spotlight_manager_animation_backward_animation_set(obj, in_animation, out_animation);
efl_unref(in_animation);
efl_unref(out_animation);
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]