efl_ui_navigation_bar: Add Efl.Ui.Navigation_Bar class

Efl.Ui.Navigation_Bar is a widget which provides a bar form useful for
navigation.
This commit is contained in:
Jaehyun Cho 2018-04-12 21:42:38 +09:00
parent 7e8722be00
commit 6c65b6368a
11 changed files with 405 additions and 0 deletions

View File

@ -1022,6 +1022,7 @@ elementary/themes/edc/efl/uiclock.edc \
elementary/themes/edc/efl/cursor.edc \
elementary/themes/edc/efl/focus.edc \
elementary/themes/edc/efl/frame.edc \
elementary/themes/edc/efl/navigation_bar.edc \
elementary/themes/edc/efl/navigation_layout.edc \
elementary/themes/edc/efl/multibuttonentry.edc \
elementary/themes/edc/efl/nstate.edc \

View File

@ -168,6 +168,7 @@ collections {
#include "edc/efl/bg.edc"
#include "edc/efl/button.edc"
#include "edc/efl/calendar.edc"
#include "edc/efl/navigation_bar.edc"
#include "edc/efl/navigation_layout.edc"
#include "edc/efl/nstate.edc"
// XXX: mobile mode needs invisible scrollers... make signals that do this

View File

@ -0,0 +1,114 @@
//Efl.Ui.Navigation_Bar Themes
group { "efl/navigation_bar";
styles {
style { name: "navigation_bar_text";
base: "font="FNBD" font_size=10 text_class=label align=center color=#fff color_class=navigation_bar_text style=shadow,bottom shadow_color=#00000080 ellipsis=1.0 wrap=mixed";
tag: "br" "\n";
tag: "hilight" "+ font="FNBD" text_class=label_light";
tag: "b" "+ font="FNBD" text_class=label_light";
tag: "whitecolor" "+ color=#fff";
tag: "tab" "\t";
}
}
parts {
spacer { "base";
desc { "default";
}
}
swallow { "back_button";
desc { "default";
fixed: 1 0;
min: 0 0;
max: 0 -1;
rel.to: "base";
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
hid;
}
desc { "visible";
inherit: "default";
min: 40 0;
max: 40 -1;
vis;
}
}
swallow { "left_content";
desc { "default";
rel.to: "base";
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
}
}
swallow { "right_content";
desc { "default";
rel.to: "base";
rel1.relative: 1.0 0.0;
align: 1.0 0.5;
}
}
spacer { "text_base";
desc { "default";
rel1 {
to: "back_button";
relative: 1.0 0.0;
}
rel2 {
to: "right_content";
relative: 0.0 1.0;
}
}
desc { "left_content";
inherit: "default";
rel1 {
to: "left_content";
relative: 1.0 0.0;
}
}
}
textblock { "text";
scale;
desc { "default";
text {
style: "navigation_bar_text";
}
rel.to: "text_base";
}
}
programs {
program {
signal: "elm,state,back_button,visible"; source: "elm";
action: STATE_SET "visible" 0.0;
target: "back_button";
}
program {
signal: "elm,state,back_button,hidden"; source: "elm";
action: STATE_SET "default" 0.0;
target: "back_button";
}
program {
signal: "elm,state,left_content,visible"; source: "elm";
action: STATE_SET "left_content" 0.0;
target: "text_base";
}
program {
signal: "elm,state,left_content,hidden"; source: "elm";
action: STATE_SET "default" 0.0;
target: "text_base";
}
}
}
}
group { name: "efl/navigation_bar/back_button";
inherit: "efl/button";
images.image: "icon_arrow_left.png" COMP;
parts {
image { name: "icon_arrow_left";
insert_before: "elm.swallow.content";
desc { "default";
image.normal: "icon_arrow_left.png";
fill.smooth: 0;
}
}
}
}

View File

@ -16,6 +16,9 @@ elm_public_eolian_files = \
lib/elementary/efl_ui_image_zoomable.eo \
lib/elementary/efl_ui_layout.eo \
lib/elementary/efl_ui_nstate.eo \
lib/elementary/efl_ui_navigation_bar.eo \
lib/elementary/efl_ui_navigation_bar_part.eo \
lib/elementary/efl_ui_navigation_bar_part_back_button.eo \
lib/elementary/efl_ui_navigation_layout.eo \
lib/elementary/efl_ui_panes.eo \
lib/elementary/efl_ui_progressbar.eo \
@ -352,6 +355,7 @@ includesunstable_HEADERS = \
lib/elementary/elm_widget_menu.h \
lib/elementary/elm_widget_multibuttonentry.h \
lib/elementary/elm_widget_naviframe.h \
lib/elementary/efl_ui_navigation_bar_private.h \
lib/elementary/efl_ui_navigation_layout_private.h \
lib/elementary/elm_widget_notify.h \
lib/elementary/elm_widget_panel.h \
@ -627,6 +631,7 @@ lib_elementary_libelementary_la_SOURCES = \
lib/elementary/elc_hoversel.c \
lib/elementary/elc_multibuttonentry.c \
lib/elementary/elc_naviframe.c \
lib/elementary/efl_ui_navigation_bar.c \
lib/elementary/efl_ui_navigation_layout.c \
lib/elementary/elc_player.c \
lib/elementary/elc_popup.c \

View File

@ -336,6 +336,9 @@ typedef Eo Efl_Ui_Focus_Manager;
# include <efl_selection.eo.h>
# include <efl_ui_dnd.eo.h>
# include <efl_ui_dnd_container.eo.h>
# include <efl_ui_navigation_bar.eo.h>
# include <efl_ui_navigation_bar_part.eo.h>
# include <efl_ui_navigation_bar_part_back_button.eo.h>
# include <efl_ui_navigation_layout.eo.h>
# include <efl_ui_stack.eo.h>
#endif

View File

@ -0,0 +1,210 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Elementary.h>
#include "elm_priv.h"
#include "efl_ui_navigation_bar_private.h"
#include "efl_ui_navigation_bar_part.eo.h"
#include "elm_part_helper.h"
#define MY_CLASS EFL_UI_NAVIGATION_BAR_CLASS
#define MY_CLASS_NAME "Efl.Ui.Navigation_Bar"
static void
_back_button_clicked_cb(void *data, const Efl_Event *ev EINA_UNUSED)
{
Eo *navigation_bar = data;
Eo *stack = efl_provider_find(navigation_bar, EFL_UI_STACK_CLASS);
if (!stack)
{
ERR("Cannot find EFL_UI_STACK_CLASS instance!");
return;
}
efl_ui_stack_pop(stack);
}
EOLIAN static Eo *
_efl_ui_navigation_bar_efl_object_constructor(Eo *obj, Efl_Ui_Navigation_Bar_Data *pd)
{
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
if (!elm_widget_theme_klass_get(obj))
elm_widget_theme_klass_set(obj, "navigation_bar");
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
elm_widget_sub_object_parent_add(obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
if (!elm_widget_theme_object_set(obj, wd->resize_obj,
elm_widget_theme_klass_get(obj),
elm_widget_theme_element_get(obj),
elm_widget_theme_style_get(obj)))
CRI("Failed to set layout!");
Eo *back_button = efl_add(EFL_UI_BUTTON_CLASS, obj,
elm_widget_element_update(obj, efl_added, "back_button"),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, obj),
efl_gfx_visible_set(efl_added, EINA_FALSE));
pd->back_button = back_button;
return obj;
}
/* Standard widget overrides */
ELM_PART_CONTENT_DEFAULT_IMPLEMENT(efl_ui_navigation_bar, Efl_Ui_Navigation_Bar_Data)
ELM_PART_TEXT_DEFAULT_GET(efl_ui_navigation_bar, "text")
ELM_PART_TEXT_DEFAULT_IMPLEMENT(efl_ui_navigation_bar, Efl_Ui_Navigation_Bar_Data)
#define EFL_UI_NAVIGATION_BAR_EXTRA_OPS \
ELM_PART_TEXT_DEFAULT_OPS(efl_ui_navigation_bar)
static Eina_Bool
_efl_ui_navigation_bar_content_set(Eo *obj, Efl_Ui_Navigation_Bar_Data *_pd EINA_UNUSED, const char *part, Efl_Gfx *content)
{
if (eina_streq(part, "left_content"))
{
if (content)
efl_layout_signal_emit(obj, "elm,state,left_content,visible", "elm");
else
efl_layout_signal_emit(obj, "elm,state,left_content,hidden", "elm");
efl_layout_signal_process(obj, EINA_FALSE);
}
return efl_content_set(efl_part(efl_super(obj, MY_CLASS), part), content);
}
static Efl_Gfx *
_efl_ui_navigation_bar_content_get(const Eo *obj, Efl_Ui_Navigation_Bar_Data *_pd EINA_UNUSED, const char *part)
{
return efl_content_get(efl_part(efl_super(obj, MY_CLASS), part));
}
static Efl_Gfx *
_efl_ui_navigation_bar_content_unset(Eo *obj, Efl_Ui_Navigation_Bar_Data *_pd EINA_UNUSED, const char *part)
{
if (eina_streq(part, "left_content"))
{
efl_layout_signal_emit(obj, "elm,state,left_content,hidden", "elm");
efl_layout_signal_process(obj, EINA_FALSE);
}
return efl_content_unset(efl_part(efl_super(obj, MY_CLASS), part));
}
/* Efl.Part begin */
EOLIAN static Efl_Object *
_efl_ui_navigation_bar_efl_part_part(const Eo *obj, Efl_Ui_Navigation_Bar_Data *priv EINA_UNUSED, const char *part)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
if (eina_streq(part, "back_button"))
return ELM_PART_IMPLEMENT(EFL_UI_NAVIGATION_BAR_PART_BACK_BUTTON_CLASS, obj, part);
else if (eina_streq(part, "left_content") || eina_streq(part, "right_content"))
return ELM_PART_IMPLEMENT(EFL_UI_NAVIGATION_BAR_PART_CLASS, obj, part);
return efl_part(efl_super(obj, MY_CLASS), part);
}
EOLIAN static void
_efl_ui_navigation_bar_part_back_button_efl_gfx_visible_set(Eo *obj, void *_pd EINA_UNUSED, Eina_Bool visible)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd);
if (visible)
{
if (!efl_content_set(efl_part(efl_super(pd->obj, MY_CLASS), "back_button"), ppd->back_button))
ERR("Part for back button(i.e. \"back_button\") does not exist!");
else
efl_layout_signal_emit(pd->obj, "elm,state,back_button,visible", "elm");
}
else
{
efl_content_unset(efl_part(efl_super(pd->obj, MY_CLASS), "back_button"));
efl_gfx_visible_set(ppd->back_button, visible);
efl_layout_signal_emit(pd->obj, "elm,state,back_button,hidden", "elm");
}
efl_layout_signal_process(pd->obj, EINA_FALSE);
}
EOLIAN static Eina_Bool
_efl_ui_navigation_bar_part_back_button_efl_gfx_visible_get(const Eo *obj, void *_pd EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, EINA_FALSE);
return efl_gfx_visible_get(ppd->back_button);
}
EOLIAN static void
_efl_ui_navigation_bar_part_back_button_efl_text_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *label)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd);
efl_text_set(ppd->back_button, label);
}
EOLIAN static const char *
_efl_ui_navigation_bar_part_back_button_efl_text_text_get(const Eo *obj, void *_pd EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, EINA_FALSE);
return efl_text_get(ppd->back_button);
}
static Eina_Bool
_efl_ui_navigation_bar_part_back_button_efl_content_content_set(Eo *obj, void *_pd EINA_UNUSED, Efl_Gfx *content)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, EINA_FALSE);
if (content == ppd->back_button) return EINA_FALSE;
efl_event_callback_add(content, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
ppd->back_button = content;
return _efl_ui_navigation_bar_content_set(pd->obj, ppd, pd->part, content);
}
static Efl_Gfx*
_efl_ui_navigation_bar_part_back_button_efl_content_content_get(const Eo *obj, void *_pd EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, NULL);
return _efl_ui_navigation_bar_content_get(pd->obj, ppd, pd->part);
}
static Efl_Gfx*
_efl_ui_navigation_bar_part_back_button_efl_content_content_unset(Eo *obj, void *_pd EINA_UNUSED)
{
Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(pd->obj, ppd, NULL);
efl_event_callback_del(ppd->back_button, EFL_UI_EVENT_CLICKED, _back_button_clicked_cb, pd->obj);
ppd->back_button = NULL;
return _efl_ui_navigation_bar_content_unset(pd->obj, ppd, pd->part);
}
ELM_PART_OVERRIDE_CONTENT_SET(efl_ui_navigation_bar, EFL_UI_NAVIGATION_BAR, Efl_Ui_Navigation_Bar_Data)
ELM_PART_OVERRIDE_CONTENT_GET(efl_ui_navigation_bar, EFL_UI_NAVIGATION_BAR, Efl_Ui_Navigation_Bar_Data)
ELM_PART_OVERRIDE_CONTENT_UNSET(efl_ui_navigation_bar, EFL_UI_NAVIGATION_BAR, Efl_Ui_Navigation_Bar_Data)
#include "efl_ui_navigation_bar_part.eo.c"
/* Efl.Part end */
/* Efl.Part Back_Button begin */
#include "efl_ui_navigation_bar_part_back_button.eo.c"
/* Efl.Part Back_Button end */
#include "efl_ui_navigation_bar.eo.c"

View File

@ -0,0 +1,30 @@
class Efl.Ui.Navigation_Bar (Efl.Ui.Layout, Efl.Content, Efl.Text, Efl.Ui.Translatable)
{
[[Navigation_Bar widget.
Navigation_Bar widget provides a bar form useful for navigation.
Navigation_Bar has a back button which is used to navigate to the previous
content in the stack.
]]
parts {
back_button: Efl.Ui.Navigation_Bar.Part_Back_Button;
[[Back button to navigate to the previous content in the stack.
The back button works only if the Navigation_Bar widget is contained
in the Stack widget(Efl.Ui.Stack class).
e.g. The Navigation_Bar widget is set in the Navigation_Layout widget
and the Navigation_Layout widget is pushed to the Stack widget.
The back button is hidden by default and it can be visible.
e.g. efl_gfx_visible_set(efl_part(navigation_bar, "back_button"), EINA_TRUE);
]]
}
implements {
Efl.Object.constructor;
Efl.Content.content { set; get; }
Efl.Content.content_unset;
Efl.Text.text { set; get; }
Efl.Ui.Translatable.translatable_text { set; get; }
Efl.Part.part;
}
}

View File

@ -0,0 +1,9 @@
class Efl.Ui.Navigation_Bar.Part (Efl.Ui.Layout.Part_Content)
{
[[Efl UI Navigation_Bar internal part class]]
data: null;
implements {
Efl.Content.content { set; get; }
Efl.Content.content_unset;
}
}

View File

@ -0,0 +1,11 @@
class Efl.Ui.Navigation_Bar.Part_Back_Button (Efl.Ui.Widget.Part, Efl.Ui.Button)
{
[[Efl Ui Navigation_Bar internal part back button class]]
data: null;
implements {
Efl.Gfx.visible { set; get; }
Efl.Text.text { set; get; }
Efl.Content.content { set; get; }
Efl.Content.content_unset;
}
}

View File

@ -0,0 +1,20 @@
#ifndef EFL_UI_WIDGET_NAVIGATION_BAR_H
#define EFL_UI_WIDGET_NAVIGATION_BAR_H
typedef struct _Efl_Ui_Navigation_Bar_Data Efl_Ui_Navigation_Bar_Data;
struct _Efl_Ui_Navigation_Bar_Data
{
Eo *back_button;
};
#define EFL_UI_NAVIGATION_BAR_DATA_GET_OR_RETURN(o, ptr, ...) \
Efl_Ui_Navigation_Bar_Data *ptr; \
ptr = efl_data_scope_get(o, EFL_UI_NAVIGATION_BAR_CLASS); \
if (EINA_UNLIKELY(!ptr)) \
{ \
CRI("no ui frame navigation data for object %p (%s)", \
o, evas_object_type_get(o)); \
return __VA_ARGS__; \
}
#endif

View File

@ -9,6 +9,7 @@ class Efl.Ui.Navigation_Layout (Efl.Ui.Layout, Efl.Content)
methods {
@property bar {
[[The bar object which is located at the top area as a title.
e.g. Navigation_Bar widget(Efl.Ui.Navigation_Bar) can be used as $bar.
]]
set {
}