forked from enlightenment/efl
efl_ui_stack: Add Efl.Ui.Stack class
Efl.Ui.Stack is a container arranges objects in stack structure by pushing and popping them.
This commit is contained in:
parent
e3315baaa3
commit
ab4fa83f62
|
@ -11,6 +11,7 @@ elm_public_eolian_files = \
|
||||||
lib/elementary/efl_ui_check.eo \
|
lib/elementary/efl_ui_check.eo \
|
||||||
lib/elementary/efl_ui_flip.eo \
|
lib/elementary/efl_ui_flip.eo \
|
||||||
lib/elementary/efl_ui_frame.eo \
|
lib/elementary/efl_ui_frame.eo \
|
||||||
|
lib/elementary/efl_ui_stack.eo \
|
||||||
lib/elementary/efl_ui_image.eo \
|
lib/elementary/efl_ui_image.eo \
|
||||||
lib/elementary/efl_ui_image_zoomable.eo \
|
lib/elementary/efl_ui_image_zoomable.eo \
|
||||||
lib/elementary/efl_ui_layout.eo \
|
lib/elementary/efl_ui_layout.eo \
|
||||||
|
@ -326,6 +327,7 @@ includesunstable_HEADERS = \
|
||||||
lib/elementary/efl_ui_widget_flip.h \
|
lib/elementary/efl_ui_widget_flip.h \
|
||||||
lib/elementary/elm_widget_flipselector.h \
|
lib/elementary/elm_widget_flipselector.h \
|
||||||
lib/elementary/efl_ui_widget_frame.h \
|
lib/elementary/efl_ui_widget_frame.h \
|
||||||
|
lib/elementary/efl_ui_stack_private.h \
|
||||||
lib/elementary/elm_widget_gengrid.h \
|
lib/elementary/elm_widget_gengrid.h \
|
||||||
lib/elementary/elm_widget_genlist.h \
|
lib/elementary/elm_widget_genlist.h \
|
||||||
lib/elementary/elm_widget_glview.h \
|
lib/elementary/elm_widget_glview.h \
|
||||||
|
@ -668,6 +670,7 @@ lib_elementary_libelementary_la_SOURCES = \
|
||||||
lib/elementary/elm_flipselector.c \
|
lib/elementary/elm_flipselector.c \
|
||||||
lib/elementary/elm_font.c \
|
lib/elementary/elm_font.c \
|
||||||
lib/elementary/efl_ui_frame.c \
|
lib/elementary/efl_ui_frame.c \
|
||||||
|
lib/elementary/efl_ui_stack.c \
|
||||||
lib/elementary/elm_gengrid.c \
|
lib/elementary/elm_gengrid.c \
|
||||||
lib/elementary/elm_genlist.c \
|
lib/elementary/elm_genlist.c \
|
||||||
lib/elementary/elm_gesture_layer.c \
|
lib/elementary/elm_gesture_layer.c \
|
||||||
|
|
|
@ -336,6 +336,7 @@ typedef Eo Efl_Ui_Focus_Manager;
|
||||||
# include <efl_selection.eo.h>
|
# include <efl_selection.eo.h>
|
||||||
# include <efl_ui_dnd.eo.h>
|
# include <efl_ui_dnd.eo.h>
|
||||||
# include <efl_ui_dnd_container.eo.h>
|
# include <efl_ui_dnd_container.eo.h>
|
||||||
|
# include <efl_ui_stack.eo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* include deprecated calls last of all */
|
/* include deprecated calls last of all */
|
||||||
|
|
|
@ -0,0 +1,972 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "elementary_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Elementary.h>
|
||||||
|
|
||||||
|
#include "elm_priv.h"
|
||||||
|
#include "efl_ui_stack_private.h"
|
||||||
|
|
||||||
|
#define MY_CLASS EFL_UI_STACK_CLASS
|
||||||
|
#define MY_CLASS_NAME "Efl.Ui.Stack"
|
||||||
|
|
||||||
|
static Efl_Canvas_Animation *show_anim = NULL;
|
||||||
|
static Efl_Canvas_Animation *hide_anim = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_content_del_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Content_Data *cd = data;
|
||||||
|
|
||||||
|
//Popped content has already called deactivated event and unloaded event.
|
||||||
|
if (cd->popped_hidden) return;
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = cd->content;
|
||||||
|
efl_event_callback_call(cd->stack,
|
||||||
|
EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = cd->content;
|
||||||
|
efl_event_callback_call(cd->stack,
|
||||||
|
EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Content_Data *
|
||||||
|
_content_data_new(Eo *obj, Eo *content)
|
||||||
|
{
|
||||||
|
Content_Data *cd = calloc(1, sizeof(Content_Data));
|
||||||
|
if (!cd)
|
||||||
|
{
|
||||||
|
ERR("Memory allocation error!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cd->stack = obj;
|
||||||
|
cd->content = content;
|
||||||
|
|
||||||
|
efl_event_callback_add(cd->content, EFL_EVENT_DEL, _content_del_cb, cd);
|
||||||
|
|
||||||
|
return cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_content_data_del(Content_Data *cd)
|
||||||
|
{
|
||||||
|
if (!cd) return;
|
||||||
|
|
||||||
|
if (cd->content)
|
||||||
|
efl_del(cd->content);
|
||||||
|
|
||||||
|
free(cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anim_started_cb(void *data EINA_UNUSED, const Efl_Event *event)
|
||||||
|
{
|
||||||
|
efl_canvas_object_freeze_events_set(event->object, EINA_TRUE);
|
||||||
|
|
||||||
|
efl_event_callback_del(event->object, EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
||||||
|
_anim_started_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_anim_ended_cb(void *data, const Efl_Event *event)
|
||||||
|
{
|
||||||
|
Transit_Data *td = data;
|
||||||
|
Efl_Canvas_Object_Animation_Event_Info *anim_event = event->info;
|
||||||
|
|
||||||
|
//Unset animation because originally there is no animation.
|
||||||
|
if (!td->orig_anim)
|
||||||
|
efl_canvas_object_event_animation_set(event->object,
|
||||||
|
anim_event->event_type, NULL);
|
||||||
|
|
||||||
|
efl_canvas_object_freeze_events_set(event->object,
|
||||||
|
td->freeze_events);
|
||||||
|
|
||||||
|
td->cd->on_pushing = EINA_FALSE;
|
||||||
|
td->cd->on_popping = EINA_FALSE;
|
||||||
|
|
||||||
|
if (anim_event->event_type == EFL_GFX_EVENT_SHOW)
|
||||||
|
{
|
||||||
|
//Activated Event
|
||||||
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
|
activated_info.content = event->object;
|
||||||
|
efl_event_callback_call(td->cd->stack,
|
||||||
|
EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
|
&activated_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = event->object;
|
||||||
|
efl_event_callback_call(td->cd->stack,
|
||||||
|
EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = event->object;
|
||||||
|
efl_event_callback_call(td->cd->stack,
|
||||||
|
EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
efl_event_callback_del(event->object, EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED,
|
||||||
|
_anim_ended_cb, data);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_push(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content)
|
||||||
|
{
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
//If the given content exists in the stack, promote the given content to the top.
|
||||||
|
Content_Data *cd = NULL;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, cd)
|
||||||
|
if (cd->content == content)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Content_Data *top_cd = NULL;
|
||||||
|
if (pd->stack)
|
||||||
|
top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
|
||||||
|
|
||||||
|
if (cd)
|
||||||
|
{
|
||||||
|
//If given content is already the top content, then do nothing.
|
||||||
|
if (cd == top_cd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
//Remove the given content(existing content) to promote it to the top.
|
||||||
|
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cd = _content_data_new(obj, content);
|
||||||
|
if (!cd) return;
|
||||||
|
|
||||||
|
evas_object_smart_member_add(content, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_append(pd->stack, EINA_INLIST_GET(cd));
|
||||||
|
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED, &loaded_info);
|
||||||
|
|
||||||
|
/* Apply transition to top content.
|
||||||
|
* Hide top content with animation. */
|
||||||
|
if (top_cd)
|
||||||
|
{
|
||||||
|
Eo *top_content = top_cd->content;
|
||||||
|
|
||||||
|
Efl_Canvas_Animation *orig_hide_anim =
|
||||||
|
efl_canvas_object_event_animation_get(top_content, EFL_GFX_EVENT_HIDE);
|
||||||
|
|
||||||
|
/* If content is being pushed now, then finish current animation and hide
|
||||||
|
* the content without animation. */
|
||||||
|
if (top_cd->on_pushing)
|
||||||
|
{
|
||||||
|
//Finish current animation.
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_SHOW, NULL);
|
||||||
|
|
||||||
|
//Hide without animation.
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE, NULL);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(top_content, EINA_FALSE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
orig_hide_anim);
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = top_content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = top_content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top_cd->on_pushing = EINA_TRUE;
|
||||||
|
|
||||||
|
//Hide with animation.
|
||||||
|
if (!orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
hide_anim);
|
||||||
|
|
||||||
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
|
td->cd = top_cd;
|
||||||
|
td->orig_anim = !!(orig_hide_anim);
|
||||||
|
td->freeze_events = efl_canvas_object_freeze_events_get(top_content);
|
||||||
|
|
||||||
|
efl_event_callback_add(top_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
||||||
|
_anim_started_cb, NULL);
|
||||||
|
efl_event_callback_add(top_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED,
|
||||||
|
_anim_ended_cb, td);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(top_content, EINA_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare transition for new content.
|
||||||
|
* Hide new content without animation. */
|
||||||
|
{
|
||||||
|
cd->on_pushing = EINA_TRUE;
|
||||||
|
|
||||||
|
Efl_Canvas_Animation *orig_hide_anim =
|
||||||
|
efl_canvas_object_event_animation_get(content, EFL_GFX_EVENT_HIDE);
|
||||||
|
|
||||||
|
//Hide without animation.
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_HIDE, NULL);
|
||||||
|
efl_gfx_visible_set(content, EINA_FALSE);
|
||||||
|
|
||||||
|
//Restore original hide animation
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_HIDE,
|
||||||
|
orig_hide_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply transition to new content.
|
||||||
|
* Show new content with animation. */
|
||||||
|
{
|
||||||
|
evas_object_raise(content);
|
||||||
|
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(content, EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
//Show with animation
|
||||||
|
if (!orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_SHOW,
|
||||||
|
show_anim);
|
||||||
|
|
||||||
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
|
td->cd = cd;
|
||||||
|
td->orig_anim = !!(orig_show_anim);
|
||||||
|
td->freeze_events = efl_canvas_object_freeze_events_get(content);
|
||||||
|
|
||||||
|
efl_event_callback_add(content, EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
||||||
|
_anim_started_cb, NULL);
|
||||||
|
efl_event_callback_add(content, EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED,
|
||||||
|
_anim_ended_cb, td);
|
||||||
|
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_pop_content_hide_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Content_Data *cd = data;
|
||||||
|
|
||||||
|
cd->popped_hidden = EINA_TRUE;
|
||||||
|
|
||||||
|
_content_data_del(cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eo *
|
||||||
|
_efl_ui_stack_pop(Eo *obj, Efl_Ui_Stack_Data *pd)
|
||||||
|
{
|
||||||
|
if (!pd->stack)
|
||||||
|
{
|
||||||
|
ERR("There is no content in the stack!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
|
||||||
|
if (!top_cd) return NULL;
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(top_cd));
|
||||||
|
|
||||||
|
/* Apply transition to top content.
|
||||||
|
* Hide top content with animation. */
|
||||||
|
{
|
||||||
|
Eo *top_content = top_cd->content;
|
||||||
|
|
||||||
|
Efl_Canvas_Animation *orig_hide_anim =
|
||||||
|
efl_canvas_object_event_animation_get(top_content, EFL_GFX_EVENT_HIDE);
|
||||||
|
|
||||||
|
/* If content is being popped now, then finish current animation and show
|
||||||
|
* the content without animation. */
|
||||||
|
if (top_cd->on_popping)
|
||||||
|
{
|
||||||
|
//Finish current animation.
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_SHOW, NULL);
|
||||||
|
|
||||||
|
//Hide without animation.
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE, NULL);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(top_content, EINA_FALSE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
orig_hide_anim);
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = top_content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = top_content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top_cd->on_popping = EINA_TRUE;
|
||||||
|
|
||||||
|
//Hide with animation.
|
||||||
|
if (!orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(top_content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
hide_anim);
|
||||||
|
|
||||||
|
//Deallocate content data when hide animation is finished.
|
||||||
|
efl_event_callback_add(top_content, EFL_GFX_EVENT_HIDE,
|
||||||
|
_pop_content_hide_cb, top_cd);
|
||||||
|
|
||||||
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
|
td->cd = top_cd;
|
||||||
|
td->orig_anim = !!(orig_hide_anim);
|
||||||
|
td->freeze_events = efl_canvas_object_freeze_events_get(top_content);
|
||||||
|
|
||||||
|
efl_event_callback_add(top_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
||||||
|
_anim_started_cb, NULL);
|
||||||
|
efl_event_callback_add(top_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED,
|
||||||
|
_anim_ended_cb, td);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(top_content, EINA_FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pd->stack)
|
||||||
|
{
|
||||||
|
Content_Data *prev_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
|
||||||
|
Content_Data);
|
||||||
|
if (prev_cd)
|
||||||
|
{
|
||||||
|
Eo *prev_content = prev_cd->content;
|
||||||
|
|
||||||
|
//If content is being pushed now, then finish current animation.
|
||||||
|
if (prev_cd->on_pushing)
|
||||||
|
{
|
||||||
|
efl_canvas_object_event_animation_set(prev_content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
prev_cd->on_popping = EINA_TRUE;
|
||||||
|
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = prev_content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
|
&loaded_info);
|
||||||
|
|
||||||
|
/* Apply transition to previous content.
|
||||||
|
* Show previous content with animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(prev_content,
|
||||||
|
EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
//Show with animation
|
||||||
|
if (!orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(prev_content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
show_anim);
|
||||||
|
|
||||||
|
Transit_Data *td = calloc(1, sizeof(Transit_Data));
|
||||||
|
td->cd = prev_cd;
|
||||||
|
td->orig_anim = !!(orig_show_anim);
|
||||||
|
td->freeze_events =
|
||||||
|
efl_canvas_object_freeze_events_get(prev_content);
|
||||||
|
|
||||||
|
efl_event_callback_add(prev_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_STARTED,
|
||||||
|
_anim_started_cb, NULL);
|
||||||
|
efl_event_callback_add(prev_content,
|
||||||
|
EFL_CANVAS_OBJECT_EVENT_ANIM_ENDED,
|
||||||
|
_anim_ended_cb, td);
|
||||||
|
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, prev_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_insert_before(Eo *obj, Efl_Ui_Stack_Data *pd,
|
||||||
|
Eo *base_content, Eo *content)
|
||||||
|
{
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
Content_Data *base_cd = NULL;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, base_cd)
|
||||||
|
if (base_cd->content == base_content)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!base_cd)
|
||||||
|
{
|
||||||
|
ERR("The given base content is not found in the stack!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = _content_data_new(obj, content);
|
||||||
|
if (!cd) return;
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_prepend_relative(pd->stack,
|
||||||
|
EINA_INLIST_GET(cd),
|
||||||
|
EINA_INLIST_GET(base_cd));
|
||||||
|
evas_object_smart_member_add(content, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_insert_after(Eo *obj, Efl_Ui_Stack_Data *pd,
|
||||||
|
Eo *base_content, Eo *content)
|
||||||
|
{
|
||||||
|
if (!content) return;
|
||||||
|
|
||||||
|
Content_Data *base_cd = NULL;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, base_cd)
|
||||||
|
if (base_cd->content == base_content)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!base_cd)
|
||||||
|
{
|
||||||
|
ERR("The given base content is not found in the stack!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = _content_data_new(obj, content);
|
||||||
|
if (!cd) return;
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_append_relative(pd->stack,
|
||||||
|
EINA_INLIST_GET(cd),
|
||||||
|
EINA_INLIST_GET(base_cd));
|
||||||
|
evas_object_smart_member_add(content, obj);
|
||||||
|
|
||||||
|
if (pd->stack->last == EINA_INLIST_GET(cd))
|
||||||
|
{
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
|
&loaded_info);
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Hide top content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_hide_anim =
|
||||||
|
efl_canvas_object_event_animation_get(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE, NULL);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(base_cd->content, EINA_FALSE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
orig_hide_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = base_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = base_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Show new content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(content,
|
||||||
|
EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_SHOW,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
evas_object_raise(content);
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, content);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_SHOW,
|
||||||
|
orig_show_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Activated Event
|
||||||
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
|
activated_info.content = content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
|
&activated_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_insert_at(Eo *obj, Efl_Ui_Stack_Data *pd,
|
||||||
|
int index, Eo *content)
|
||||||
|
{
|
||||||
|
if (!content)
|
||||||
|
{
|
||||||
|
ERR("The given content is NULL!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = eina_inlist_count(pd->stack);
|
||||||
|
if ((index < 0) || (index > count))
|
||||||
|
{
|
||||||
|
ERR("The index(%d) should be from 0 to #contents in the stack(%d)!",
|
||||||
|
index, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *base_cd = NULL;
|
||||||
|
|
||||||
|
if (index == count)
|
||||||
|
{
|
||||||
|
base_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, base_cd)
|
||||||
|
{
|
||||||
|
if (i == index)
|
||||||
|
break;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = _content_data_new(obj, content);
|
||||||
|
if (!cd) return;
|
||||||
|
|
||||||
|
if (index == count)
|
||||||
|
pd->stack = eina_inlist_append_relative(pd->stack,
|
||||||
|
EINA_INLIST_GET(cd),
|
||||||
|
EINA_INLIST_GET(base_cd));
|
||||||
|
else
|
||||||
|
pd->stack = eina_inlist_prepend_relative(pd->stack,
|
||||||
|
EINA_INLIST_GET(cd),
|
||||||
|
EINA_INLIST_GET(base_cd));
|
||||||
|
|
||||||
|
evas_object_smart_member_add(content, obj);
|
||||||
|
|
||||||
|
if (pd->stack->last == EINA_INLIST_GET(cd))
|
||||||
|
{
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
|
&loaded_info);
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Hide top content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_hide_anim =
|
||||||
|
efl_canvas_object_event_animation_get(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE, NULL);
|
||||||
|
|
||||||
|
efl_gfx_visible_set(base_cd->content, EINA_FALSE);
|
||||||
|
|
||||||
|
if (orig_hide_anim)
|
||||||
|
efl_canvas_object_event_animation_set(base_cd->content,
|
||||||
|
EFL_GFX_EVENT_HIDE,
|
||||||
|
orig_hide_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = base_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = base_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Show new content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(content,
|
||||||
|
EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_SHOW,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
evas_object_raise(content);
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, content);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(content, EFL_GFX_EVENT_SHOW,
|
||||||
|
orig_show_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Activated Event
|
||||||
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
|
activated_info.content = content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
|
&activated_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_remove(Eo *obj, Efl_Ui_Stack_Data *pd, Eo *content)
|
||||||
|
{
|
||||||
|
if (!pd->stack)
|
||||||
|
{
|
||||||
|
ERR("There is no content in the stack!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!content)
|
||||||
|
{
|
||||||
|
ERR("The given content is NULL!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = NULL;
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, cd)
|
||||||
|
{
|
||||||
|
if (cd->content == content)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!cd)
|
||||||
|
{
|
||||||
|
ERR("The given content does not exist in the stack!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool remove_top = EINA_FALSE;
|
||||||
|
if (pd->stack->last == EINA_INLIST_GET(cd))
|
||||||
|
remove_top = EINA_TRUE;
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
_content_data_del(cd);
|
||||||
|
|
||||||
|
if (remove_top)
|
||||||
|
{
|
||||||
|
if (pd->stack)
|
||||||
|
{
|
||||||
|
Content_Data *new_top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
|
||||||
|
Content_Data);
|
||||||
|
if (new_top_cd)
|
||||||
|
{
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = new_top_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
|
&loaded_info);
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Show new content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
evas_object_raise(new_top_cd->content);
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, new_top_cd->content);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
orig_show_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Activated Event
|
||||||
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
|
activated_info.content = new_top_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
|
&activated_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static void
|
||||||
|
_efl_ui_stack_remove_at(Eo *obj, Efl_Ui_Stack_Data *pd,
|
||||||
|
int index)
|
||||||
|
{
|
||||||
|
if (!pd->stack)
|
||||||
|
{
|
||||||
|
ERR("There is no content in the stack!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = eina_inlist_count(pd->stack);
|
||||||
|
if ((index < 0) || (index >= count))
|
||||||
|
{
|
||||||
|
ERR("The index(%d) should be from 0 to (#contents - 1) in the stack(%d)!",
|
||||||
|
index, count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = NULL;
|
||||||
|
int i = 0;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, cd)
|
||||||
|
{
|
||||||
|
if (i == index)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool remove_top = EINA_FALSE;
|
||||||
|
if (pd->stack->last == EINA_INLIST_GET(cd))
|
||||||
|
remove_top = EINA_TRUE;
|
||||||
|
|
||||||
|
pd->stack = eina_inlist_remove(pd->stack, EINA_INLIST_GET(cd));
|
||||||
|
|
||||||
|
//Deactivated Event
|
||||||
|
Efl_Ui_Stack_Event_Deactivated deactivated_info;
|
||||||
|
deactivated_info.content = cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_DEACTIVATED,
|
||||||
|
&deactivated_info);
|
||||||
|
|
||||||
|
//Unloaded Event
|
||||||
|
Efl_Ui_Stack_Event_Unloaded unloaded_info;
|
||||||
|
unloaded_info.content = cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_UNLOADED,
|
||||||
|
&unloaded_info);
|
||||||
|
_content_data_del(cd);
|
||||||
|
|
||||||
|
//FIXME: Apply transition here.
|
||||||
|
if (remove_top)
|
||||||
|
{
|
||||||
|
if (pd->stack)
|
||||||
|
{
|
||||||
|
Content_Data *new_top_cd = EINA_INLIST_CONTAINER_GET(pd->stack->last,
|
||||||
|
Content_Data);
|
||||||
|
if (new_top_cd)
|
||||||
|
{
|
||||||
|
//Loaded Event
|
||||||
|
Efl_Ui_Stack_Event_Loaded loaded_info;
|
||||||
|
loaded_info.content = new_top_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_LOADED,
|
||||||
|
&loaded_info);
|
||||||
|
|
||||||
|
/* Do not apply transition for insert.
|
||||||
|
* Show new content without animation. */
|
||||||
|
{
|
||||||
|
Efl_Canvas_Animation *orig_show_anim =
|
||||||
|
efl_canvas_object_event_animation_get(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
evas_object_raise(new_top_cd->content);
|
||||||
|
/* efl_ui_widget_resize_object_set() calls efl_gfx_visible_set()
|
||||||
|
* internally.
|
||||||
|
* Therefore, efl_ui_widget_resize_object_set() is called after
|
||||||
|
* setting animation and efl_gfx_visible_set() is not called. */
|
||||||
|
efl_ui_widget_resize_object_set(obj, new_top_cd->content);
|
||||||
|
|
||||||
|
if (orig_show_anim)
|
||||||
|
efl_canvas_object_event_animation_set(new_top_cd->content,
|
||||||
|
EFL_GFX_EVENT_SHOW,
|
||||||
|
orig_show_anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Activated Event
|
||||||
|
Efl_Ui_Stack_Event_Activated activated_info;
|
||||||
|
activated_info.content = new_top_cd->content;
|
||||||
|
efl_event_callback_call(obj, EFL_UI_STACK_EVENT_ACTIVATED,
|
||||||
|
&activated_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static int
|
||||||
|
_efl_ui_stack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, Efl_Canvas_Object *content)
|
||||||
|
{
|
||||||
|
if (!pd->stack)
|
||||||
|
{
|
||||||
|
ERR("There is no content in the stack!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!content)
|
||||||
|
{
|
||||||
|
ERR("The given content is NULL!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = NULL;
|
||||||
|
int index = 0;
|
||||||
|
int count = eina_inlist_count(pd->stack);
|
||||||
|
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, cd)
|
||||||
|
{
|
||||||
|
if (cd->content == content)
|
||||||
|
break;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//The given content is not found.
|
||||||
|
if (index == count) return -1;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eo *
|
||||||
|
_efl_ui_stack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd, int index)
|
||||||
|
{
|
||||||
|
if (!pd->stack)
|
||||||
|
{
|
||||||
|
ERR("There is no content in the stack!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = eina_inlist_count(pd->stack);
|
||||||
|
if ((index < 0) || (index >= count))
|
||||||
|
{
|
||||||
|
ERR("The index(%d) should be from 0 to (#contents - 1) in the stack(%d)!",
|
||||||
|
index, count);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content_Data *cd = NULL;
|
||||||
|
int i = 0;
|
||||||
|
EINA_INLIST_FOREACH(pd->stack, cd)
|
||||||
|
{
|
||||||
|
if (i == index)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cd)
|
||||||
|
return cd->content;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eo *
|
||||||
|
_efl_ui_stack_top(Eo *obj EINA_UNUSED, Efl_Ui_Stack_Data *pd)
|
||||||
|
{
|
||||||
|
if (!pd->stack) return NULL;
|
||||||
|
|
||||||
|
Content_Data *cd = EINA_INLIST_CONTAINER_GET(pd->stack->last, Content_Data);
|
||||||
|
if (!cd) return NULL;
|
||||||
|
|
||||||
|
return cd->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN static Eo *
|
||||||
|
_efl_ui_stack_efl_object_constructor(Eo *obj, Efl_Ui_Stack_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
||||||
|
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
|
||||||
|
|
||||||
|
//Default Show Animation
|
||||||
|
show_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
|
||||||
|
efl_animation_alpha_set(show_anim, 0.0, 1.0);
|
||||||
|
efl_animation_duration_set(show_anim, 0.5);
|
||||||
|
efl_animation_final_state_keep_set(show_anim, EINA_TRUE);
|
||||||
|
|
||||||
|
//Default Hide Animation
|
||||||
|
hide_anim = efl_add(EFL_CANVAS_ANIMATION_ALPHA_CLASS, obj);
|
||||||
|
efl_animation_alpha_set(hide_anim, 1.0, 0.0);
|
||||||
|
efl_animation_duration_set(hide_anim, 0.5);
|
||||||
|
efl_animation_final_state_keep_set(hide_anim, EINA_TRUE);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "efl_ui_stack.eo.c"
|
|
@ -0,0 +1,131 @@
|
||||||
|
struct Efl.Ui.Stack.Event_Loaded {
|
||||||
|
[[Information of loaded event.]]
|
||||||
|
content: Efl.Canvas.Object; [[Loaded content.]]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Efl.Ui.Stack.Event_Unloaded {
|
||||||
|
[[Information of unloaded event.]]
|
||||||
|
content: Efl.Canvas.Object; [[Unloaded content.]]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Efl.Ui.Stack.Event_Activated {
|
||||||
|
[[Information of activated event.]]
|
||||||
|
content: Efl.Canvas.Object; [[Activated content.]]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Efl.Ui.Stack.Event_Deactivated {
|
||||||
|
[[Information of deactivated event.]]
|
||||||
|
content: Efl.Canvas.Object; [[Deactivated content.]]
|
||||||
|
}
|
||||||
|
|
||||||
|
class Efl.Ui.Stack (Efl.Ui.Layout)
|
||||||
|
{
|
||||||
|
[[Stack widget.
|
||||||
|
|
||||||
|
Stack widget arranges objects in stack structure by pushing and poping them.
|
||||||
|
]]
|
||||||
|
methods {
|
||||||
|
push {
|
||||||
|
[[Pushes a new object to the top of the stack and shows it.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The pushed object which becomes the top content of the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pop {
|
||||||
|
[[Pops the top content from the stack and deletes it.
|
||||||
|
]]
|
||||||
|
return: Efl.Canvas.Object;
|
||||||
|
[[The top content which is removed from the stack.]]
|
||||||
|
}
|
||||||
|
insert_before {
|
||||||
|
[[Inserts an object before the given base content in the stack.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in base_content: Efl.Canvas.Object;
|
||||||
|
[[$content is inserted before this $base_content.]]
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The inserted object in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insert_after {
|
||||||
|
[[Inserts an object after the given base content in the stack.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in base_content: Efl.Canvas.Object;
|
||||||
|
[[$content is inserted after this $base_content.]]
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The inserted object in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insert_at {
|
||||||
|
[[Inserts an object at the given place in the stack.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in index: int;
|
||||||
|
[[The index of the inserted object in the stack.
|
||||||
|
$index begins from bottom to top of the stack.
|
||||||
|
$index of the bottom content is 0.
|
||||||
|
]]
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The inserted object in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove {
|
||||||
|
[[Removes the given content in the stack.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The removed content from the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove_at {
|
||||||
|
[[Removes a content matched to the given index in the stack.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in index: int;
|
||||||
|
[[The index of the removed object in the stack.
|
||||||
|
$index begins from bottom to top of the stack.
|
||||||
|
$index of the bottom content is 0.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index_get {
|
||||||
|
[[Gets the index of the given content in the stack.
|
||||||
|
The index begins from bottom to top of the stack.
|
||||||
|
The index of the bottom content is 0.
|
||||||
|
]]
|
||||||
|
return: int;
|
||||||
|
[[The index of $content in the stack.]]
|
||||||
|
params {
|
||||||
|
@in content: Efl.Canvas.Object;
|
||||||
|
[[The content matched to the index to be returned in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content_get {
|
||||||
|
[[Gets the content matched to the given index in the stack.
|
||||||
|
]]
|
||||||
|
return: Efl.Canvas.Object;
|
||||||
|
[[The content matched to $index in the stack.]]
|
||||||
|
params {
|
||||||
|
@in index: int;
|
||||||
|
[[The index of the content to be returned in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
top {
|
||||||
|
[[Gets the top content in the stack.
|
||||||
|
]]
|
||||||
|
return: Efl.Canvas.Object; [[The top content in the stack.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
implements {
|
||||||
|
Efl.Object.constructor;
|
||||||
|
}
|
||||||
|
events {
|
||||||
|
loaded; [[Called when content is loaded right before transition.]]
|
||||||
|
unloaded; [[Called when content is unloaded right after being deactivated.]]
|
||||||
|
activated; [[Called when content is activated right after transition.]]
|
||||||
|
deactivated; [[Called when content is deactivated right after transition.]]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef EFL_UI_WIDGET_STACK_H
|
||||||
|
#define EFL_UI_WIDGET_STACK_H
|
||||||
|
|
||||||
|
typedef struct _Efl_Ui_Stack_Data Efl_Ui_Stack_Data;
|
||||||
|
struct _Efl_Ui_Stack_Data
|
||||||
|
{
|
||||||
|
Eina_Inlist *stack; /* the last item is the top item */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Content_Data Content_Data;
|
||||||
|
struct _Content_Data
|
||||||
|
{
|
||||||
|
EINA_INLIST;
|
||||||
|
|
||||||
|
Eo *stack;
|
||||||
|
Eo *content;
|
||||||
|
Eina_Bool on_pushing : 1;
|
||||||
|
Eina_Bool on_popping : 1;
|
||||||
|
Eina_Bool popped_hidden : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Transit_Data Transit_Data;
|
||||||
|
struct _Transit_Data
|
||||||
|
{
|
||||||
|
Content_Data *cd;
|
||||||
|
Eina_Bool orig_anim;
|
||||||
|
Eina_Bool freeze_events;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue