diff --git a/data/Makefile.am b/data/Makefile.am index 19c056f789..74a025ef8f 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -226,6 +226,7 @@ elementary/objects/test_prefs.edj \ elementary/objects/test_prefs.epb \ elementary/objects/test_focus_style.edj \ elementary/objects/test_tooltip.edj \ +elementary/objects/test_tab_pager.edj \ $(NULL) CLEANFILES += $(elementaryobjects_DATA) @@ -292,3 +293,7 @@ elementary/objects/test_prefs.epb: elementary/objects/test_prefs.epc $(MKDIR_P) elementary/objects/; \ $(ELM_PREFS_CC) $(ELM_PREFS_FLAGS) $< $@ +elementary/objects/test_tab_pager.edj: elementary/objects/test_tab_pager.edc + $(AM_V_EDJ) \ + $(MKDIR_P) elementary/objects/; \ + $(EDJE_CC) $(EDJE_CC_FLAGS) $< $@ diff --git a/data/elementary/objects/test_tab_pager.edc b/data/elementary/objects/test_tab_pager.edc new file mode 100644 index 0000000000..95715713ae --- /dev/null +++ b/data/elementary/objects/test_tab_pager.edc @@ -0,0 +1,66 @@ +collections { + group { "tab_page_layout"; + parts { + spacer { "base"; + scale; + desc { "default"; + } + } + swallow { "menu"; + scale; + desc { "default"; + rel.to: "base"; + align: 0 0; + min: 200 0; + max: 200 -1; + fixed: 0 1; + } + } + rect { "separator"; + scale; + desc { "default"; + rel.to: "menu"; + rel1.relative: 1 0; + align: 0 0; + min: 1 0; + max: 1 -1; + fixed: 0 1; + color: 75 75 75 255; + } + } + swallow { "tab_pager"; + scale; + desc { "default"; + rel1.to: "separator"; + rel2.to: "base"; + rel1.relative: 1 0; + } + } + } + } + group { "page_layout"; + parts { + spacer { "base"; + scale; + desc { "default"; + } + } + rect { "bg"; + scale; + desc { "default"; + rel.to: "base"; + color: 255 255 255 255; + } + } + text { "text"; + scale; + desc { "default"; + rel.to: "base"; + align: 0.5 0.5; + color: 0 0 0 255; + text.size: 20; + } + } + } + } +} diff --git a/data/elementary/themes/Makefile.am b/data/elementary/themes/Makefile.am index 6aaf061966..1cf4e6e304 100644 --- a/data/elementary/themes/Makefile.am +++ b/data/elementary/themes/Makefile.am @@ -1044,7 +1044,10 @@ elementary/themes/edc/efl/tooltip.edc \ elementary/themes/edc/efl/video.edc \ elementary/themes/edc/efl/list.edc \ elementary/themes/edc/efl/win.edc \ -elementary/themes/edc/efl/pager.edc +elementary/themes/edc/efl/pager.edc \ +elementary/themes/edc/efl/tab_pager.edc \ +elementary/themes/edc/efl/tab_bar.edc \ +elementary/themes/edc/efl/tab_page.edc elementary_fdo_actions_128_files = \ elementary/themes/fdo/actions/128/address-book-new.png \ diff --git a/data/elementary/themes/default.edc b/data/elementary/themes/default.edc index e3f94b8a3c..40d1920a07 100644 --- a/data/elementary/themes/default.edc +++ b/data/elementary/themes/default.edc @@ -200,4 +200,7 @@ collections { #include "edc/efl/win.edc" #include "edc/efl/uiclock.edc" #include "edc/efl/pager.edc" +#include "edc/efl/tab_pager.edc" +#include "edc/efl/tab_bar.edc" +#include "edc/efl/tab_page.edc" } diff --git a/data/elementary/themes/edc/efl/tab_bar.edc b/data/elementary/themes/edc/efl/tab_bar.edc new file mode 100644 index 0000000000..f7f039cb79 --- /dev/null +++ b/data/elementary/themes/edc/efl/tab_bar.edc @@ -0,0 +1,596 @@ +group { "efl/tab_bar"; + images.image: "vgrad_med_lighter.png" COMP; + images.image: "bevel_out.png" COMP; + images.image: "shine.png" COMP; + images.image: "shadow_square_tiny.png" COMP; + parts { + spacer { "base"; + scale; + desc { "default"; + } + } + image { "shadow"; + nomouse; + desc { "default"; + rel.to: "base"; + rel1.offset: -3 -2; + rel2.offset: 2 3; + image.normal: "shadow_square_tiny.png"; + image.border: 6 6 6 6; + fill.smooth: 0; + } + } + image { "bg"; + desc { "default"; + rel.to: "base"; + image.normal: "vgrad_med_lighter.png"; + rel1.offset: 0 0; + rel2.offset: -1 -1; + fill.smooth: 0; + } + } + swallow { "efl.content"; + scale; + desc { "default"; + rel.to: "base"; + } + } + image { "bevel"; + nomouse; + desc { "default"; + rel.to: "base"; + image.normal: "bevel_out.png"; + image.border: 1 1 1 1; + image.middle: 0; + fill.smooth: 0; + } + } + image { "shine"; + nomouse; + desc { "default"; + image.normal: "shine.png"; + rel.to: "base"; + rel1.offset: 0 -2; + rel2.relative: 1.0 0.0; + rel2.offset: -1 2; + FIXED_SIZE(69, 5) + } + } + } +} + +group { "efl/tab_bar/tab"; + images.image: "shadow_inset_bevels.png" COMP; + images.image: "shadow_angled_in_sides.png" COMP; + images.image: "horizontal_separated_bar_small_glow.png" COMP; + data.item: "transition_animation_on" "1"; + images.image: "bevel_dark_in.png" COMP; + +#define ICON 1 +#define LABEL 2 +#define MASK 3 +#define DISABLE 4 + script { + public btmode; + public eval_mode(m) { + new m1 = m & MASK; + new d = m & DISABLE; + if (m1 == (ICON | LABEL)) { + if (!d) { + set_state(PART:"efl.icon", "default", 0.0); + set_state(PART:"icon_clip", "default", 0.0); + set_state(PART:"efl.text", "default", 0.0); + set_state(PART:"label2", "default", 0.0); + } else { + set_state(PART:"efl.icon", "default", 0.0); + set_state(PART:"icon_clip", "disabled", 0.0); + set_state(PART:"efl.text", "disabled", 0.0); + set_state(PART:"label2", "default", 0.0); + } + } else if (m1 == (ICON)) { + if (!d) { + set_state(PART:"efl.icon", "icononly", 0.0); + set_state(PART:"icon_clip", "default", 0.0); + set_state(PART:"efl.text", "icononly", 0.0); + set_state(PART:"label2", "icononly", 0.0); + } else { + set_state(PART:"efl.icon", "icononly", 0.0); + set_state(PART:"icon_clip", "disabled", 0.0); + set_state(PART:"efl.text", "icononly", 0.0); + set_state(PART:"label2", "icononly", 0.0); + } + } else if (m1 == (LABEL)) { + if (!d) { + set_state(PART:"efl.icon", "noicon", 0.0); + set_state(PART:"icon_clip", "default", 0.0); + set_state(PART:"efl.text", "noicon", 0.0); + set_state(PART:"label2", "noicon", 0.0); + } else { + set_state(PART:"efl.icon", "noicon", 0.0); + set_state(PART:"icon_clip", "disabled", 0.0); + set_state(PART:"efl.text", "noicon_disabled", 0.0); + set_state(PART:"label2", "noicon_disabled", 0.0); + } + } else { + if (!d) { + set_state(PART:"efl.icon", "noicon", 0.0); + set_state(PART:"icon_clip", "default", 0.0); + set_state(PART:"efl.text", "noicon", 0.0); + set_state(PART:"label2", "noicon", 0.0); + } else { + set_state(PART:"efl.icon", "noicon", 0.0); + set_state(PART:"icon_clip", "disabled", 0.0); + set_state(PART:"efl.text", "noicon_disabled", 0.0); + set_state(PART:"label2", "noicon_disabled", 0.0); + } + } + } + } + parts { + spacer { "base"; + scale; + desc { "default"; + } + desc { "vert"; + rel1.offset: -1 0; + rel2.offset: 0 -1; + } + } + image { "shadow1"; + nomouse; + desc { "default"; + rel.to: "base"; + image.normal: "shadow_inset_bevels.png"; + image.border: 2 2 0 1; + hid; + } + desc { "selected"; + inherit: "default"; + vis; + } + } + image { "shadow2"; + nomouse; + desc { "default"; + rel.to: "shadow1"; + rel1.offset: 1 0; + rel2.offset: -2 -1; + image.normal: "shadow_angled_in_sides.png"; + image.border: 8 8 0 1; + image.middle: 0; + hid; + } + desc { "selected"; + inherit: "default"; + vis; + } + } + rect { "bend_clip"; + desc { "default"; + hid; + } + desc { "vert"; + vis; + } + } + image { "bend"; + clip_to: "bend_clip"; + desc { "default"; + min: 2 2; + max: 99999 2; + rel2.offset: -1 1; + rel2.relative: 1.0 0.0; + image.normal: "bevel_dark_in.png"; + image.border: 2 2 2 2; + fill.smooth: 0; + hid; + fixed: 1 1; + } + desc { "selected"; + inherit: "default"; + vis; + } + } + rect { "icon_clip"; + desc { "default"; + } + desc { "disabled"; + inherit: "default"; + color: 255 255 255 64; + } + } + rect { "icon_clip1"; + clip_to: "icon_clip"; + desc { "default"; + color: 255 255 255 255; + vis; + } + desc { "animation"; + inherit: "default"; + color: 255 255 255 0; + hid; + } + } + swallow { "efl.icon"; + clip_to: "icon_clip1"; + desc { "default"; + align: 0.5 0.5; + rel1.relative: 0.0 0.0; + rel1.offset: 2 2; + rel2.to_y: "efl.text"; + rel2.relative: 1.0 0.0; + rel2.offset: -3 -1; + } + desc { "noicon"; + inherit: "default" 0.0; + hid; + rel1.offset: 2 0; + rel2.relative: 1.0 0.0; + rel2.offset: -3 -4; + } + desc { "icononly"; + inherit: "default" 0.0; + vis; + rel2.relative: 1.0 1.0; + rel2.offset: -3 -3; + rel2.to_y: "icon_clip"; + } + } + rect { "icon_clip2"; + clip_to: "icon_clip"; + desc { "default"; + color: 255 255 255 0; + hid; + } + desc { "animation"; + inherit: "default" 0.0; + color: 255 255 255 255; + vis; + } + } + swallow { "efl.icon_new"; + clip_to: "icon_clip2"; + desc { "default"; + align: 0.5 0.5; + rel1.relative: 0.0 0.0; + rel1.offset: 2 2; + rel2.to_y: "efl.text"; + rel2.relative: 1.0 0.0; + rel2.offset: -3 -1; + } + desc { "noicon"; + inherit: "default"; + hid; + rel1.offset: 2 0; + rel2.relative: 1.0 0.0; + rel2.offset: -3 -4; + } + desc { "icononly"; + inherit: "default" 0.0; + vis; + rel2.relative: 1.0 1.0; + rel2.offset: -3 -3; + rel2.to_y: "icon_clip"; + } + } + rect { "text_clip1"; + desc { "default"; + color: 255 255 255 255; + vis; + } + desc { "animation"; + inherit: "default"; + color: 255 255 255 0; + hid; + } + } + text { "efl.text"; + nomouse; + effect: SHADOW BOTTOM; + scale; + clip_to: "text_clip1"; + desc { "default"; + rel1.offset: 4 -3; + rel1.relative: 0.0 1.0; + rel2.offset: -5 -3; + align: 0.5 1.0; + color: FN_COL_DEFAULT; + color_class: "toolbar_item"; + text { font: FN; size: 10; + min: 1 1; + ellipsis: -1; + align: 0.5 0.5; + text_class: "toolbar_item"; + } + fixed: 0 1; + } + desc { "selected"; + inherit: "default"; + hid; + color_class: "toolbar_item_selected"; + } + desc { "disabled"; + inherit: "default"; + color: FN_COL_DISABLE; + color_class: "toolbar_item_disabled"; + } + desc { "noicon"; + inherit: "default"; + rel1.offset: 4 2; + rel1.relative: 0.0 0.0; + } + desc { "noicon_disabled"; + inherit: "noicon"; + color: FN_COL_DISABLE; + color_class: "toolbar_item_disabled"; + } + desc { "icononly"; + inherit: "default"; + text.min: 0 0; + hid; + fixed: 1 1; + } + } + text { "label2"; + nomouse; + effect: GLOW; + scale; + clip_to: "text_clip1"; + desc { "default"; + rel1.offset: -3 -3; + rel1.to: "efl.text"; + rel2.offset: 2 1; + rel2.to: "efl.text"; + color: FN_COL_HIGHLIGHT; + color_class: "toolbar_item_active"; + text { font: FN; size: 10; + text_source: "efl.text"; + align: 0.5 0.5; + text_class: "toolbar_item"; + } + hid; + } + desc { "selected"; + inherit: "default"; + vis; + } + desc { "noicon"; + inherit: "default"; + } + desc { "noicon_disabled"; + inherit: "noicon"; + } + desc { "icononly"; + inherit: "default"; + text.min: 0 0; + hid; + fixed: 1 1; + } + } + rect { "text_clip2"; + desc { "default"; + color: 255 255 255 0; + hid; + } + desc { "animation"; + inherit: "default"; + color: 255 255 255 255; + vis; + } + } + image { "bar"; + nomouse; + desc { "default"; + fixed: 0 1; + rel1.offset: -3 -7; + rel1.relative: 0.0 1.0; + rel1.to: "shadow2"; + rel2.offset: 2 2; + rel2.to: "shadow2"; + image.normal: "horizontal_separated_bar_small_glow.png"; + image.border: 4 4 4 4; + fill.smooth: 0; + hid; + } + desc { "selected"; + inherit: "default"; + vis; + } + } + image { "highlight"; + nomouse; + desc { "default"; + fixed: 0 1; + rel1.offset: -3 -7; + rel1.relative: 0.0 1.0; + rel1.to: "shadow2"; + rel2.offset: 2 2; + rel2.to: "shadow2"; + image.normal: "horizontal_separated_bar_small_glow.png"; + image.border: 4 4 4 4; + fill.smooth: 0; + hid; + } + desc { "selected"; + inherit: "default"; + vis; + } + } + rect { "event"; + ignore_flags: ON_HOLD; + desc { "default"; + color: 0 0 0 0; + } + } + programs { + program { + signal: "efl,orient,horizontal"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "base"; + target: "bend_clip"; + } + program { + signal: "efl,orient,vertical"; source: "efl"; + action: STATE_SET "vert" 0.0; + target: "base"; + target: "bend_clip"; + } + program { name: "st0"; + signal: "load"; source: ""; + script { + set_int(btmode, LABEL | ICON); + } + } + program { + signal: "efl,state,selected"; source: "efl"; + action: STATE_SET "selected" 0.0; + target: "efl.text"; + target: "label2"; + target: "shadow1"; + target: "shadow2"; + target: "bar"; + target: "bend"; + } + program { + signal: "efl,state,unselected"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "efl.text"; + target: "label2"; + target: "shadow1"; + target: "shadow2"; + target: "bar"; + target: "bend"; + } + program { + signal: "mouse,up,1"; source: "event"; + action: SIGNAL_EMIT "efl,action,click" "efl"; + } + program { + signal: "efl,highlight,on"; source: "efl"; + action: STATE_SET "selected" 0.0; + target: "highlight"; + } + program { + signal: "efl,highlight,off"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "highlight"; + } + program { + signal: "mouse,in"; source: "event"; + action: SIGNAL_EMIT "efl,mouse,in" "efl"; + } + program { name: "mouse,out"; + signal: "mouse,out"; source: "event"; + action: SIGNAL_EMIT "efl,mouse,out" "efl"; + } + program { name: "st1"; + signal: "efl,text,hidden"; source: "efl"; + script { + new m = get_int(btmode); + m &= ~LABEL; set_int(btmode, m); + eval_mode(m); + } + } + program { name: "st2"; + signal: "efl,text,visible"; source: "efl"; + script { + new m = get_int(btmode); + m |= LABEL; set_int(btmode, m); + eval_mode(m); + } + } + program { name: "st3"; + signal: "efl,icon,hidden"; source: "efl"; + script { + new m = get_int(btmode); + m &= ~ICON; set_int(btmode, m); + eval_mode(m); + } + } + program { name: "st4"; + signal: "efl,icon,visible"; source: "efl"; + script { + new m = get_int(btmode); + m |= ICON; set_int(btmode, m); + eval_mode(m); + } + } + program { name: "st5"; + signal: "efl,state,disabled"; source: "efl"; + script { + new m = get_int(btmode); + m |= DISABLE; set_int(btmode, m); + eval_mode(m); + } + } + program { name: "st6"; + signal: "efl,state,enabled"; source: "efl"; + script { + new m = get_int(btmode); + m &= ~DISABLE; set_int(btmode, m); + eval_mode(m); + } + } + program { + signal: "efl,state,moving"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "shadow1"; + target: "shadow2"; + } + program { + signal: "efl,state,icon_set,forward"; source: "efl"; + after: "icon_set,animation"; + } + program { + signal: "efl,state,icon_set,backward"; source: "efl"; + after: "icon_set,animation"; + } + program { name: "icon_set,animation"; + signal: "efl,state,icon_set"; source: "efl"; + action: STATE_SET "animation" 0.0; + target: "icon_clip1"; + target: "icon_clip2"; + transition: LINEAR 0.2; + after: "icon_set,animation,done"; + } + program { name: "icon_set,animation,done"; + action: SIGNAL_EMIT "efl,state,icon_set,done" "efl"; + } + program { + signal: "efl,state,icon,reset"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "icon_clip1"; + target: "icon_clip2"; + } + program { + signal: "efl,state,label_set,forward"; source: "efl"; + after: "label_set,animation"; + } + program { + signal: "efl,state,label_set,backward"; source: "efl"; + after: "label_set,animation"; + } + program { name: "label_set,animation"; + signal: "efl,state,label_set"; source: "efl"; + action: STATE_SET "animation" 0.0; + target: "text_clip1"; + target: "text_clip2"; + transition: LINEAR 0.2; + after: "label_set,animation,done"; + } + program { name: "label_set,animation,done"; + action: SIGNAL_EMIT "efl,state,label_set,done" "efl"; + } + program { + signal: "efl,state,label,reset"; source: "efl"; + action: STATE_SET "default" 0.0; + target: "text_clip1"; + target: "text_clip2"; + } + } +#undef ICON +#undef LABEL +#undef MASK +#undef DISABLE + } +} diff --git a/data/elementary/themes/edc/efl/tab_page.edc b/data/elementary/themes/edc/efl/tab_page.edc new file mode 100644 index 0000000000..68bbd6b55c --- /dev/null +++ b/data/elementary/themes/edc/efl/tab_page.edc @@ -0,0 +1,15 @@ +group { "efl/tab_page"; + parts { + spacer { "base"; + scale; + desc { "default"; + } + } + swallow { "efl.content"; + scale; + desc { "default"; + rel.to: "base"; + } + } + } +} diff --git a/data/elementary/themes/edc/efl/tab_pager.edc b/data/elementary/themes/edc/efl/tab_pager.edc new file mode 100644 index 0000000000..fb63e58a61 --- /dev/null +++ b/data/elementary/themes/edc/efl/tab_pager.edc @@ -0,0 +1,34 @@ +group { "efl/tab_pager"; + parts { + spacer { "base"; + scale; + desc { "default"; + } + } + swallow { "efl.tab_root"; + scale; + desc { "default"; + rel.to: "base"; + align: 0 0; + min: 0 50; + max: -1 50; + fixed: 0 1; + } + } + swallow { "efl.page_root"; + scale; + desc { "default"; + rel1.to: "efl.tab_root"; + rel2.to: "base"; + rel1.relative: 0 1; + } + } + swallow { "efl.event"; + scale; + repeat_events: 1; + desc { "default"; + rel.to: "efl.page_root"; + } + } + } +} diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 5bf4e58237..056b9cbd6c 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -120,6 +120,10 @@ elm_public_eolian_files = \ lib/elementary/efl_page_transition_scroll.eo \ lib/elementary/efl_page_indicator.eo \ lib/elementary/efl_page_indicator_icon.eo \ + lib/elementary/efl_ui_tab_pager.eo \ + lib/elementary/efl_ui_tab_bar.eo \ + lib/elementary/efl_ui_tab_page.eo \ + lib/elementary/efl_ui_tab_page_part_tab.eo \ $(NULL) # More public files -- FIXME @@ -428,7 +432,10 @@ includesunstable_HEADERS = \ lib/elementary/efl_page_transition.h \ lib/elementary/efl_page_transition_scroll.h \ lib/elementary/efl_page_indicator.h \ - lib/elementary/efl_page_indicator_icon.h + lib/elementary/efl_page_indicator_icon.h \ + lib/elementary/efl_ui_tab_pager_private.h \ + lib/elementary/efl_ui_tab_bar_private.h \ + lib/elementary/efl_ui_tab_page_private.h includesunstabledir = $(includedir)/elementary-@VMAJ@ nodist_includesunstable_HEADERS = \ @@ -848,6 +855,9 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_page_indicator.c \ lib/elementary/efl_page_indicator_icon.c \ lib/elementary/efl_ui_focus_graph.c \ + lib/elementary/efl_ui_tab_pager.c \ + lib/elementary/efl_ui_tab_bar.c \ + lib/elementary/efl_ui_tab_page.c \ $(NULL) @@ -1062,6 +1072,7 @@ bin/elementary/test_efl_ui_text.c \ bin/elementary/test_win_stack.c \ bin/elementary/test_win_indicator.c \ bin/elementary/test_gesture_framework.c \ +bin/elementary/test_ui_tab_pager.c \ bin/elementary/test.h bin_elementary_elementary_test_LDADD = @USE_ELEMENTARY_LIBS@ diff --git a/src/bin/elementary/Makefile.am b/src/bin/elementary/Makefile.am index 0874ccd64f..8828276e26 100644 --- a/src/bin/elementary/Makefile.am +++ b/src/bin/elementary/Makefile.am @@ -159,6 +159,7 @@ test_win_state.c \ test_win_wm_rotation.c \ test_win_dialog.c \ test_gesture_framework.c \ +test_ui_tab_pager.c \ test.h elementary_test_LDADD = $(top_builddir)/src/lib/libelementary.la \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index bc105decb8..f34be34e71 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -366,6 +366,8 @@ void test_efl_anim_interpolator(void *data, Evas_Object *obj, void *event_info); void test_gesture_framework(void *data, Evas_Object *obj, void *event_info); +void test_ui_tab_pager(void *data, Evas_Object *obj, void *event_info); + static void _list_udpate(void); static Evas_Object *win, *tbx, *entry; // TODO: refactoring @@ -1060,6 +1062,9 @@ add_tests: ADD_TEST(NULL, "Booleans", "Check", test_check); ADD_TEST(NULL, "Booleans", "Check Toggle", test_check_toggle); + //------------------------------// + ADD_TEST_EO(NULL, "Tab Pager", "Efl.Ui.Tab_Pager", test_ui_tab_pager); + //------------------------------// ADD_TEST(NULL, "Popups", "Ctxpopup", test_ctxpopup); ADD_TEST(NULL, "Popups", "Hover", test_hover); diff --git a/src/bin/elementary/test_ui_tab_pager.c b/src/bin/elementary/test_ui_tab_pager.c new file mode 100644 index 0000000000..1ed8dba8df --- /dev/null +++ b/src/bin/elementary/test_ui_tab_pager.c @@ -0,0 +1,591 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + +#define TAB_PAGE_NUM 5 +#define TAB_LABEL_COUNT 15 +#define TAB_ICON_COUNT 9 + +typedef struct _App_Data { + Evas_Object *navi; + Eo *tab_pager; +} App_Data; + +typedef struct _Tab_Set_Data { + Eo *tab_pager; + Eo *spinner; +} Tab_Set_Data; + +typedef struct _Tab_Change_Data { + Eo *tab_pager; + Eo *label_check; + Eo *icon_check; +} Tab_Change_Data; + +static void _current_cb(void *data, Evas_Object *obj, void *event_info); +static void _pack_cb(void *data, Evas_Object *obj, void *event_info); +static void _unpack_cb(void *data, Evas_Object *obj, void *event_info); +static void _tab_cb(void *data, Evas_Object *obj, void *event_info); +static void _transition_cb(void *data, Evas_Object *obj, void *event_info); +static void _win_del_cb(void *data, const Efl_Event *ev); + +static char *tab_labels[] = { + "efl", "elementary", "ecore", "evas", "eina", + "eo", "eolian", "embryo", "ethumb", "evil", + "eet", "edje", "ector", "efreet", "eldbus" +}; + +static char *tab_icons[] = { + "document-print", "folder-new", "object-rotate-right", + "mail-send", "edit-cut", "edit-copy", + "edit-paste", "edit-delete", "clock" +}; + +static char *tab_label_get() +{ + int index = rand() % (TAB_LABEL_COUNT - 1); + return tab_labels[index]; +} + +static char *tab_icon_get() +{ + int index = rand() % (TAB_ICON_COUNT - 1); + return tab_icons[index]; +} + +static void +_tab_changed_cb(void *data EINA_UNUSED, const Efl_Event *event) +{ + Efl_Ui_Tab_Page_Tab_Changed_Event *ev = event->info; + + switch (ev->changed_info) + { + case EFL_UI_TAB_PAGE_TAB_CHANGED_LABEL: + printf("[%p] tab label changed\n", event->object); + break; + + case EFL_UI_TAB_PAGE_TAB_CHANGED_ICON: + printf("[%p] tab icon changed\n", event->object); + break; + + default: + break; + } +} + +Eo * +content_add(Eo *parent, char *text) +{ + Eo *page; + char buf[PATH_MAX]; + page = efl_add(EFL_UI_LAYOUT_OBJECT_CLASS, parent); + + snprintf(buf, sizeof(buf), "%s/objects/test_tab_pager.edj", elm_app_data_dir_get()); + + page = efl_add(EFL_UI_LAYOUT_OBJECT_CLASS, parent, + efl_file_set(efl_added, buf, "page_layout"), + efl_text_set(efl_part(efl_added, "text"), text), + efl_gfx_size_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND), + efl_gfx_size_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL)); + + return page; +} + +Eo * +tab_page_add(Eo *parent) +{ + Eo *tab_page; + char *label = tab_label_get(); + char *icon = tab_icon_get(); + Eo *content = content_add(parent, label); + + tab_page = efl_add(EFL_UI_TAB_PAGE_CLASS, parent); + efl_content_set(tab_page, content); + efl_text_set(efl_part(tab_page, "tab"), label); + efl_ui_tab_page_part_tab_icon_set(efl_part(tab_page, "tab"), icon); + + efl_event_callback_add(tab_page, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, NULL); + + return tab_page; +} + +void +test_ui_tab_pager(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eo *win, *layout, *navi, *list, *tp, *tb, *page; + //Efl_Page_Transition *tran; + App_Data *ad = NULL; + char buf[PATH_MAX]; + int i; + + win = efl_add(EFL_UI_WIN_CLASS, efl_main_loop_get(), + efl_ui_win_type_set(efl_added, EFL_UI_WIN_BASIC), + efl_text_set(efl_added, "Efl.Ui.Tab_Pager"), + efl_ui_win_autodel_set(efl_added, EINA_TRUE), + efl_event_callback_add(efl_added, EFL_EVENT_DEL, _win_del_cb, ad)); + + snprintf(buf, sizeof(buf), "%s/objects/test_tab_pager.edj", elm_app_data_dir_get()); + layout = efl_add(EFL_UI_LAYOUT_OBJECT_CLASS, win, + efl_file_set(efl_added, buf, "tab_page_layout"), + efl_content_set(win, efl_added)); + + navi = elm_naviframe_add(layout); + efl_gfx_size_hint_weight_set(navi, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + efl_gfx_size_hint_align_set(navi, EVAS_HINT_FILL, EVAS_HINT_FILL); + efl_content_set(efl_part(layout, "menu"), navi); + + list = elm_list_add(navi); + efl_gfx_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + efl_gfx_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_list_select_mode_set(list, ELM_OBJECT_SELECT_MODE_ALWAYS); + elm_naviframe_item_push(navi, "Properties", NULL, NULL, list, NULL); + efl_gfx_entity_visible_set(list, EINA_TRUE); + + tp = efl_add(EFL_UI_TAB_PAGER_CLASS, layout, + efl_gfx_size_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND), + efl_gfx_size_hint_align_set(efl_added, EVAS_HINT_FILL, EVAS_HINT_FILL), + efl_ui_pager_page_size_set(efl_added, EINA_SIZE2D(-1, -1)), + efl_ui_pager_padding_set(efl_added, 20), + efl_content_set(efl_part(layout, "tab_pager"), efl_added)); + + tb = efl_add(EFL_UI_TAB_BAR_CLASS, tp); + efl_ui_tab_pager_tab_bar_set(tp, tb); + +/* + tran = efl_add(EFL_PAGE_TRANSITION_SCROLL_CLASS, tp) + efl_ui_pager_transition_set(tp, tran); +*/ + + for (i = 0 ; i < 3 ; i ++) + { + page = tab_page_add(tp); + efl_pack_end(tp, page); + } + + efl_ui_pager_current_page_set(tp, 0); + + ad = calloc(1, sizeof(ad)); + ad->navi = navi; + ad->tab_pager = tp; + + elm_list_item_append(list, "Current", NULL, NULL, _current_cb, ad); + elm_list_item_append(list, "Pack", NULL, NULL, _pack_cb, ad); + elm_list_item_append(list, "Unpack", NULL, NULL, _unpack_cb, ad); + elm_list_item_append(list, "Tab", NULL, NULL, _tab_cb, ad); + elm_list_item_append(list, "Transition", NULL, NULL, _transition_cb, ad); + elm_list_go(list); + + efl_gfx_entity_size_set(win, EINA_SIZE2D(500, 300)); +} + +/* Menu Callback */ + +static void +_win_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + free(data); +} + +static void +_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + elm_naviframe_item_pop(data); +} + +static void +_tab_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Tab_Set_Data *tsd = data; + efl_ui_pager_current_page_set(tsd->tab_pager, elm_spinner_value_get(tsd->spinner)); +} + +static void +_tab_set_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + free(data); +} + +static void +_current_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + App_Data *ad = (App_Data *) data; + Evas_Object *navi = ad->navi; + Eo *tab_pager = ad->tab_pager; + Eo *btn, *box, *sp; + Tab_Set_Data *tsd = calloc(1, sizeof(Tab_Set_Data)); + + Elm_List_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); + + btn = efl_add(EFL_UI_BUTTON_CLASS, navi, + efl_text_set(efl_added, "Back"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_cb, navi)); + + box = efl_add(EFL_UI_BOX_CLASS, navi, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + elm_naviframe_item_push(navi, "Current", btn, NULL, efl_added, NULL)); + + sp = efl_add(EFL_UI_SPIN_BUTTON_CLASS, box, + efl_ui_range_min_max_set(efl_added, 0, efl_content_count(tab_pager) - 1), + efl_ui_range_value_set(efl_added, efl_ui_pager_current_page_get(tab_pager)), + efl_pack_end(box, efl_added)); + + tsd->tab_pager = tab_pager; + tsd->spinner = sp; + + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Current Tab Page Set"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _tab_set_btn_cb, tsd), + efl_event_callback_add(efl_added, EFL_EVENT_DEL, _tab_set_btn_del_cb, tsd), + efl_pack_end(box, efl_added)); +} + +static void +_pack_begin_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + Eo *tab_page; + + tab_page = tab_page_add(tab_pager); + + efl_pack_begin(tab_pager, tab_page); +} + +static void +_pack_end_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + Eo *tab_page; + + tab_page = tab_page_add(tab_pager); + + efl_pack_end(tab_pager, tab_page); +} + +static void +_pack_before_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + Eo *tab_page, *cur_tab_page; + int index; + + index = efl_ui_pager_current_page_get(tab_pager); + cur_tab_page = efl_pack_content_get(tab_pager, index); + + tab_page = tab_page_add(tab_pager); + + efl_pack_before(tab_pager, tab_page, cur_tab_page); +} + +static void +_pack_after_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + Eo *tab_page, *cur_tab_page; + int index; + + index = efl_ui_pager_current_page_get(tab_pager); + cur_tab_page = efl_pack_content_get(tab_pager, index); + + tab_page = tab_page_add(tab_pager); + + efl_pack_after(tab_pager, tab_page, cur_tab_page); +} + +static void +_pack_at_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Tab_Set_Data *tsd = data; + Eo *tab_page; + + tab_page = tab_page_add(tsd->tab_pager); + + efl_pack_at(tsd->tab_pager, tab_page, elm_spinner_value_get(tsd->spinner)); + efl_ui_range_min_max_set(tsd->spinner, 0, efl_content_count(tsd->tab_pager) - 1); +} + +static void +_pack_at_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + free(data); +} + +static void +_pack_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + App_Data *ad = (App_Data *) data; + Evas_Object *navi = ad->navi; + Eo *tab_pager = ad->tab_pager; + Eo *btn, *box, *in_box, *sp; + Tab_Set_Data *tsd = calloc(1, sizeof(Tab_Set_Data)); + + Elm_List_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); + + btn = efl_add(EFL_UI_BUTTON_CLASS, navi, + efl_text_set(efl_added, "Back"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_cb, navi)); + + box = efl_add(EFL_UI_BOX_CLASS, navi, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + elm_naviframe_item_push(navi, "Pack", btn, NULL, efl_added, NULL)); + + /* Pack Begin */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Pack Begin"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _pack_begin_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + /* Pack End */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Pack End"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _pack_end_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + /* Pack Before */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Pack Before Current Tab Page"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _pack_before_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + /* Pack After */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Pack After Current Tab Page"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _pack_after_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + in_box = efl_add(EFL_UI_BOX_CLASS, box, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL), + efl_pack_end(box, efl_added)); + + sp = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box, + efl_ui_range_min_max_set(efl_added, 0, efl_content_count(tab_pager) - 1), + efl_ui_range_value_set(efl_added, efl_ui_pager_current_page_get(tab_pager)), + efl_pack_end(in_box, efl_added)); + + tsd->tab_pager = tab_pager; + tsd->spinner = sp; + + /* Pack At */ + btn = efl_add(EFL_UI_BUTTON_CLASS, in_box, + efl_text_set(efl_added, "Pack At"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _pack_at_btn_cb, tsd), + efl_event_callback_add(efl_added, EFL_EVENT_DEL, _pack_at_btn_del_cb, tsd), + efl_pack_end(in_box, efl_added)); +} + +static void +_clear_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + efl_pack_clear(tab_pager); +} + +static void +_unpack_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + int index = efl_ui_pager_current_page_get(tab_pager); + Eo *tab_page = efl_pack_content_get(tab_pager, index); + efl_pack_unpack(tab_pager, tab_page); +} + +static void +_unpack_all_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Eo *tab_pager = data; + efl_pack_unpack_all(tab_pager); +} + +static void +_unpack_at_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Tab_Set_Data *tsd = data; + + efl_pack_unpack_at(tsd->tab_pager, elm_spinner_value_get(tsd->spinner)); + efl_ui_range_min_max_set(tsd->spinner, 0, efl_content_count(tsd->tab_pager) - 1); +} + +static void +_unpack_at_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + free(data); +} + +static void +_unpack_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + App_Data *ad = (App_Data *) data; + Evas_Object *navi = ad->navi; + Eo *tab_pager = ad->tab_pager; + Eo *btn, *box, *sp, *in_box; + Tab_Set_Data *tsd = calloc(1, sizeof(Tab_Set_Data)); + + Elm_List_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); + + btn = efl_add(EFL_UI_BUTTON_CLASS, navi, + efl_text_set(efl_added, "Back"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_cb, navi)); + + box = efl_add(EFL_UI_BOX_CLASS, navi, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + elm_naviframe_item_push(navi, "Unpack", btn, NULL, efl_added, NULL)); + + /* Clear */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Clear"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _clear_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + /* Unpack */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Unpack"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _unpack_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + /* Unpack All */ + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Unpack All"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _unpack_all_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + in_box = efl_add(EFL_UI_BOX_CLASS, box, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + efl_ui_direction_set(efl_added, EFL_UI_DIR_HORIZONTAL), + efl_pack_end(box, efl_added)); + + sp = efl_add(EFL_UI_SPIN_BUTTON_CLASS, in_box, + efl_ui_range_min_max_set(efl_added, 0, efl_content_count(tab_pager) - 1), + efl_ui_range_value_set(efl_added, efl_ui_pager_current_page_get(tab_pager)), + efl_pack_end(in_box, efl_added)); + + tsd->tab_pager = tab_pager; + tsd->spinner = sp; + + /* Unpack At */ + btn = efl_add(EFL_UI_BUTTON_CLASS, in_box, + efl_text_set(efl_added, "Unpack At"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _unpack_at_btn_cb, tsd), + efl_event_callback_add(efl_added, EFL_EVENT_DEL, _unpack_at_btn_del_cb, tsd), + efl_pack_end(in_box, efl_added)); +} + +static void +_change_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Tab_Change_Data *tcd = data; + + Eo *tab_page, *content; + char *label = NULL; + char *icon = NULL; + int cur; + cur = efl_ui_pager_current_page_get(tcd->tab_pager); + tab_page = efl_pack_content_get(tcd->tab_pager, cur); + + if (efl_ui_nstate_value_get(tcd->label_check)) + { + label = tab_label_get(); + efl_text_set(efl_part(tab_page, "tab"), label); + content = content_add(tab_page, label); + efl_content_set(tab_page, content); + } + + if (efl_ui_nstate_value_get(tcd->icon_check)) + { + icon = tab_icon_get(); + efl_ui_tab_page_part_tab_icon_set(efl_part(tab_page, "tab"), icon); + } +} + +static void +_change_btn_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + free(data); +} + +static void +_tab_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + App_Data *ad = (App_Data *) data; + Evas_Object *navi = ad->navi; + Eo *tab_pager = ad->tab_pager; + Eo *btn, *box, *label_check, *icon_check; + Tab_Change_Data *tcd = calloc(1, sizeof(Tab_Change_Data)); + + Elm_List_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); + + btn = efl_add(EFL_UI_BUTTON_CLASS, navi, + efl_text_set(efl_added, "Back"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_cb, navi)); + + box = efl_add(EFL_UI_BOX_CLASS, navi, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + elm_naviframe_item_push(navi, "Tab", btn, NULL, efl_added, NULL)); + + label_check = efl_add(EFL_UI_CHECK_CLASS, box, + efl_text_set(efl_added, "Tab Label + Page"), + efl_ui_nstate_value_set(efl_added, EINA_FALSE), + efl_pack_end(box, efl_added)); + + icon_check = efl_add(EFL_UI_CHECK_CLASS, box, + efl_text_set(efl_added, "Tab Icon"), + efl_ui_nstate_value_set(efl_added, EINA_FALSE), + efl_pack_end(box, efl_added)); + + tcd->tab_pager = tab_pager; + tcd->label_check = label_check; + tcd->icon_check = icon_check; + + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Change"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _change_btn_cb, tcd), + efl_event_callback_add(efl_added, EFL_EVENT_DEL, _change_btn_del_cb, tcd), + efl_pack_end(box, efl_added)); +} + +static void +_tran_set_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + Efl_Page_Transition *tran = efl_add(EFL_PAGE_TRANSITION_SCROLL_CLASS, data); + efl_ui_pager_transition_set(data, tran); +} + +static void +_tran_unset_btn_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + efl_ui_pager_transition_set(data, NULL); +} + +static void +_transition_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) +{ + App_Data *ad = (App_Data *) data; + Evas_Object *navi = ad->navi; + Eo *tab_pager = ad->tab_pager; + Eo *btn, *box; + + Elm_List_Item *it = event_info; + elm_list_item_selected_set(it, EINA_FALSE); + + btn = efl_add(EFL_UI_BUTTON_CLASS, navi, + efl_text_set(efl_added, "Back"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _btn_cb, navi)); + + box = efl_add(EFL_UI_BOX_CLASS, navi, + efl_pack_padding_set(efl_added, 10, 10, EINA_TRUE), + elm_naviframe_item_push(navi, "Transition", btn, NULL, efl_added, NULL)); + + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Set"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _tran_set_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); + + btn = efl_add(EFL_UI_BUTTON_CLASS, box, + efl_text_set(efl_added, "Unset"), + efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _tran_unset_btn_cb, tab_pager), + efl_pack_end(box, efl_added)); +} diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 0c9cb665f3..1b5a2a7a9b 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -362,6 +362,11 @@ typedef Eo Efl_Ui_Pager; # include # include # include + +# include +# include +# include +# include #endif /* include deprecated calls last of all */ diff --git a/src/lib/elementary/efl_ui_tab_bar.c b/src/lib/elementary/efl_ui_tab_bar.c new file mode 100644 index 0000000000..ffbc1fdbce --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_bar.c @@ -0,0 +1,392 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#define EFL_UI_TAB_BAR_BETA + +#include +#include "elm_priv.h" +#include "efl_ui_tab_bar_private.h" +#include "els_box.h" + +#define MY_CLASS EFL_UI_TAB_BAR_CLASS + +static const char PART_NAME_TAB[] = "tab"; + +static void _tab_select(Efl_Ui_Tab_Bar_Data *sd, Tab_Info *ti); + +EOLIAN static void +_efl_ui_tab_bar_current_tab_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *sd, int index) +{ + Tab_Info *ti; + ti = eina_list_nth(sd->tab_infos, index); + + _tab_select(sd, ti); +} + +EOLIAN static int +_efl_ui_tab_bar_current_tab_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *sd) +{ + return sd->cur; +} + +EOLIAN static unsigned int +_efl_ui_tab_bar_tab_count(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *sd) +{ + return sd->cnt; +} + +static void +_tab_icon_update(Tab_Info *ti) +{ + Eo *old_icon = + efl_content_get(efl_part(ti->tab, "efl.icon")); + + _elm_widget_sub_object_redirect_to_top(ti->tab, old_icon); + efl_content_unset(efl_part(ti->tab, "efl.icon")); + efl_content_set(efl_part(ti->tab, "efl.icon"), ti->icon); + + if (ti->icon) + efl_layout_signal_emit(ti->tab, "efl,state,icon,visible", "efl"); + else + efl_layout_signal_emit(ti->tab, "efl,state,icon,hidden", "efl"); + + efl_del(old_icon); +} + +static void +_tab_icon_set_cb(void *data, + Eo *obj, + const char *emission, + const char *source) +{ + Tab_Info *ti = data; + _tab_icon_update(ti); + + efl_layout_signal_callback_del(obj, emission, source, _tab_icon_set_cb, NULL); + efl_layout_signal_emit(ti->tab, "efl,state,icon,reset", "efl"); +} + +static void +_tab_icon_obj_set(Eo *obj, + Tab_Info *ti, + Eo *icon_obj, + const char *icon_str, + const char *sig) +{ + Eo *old_icon; + const char *s; + + if (icon_str) + eina_stringshare_replace(&ti->icon_str, icon_str); + else + { + eina_stringshare_del(ti->icon_str); + ti->icon_str = NULL; + } + + ti->icon = icon_obj; + if (icon_obj) + { + efl_gfx_entity_visible_set(ti->icon, EINA_TRUE); + elm_widget_sub_object_add(obj, ti->icon); + } + + s = elm_layout_data_get(ti->tab, "transition_animation_on"); + if ((s) && (atoi(s))) + { + old_icon = efl_content_get + (efl_part(ti->tab, "efl.icon_new")); + if (old_icon) + { + _elm_widget_sub_object_redirect_to_top(ti->tab, old_icon); + efl_gfx_entity_visible_set(old_icon, EINA_FALSE); + } + efl_content_set + (efl_part(ti->tab, "efl.icon_new"), ti->icon); + efl_layout_signal_emit(ti->tab, sig, "efl"); + efl_layout_signal_callback_add + (ti->tab, "efl,state,icon_set,done", "efl", _tab_icon_set_cb, ti); + } + else + _tab_icon_update(ti); +} + +static Eina_Bool +_tab_icon_set(Eo *icon_obj, + const char *type, + const char *icon) +{ + char icon_str[512]; + + if ((!type) || (!*type)) goto end; + if ((!icon) || (!*icon)) return EINA_FALSE; + if ((snprintf(icon_str, sizeof(icon_str), "%s%s", type, icon) > 0) + && (elm_icon_standard_set(icon_obj, icon_str))) + return EINA_TRUE; +end: + if (elm_icon_standard_set(icon_obj, icon)) + return EINA_TRUE; + + WRN("couldn't find icon definition for '%s'", icon); + return EINA_FALSE; +} + +static void +_tab_unselect(Efl_Ui_Tab_Bar_Data *sd, Tab_Info *ti) +{ + if ((!ti->tab) || (!ti->selected)) return; + + ti->selected = EINA_FALSE; + + efl_layout_signal_emit(ti->tab, "efl,state,unselected", "efl"); + if (ti->icon) + elm_widget_signal_emit(ti->icon, "efl,state,unselected", "efl"); + + sd->cur = -1; +} + +static void +_tab_select(Efl_Ui_Tab_Bar_Data *sd, Tab_Info *ti) +{ + if (!ti->selected) + { + Eo *tp; + tp = efl_parent_get(ti->tab); + int index; + + _tab_unselect(sd, sd->selected_tab); + ti->selected = EINA_TRUE; + sd->selected_tab = ti; + + efl_layout_signal_emit(ti->tab, "efl,state,selected", "efl"); + if (ti->icon) + elm_widget_signal_emit(ti->icon, "efl,state,selected", "efl"); + + index = eina_list_data_idx(sd->tab_infos, ti); + + efl_event_callback_call(tp, EFL_UI_EVENT_SELECTED, (void *)(intptr_t)index); + + sd->cur = index; + } +} + +static void +_action_click_cb(void *data, + Eo *obj EINA_UNUSED, + const char *emission EINA_UNUSED, + const char *source EINA_UNUSED) +{ + Eo *tb; + Tab_Info *ti; + ti = data; + tb = efl_parent_get(ti->tab); + EFL_UI_TAB_BAR_DATA_GET(tb, sd); + + _tab_select(sd, ti); +} + +static Tab_Info * +_tab_add(Eo *obj, const char *label, const char *icon) +{ + Eo *tab, *icon_obj; + Tab_Info *ti; + Efl_Ui_Theme_Apply theme_apply; + + ti = calloc(1, sizeof(*ti)); + + ti->tab = NULL; + ti->label = eina_stringshare_add(label); + + tab = efl_add(EFL_UI_LAYOUT_OBJECT_CLASS, obj); + + icon_obj = elm_icon_add(tab); + + if (_tab_icon_set(icon_obj, "toolbar/", icon)) + { + ti->icon = icon_obj; + ti->icon_str = eina_stringshare_add(icon); + } + else + { + ti->icon = NULL; + ti->icon_str = NULL; + efl_del(icon_obj); + } + + theme_apply = elm_widget_element_update(obj, tab, PART_NAME_TAB); + + if (theme_apply == EFL_UI_THEME_APPLY_FAILED) + CRI("Failed to set layout!"); + + efl_layout_signal_callback_add + (tab, "efl,action,click", "efl", _action_click_cb, ti); + + if (ti->icon) + { + efl_content_set(efl_part(tab, "efl.icon"), ti->icon); + efl_layout_signal_emit(tab, "efl,state,icon,visible", "efl"); + efl_layout_signal_emit(tab, "efl,icon,visible", "efl"); + efl_gfx_entity_visible_set(ti->icon, EINA_TRUE); + } + else + { + efl_layout_signal_emit(tab, "efl,state,icon,hidden", "efl"); + efl_layout_signal_emit(tab, "efl,icon,hidden", "efl"); + } + + if (ti->label) + { + efl_text_set(efl_part(tab, "efl.text"), ti->label); + efl_layout_signal_emit(tab, "efl,state,text,visible", "efl"); + efl_layout_signal_emit(tab, "efl,text,visible", "efl"); + } + else + { + efl_layout_signal_emit(tab, "efl,state,text,hidden", "efl"); + efl_layout_signal_emit(tab, "efl,text,hidden", "efl"); + } + + efl_ui_widget_focus_allow_set(tab, EINA_TRUE); + + ti->tab = tab; + + return ti; +} + +EOLIAN static void +_efl_ui_tab_bar_tab_add(Eo *obj, Efl_Ui_Tab_Bar_Data *sd, + int index, const char *label, const char *icon) +{ + Tab_Info *ti; + ti = _tab_add(obj, label, icon); + + efl_parent_set(ti->tab, obj); + efl_ui_widget_sub_object_add(obj, ti->tab); + + if (sd->cnt > index) + { + Tab_Info *existing_ti; + existing_ti = eina_list_nth(sd->tab_infos, index); + + sd->tab_infos = eina_list_prepend_relative(sd->tab_infos, ti, existing_ti); + evas_object_box_insert_before(sd->bx, ti->tab, existing_ti->tab); + + if (sd->cur >= index) sd->cur ++; + } + else + { + sd->tab_infos = eina_list_append(sd->tab_infos, ti); + evas_object_box_append(sd->bx, ti->tab); + } + + sd->cnt ++; +} + +EOLIAN static void +_efl_ui_tab_bar_tab_remove(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *sd, int index) +{ + if ((sd->cnt > 0) && (sd->cnt > index) && (index >= 0)) + { + Tab_Info *ti; + ti = eina_list_nth(sd->tab_infos, index); + + _tab_unselect(sd, ti); + evas_object_box_remove(sd->bx, ti->tab); + efl_del(ti->tab); + efl_del(ti->icon); + + sd->tab_infos = eina_list_remove(sd->tab_infos, ti); + sd->cnt --; + } +} + +EOLIAN static void +_efl_ui_tab_bar_tab_label_set(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Bar_Data *sd, int index, const char *label) +{ + Tab_Info *ti; + ti = eina_list_nth(sd->tab_infos, index); + eina_stringshare_replace(&ti->label, label); + + efl_text_set(efl_part(ti->tab, "efl.text"), ti->label); +} + +EOLIAN static void +_efl_ui_tab_bar_tab_icon_set(Eo *obj, Efl_Ui_Tab_Bar_Data *sd, int index, const char *icon) +{ + Eo *icon_obj; + Tab_Info *ti; + ti = eina_list_nth(sd->tab_infos, index); + + if ((icon) && (ti->icon_str) && (!strcmp(icon, ti->icon_str))) return; + + icon_obj = elm_icon_add(obj); + if (!icon_obj) return; + if (_tab_icon_set(icon_obj, "toolbar/", icon)) + _tab_icon_obj_set(obj, ti, icon_obj, icon, "efl,state,icon_set"); + else + { + _tab_icon_obj_set(obj, ti, NULL, NULL, "efl,state,icon_set"); + efl_del(icon_obj); + } +} + +static void +_layout(Evas_Object *o, + Evas_Object_Box_Data *priv, + void *data) +{ + Evas_Object *obj = (Evas_Object *)data; + Eina_Bool horizontal; + + EFL_UI_TAB_BAR_DATA_GET(obj, sd); + + horizontal = efl_ui_dir_is_horizontal(sd->dir, EINA_TRUE); + + _els_box_layout + (o, priv, horizontal, EINA_TRUE, efl_ui_mirrored_get(obj)); +} + +EOLIAN static void +_efl_ui_tab_bar_efl_object_destructor(Eo *obj, Efl_Ui_Tab_Bar_Data *sd EINA_UNUSED) +{ + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Object * +_efl_ui_tab_bar_efl_object_constructor(Eo *obj, Efl_Ui_Tab_Bar_Data *sd) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); + + if (!elm_widget_theme_klass_get(obj)) + elm_widget_theme_klass_set(obj, "tab_bar"); + + obj = efl_constructor(efl_super(obj, MY_CLASS)); + + 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!"); + + elm_widget_sub_object_parent_add(obj); + + sd->dir = EFL_UI_DIR_HORIZONTAL; + sd->bx = evas_object_box_add(evas_object_evas_get(obj)); + evas_object_box_align_set(sd->bx, 0.5, 0.5); + evas_object_box_layout_set(sd->bx, _layout, obj, NULL); + + efl_ui_widget_focus_allow_set(obj, EINA_TRUE); + + efl_content_set(efl_part(obj, "efl.content"), sd->bx); + + sd->cnt = 0; + sd->cur = -1; + + Tab_Info *ti = calloc(1, sizeof(*ti)); + sd->selected_tab = ti; + + return obj; +} + +#include "efl_ui_tab_bar.eo.c" diff --git a/src/lib/elementary/efl_ui_tab_bar.eo b/src/lib/elementary/efl_ui_tab_bar.eo new file mode 100644 index 0000000000..ea07a4d051 --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_bar.eo @@ -0,0 +1,42 @@ +class Efl.Ui.Tab_Bar (Efl.Ui.Layout.Object, Efl.Ui.Clickable) +{ + [[Tab Bar class]] + methods { + @property current_tab { + values { + index: int; + } + } + tab_count @const { + return: uint; + } + tab_add @beta { + params { + @in index: int; + @in label: string; + @in icon: string; + } + } + tab_remove @beta { + params { + @in index: int; + } + } + tab_label_set @beta { + params { + @in index: int; + @in label: string; + } + } + tab_icon_set @beta { + params { + @in index: int; + @in icon: string; + } + } + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + } +} \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_bar_private.h b/src/lib/elementary/efl_ui_tab_bar_private.h new file mode 100644 index 0000000000..7e11cf017d --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_bar_private.h @@ -0,0 +1,43 @@ +#ifndef EFL_UI_TAB_BAR_PRIVATE_H +#define EFL_UI_TAB_BAR_PRIVATE_H + +typedef struct _Efl_Ui_Tab_Bar_Data Efl_Ui_Tab_Bar_Data; +typedef struct _Tab_Info Tab_Info; + +struct _Efl_Ui_Tab_Bar_Data +{ + Efl_Canvas_Object *bx; + int cnt; + int cur; + Efl_Ui_Dir dir; + + Eina_List *tab_infos; + Tab_Info *selected_tab; +}; + +struct _Tab_Info +{ + Eo *tab; + + const char *label; + const char *icon_str; + Eo *icon; + + Eina_Bool selected : 1; +}; + + +#define EFL_UI_TAB_BAR_DATA_GET(o, sd) \ + Efl_Ui_Tab_Bar_Data *sd = efl_data_scope_get(o, EFL_UI_TAB_BAR_CLASS) + +#define EFL_UI_TAB_BAR_DATA_GET_OR_RETURN(o, sd, ...) \ + Efl_Ui_Tab_Bar_Data *sd = efl_data_scope_safe_get(o, EFL_UI_TAB_BAR_CLASS); \ + if (EINA_UNLIKELY(!sd)) \ + { \ + ERR("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return __VA_ARGS__; \ + } + + +#endif diff --git a/src/lib/elementary/efl_ui_tab_page.c b/src/lib/elementary/efl_ui_tab_page.c new file mode 100644 index 0000000000..79c52b480f --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_page.c @@ -0,0 +1,129 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include +#include "elm_priv.h" +#include "efl_ui_tab_page_private.h" +#include "elm_part_helper.h" + +#define MY_CLASS EFL_UI_TAB_PAGE_CLASS + +EOLIAN static Eina_Bool +_efl_ui_tab_page_efl_content_content_set(Eo *obj, Efl_Ui_Tab_Page_Data *sd, Eo *content) +{ + if (sd->content) + { + efl_content_unset(efl_part(obj, "efl.content")); + efl_del(sd->content); + } + + sd->content = content; + efl_content_set(efl_part(obj, "efl.content"), sd->content); + + return EINA_TRUE; +} + +EOLIAN static Eo * +_efl_ui_tab_page_efl_content_content_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Page_Data *sd) +{ + return sd->content; +} + +EOLIAN static Efl_Object * +_efl_ui_tab_page_efl_object_constructor(Eo *obj, Efl_Ui_Tab_Page_Data *sd) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); + + if (!elm_widget_theme_klass_get(obj)) + elm_widget_theme_klass_set(obj, "tab_page"); + + obj = efl_constructor(efl_super(obj, MY_CLASS)); + + 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!"); + + elm_widget_sub_object_parent_add(obj); + + efl_ui_widget_focus_allow_set(obj, EINA_TRUE); + + sd->content = NULL; + sd->tab_label = NULL; + sd->tab_icon = NULL; + + return obj; +} + +EOLIAN static void +_efl_ui_tab_page_efl_object_destructor(Eo *obj, Efl_Ui_Tab_Page_Data *sd EINA_UNUSED) +{ + efl_destructor(efl_super(obj, MY_CLASS)); +} + +/* Efl.Part begin */ + +EOLIAN static Eo * +_efl_ui_tab_page_efl_part_part(const Eo *obj, Efl_Ui_Tab_Page_Data *sd EINA_UNUSED, const char *part) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL); + + if (eina_streq(part, "tab")) + return ELM_PART_IMPLEMENT(EFL_UI_TAB_PAGE_PART_TAB_CLASS, obj, part); + + return efl_part(efl_super(obj, MY_CLASS), part); +} + +EOLIAN static void +_efl_ui_tab_page_part_tab_icon_set(Eo *obj, void *_pd EINA_UNUSED, const char *path) +{ + Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS); + Efl_Ui_Tab_Page_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_TAB_PAGE_CLASS); + + eina_stringshare_replace(&sd->tab_icon, path); + + Efl_Ui_Tab_Page_Tab_Changed_Event event; + event.changed_info = EFL_UI_TAB_PAGE_TAB_CHANGED_ICON; + + efl_event_callback_call(pd->obj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, &event); +} + +EOLIAN static const char * +_efl_ui_tab_page_part_tab_icon_get(const Eo *obj, void *_pd EINA_UNUSED) +{ + Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS); + Efl_Ui_Tab_Page_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_TAB_PAGE_CLASS); + + return sd->tab_icon; +} + +EOLIAN static void +_efl_ui_tab_page_part_tab_efl_text_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *text) +{ + Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS); + Efl_Ui_Tab_Page_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_TAB_PAGE_CLASS); + + eina_stringshare_replace(&sd->tab_label, text); + + Efl_Ui_Tab_Page_Tab_Changed_Event event; + event.changed_info = EFL_UI_TAB_PAGE_TAB_CHANGED_LABEL; + + efl_event_callback_call(pd->obj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, &event); +} + +EOLIAN static const char * +_efl_ui_tab_page_part_tab_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_Tab_Page_Data *sd = efl_data_scope_get(pd->obj, EFL_UI_TAB_PAGE_CLASS); + + return sd->tab_label; +} + +#include "efl_ui_tab_page_part_tab.eo.c" + +/* Efl.Part end */ + +#include "efl_ui_tab_page.eo.c" \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_page.eo b/src/lib/elementary/efl_ui_tab_page.eo new file mode 100644 index 0000000000..75249b816c --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_page.eo @@ -0,0 +1,28 @@ +enum Efl.Ui.Tab_Page.Tab_Changed { + label = 0, [[Label changed]] + icon [[Icon changed]] +} + +struct Efl.Ui.Tab_Page.Tab.Changed_Event { + [[Information of changed event]] + changed_info: Efl.Ui.Tab_Page.Tab_Changed; +} + +class Efl.Ui.Tab_Page (Efl.Ui.Layout.Object, Efl.Content) +{ + [[Tab Page class]] + methods { + } + parts { + tab: Efl.Ui.Tab_Page.Part_Tab; + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Content.content { get; set; } + Efl.Part.part; + } + events { + tab,changed: Efl.Ui.Tab_Page.Tab.Changed_Event; [[Called when tab changed]] + } +} \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_page_part_tab.eo b/src/lib/elementary/efl_ui_tab_page_part_tab.eo new file mode 100644 index 0000000000..b28fd9ae20 --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_page_part_tab.eo @@ -0,0 +1,15 @@ +class Efl.Ui.Tab_Page.Part_Tab (Efl.Ui.Layout.Part, Efl.Text) +{ + [[Tab_Page internal part class]] + data: null; + methods { + @property icon { + values { + path: string; + } + } + } + implements { + Efl.Text.text { get; set; } + } +} \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_page_private.h b/src/lib/elementary/efl_ui_tab_page_private.h new file mode 100644 index 0000000000..44153647c4 --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_page_private.h @@ -0,0 +1,28 @@ +#ifndef EFL_UI_TAB_PAGE_PRIVATE_H +#define EFL_UI_TAB_PAGE_PRIVATE_H + +typedef struct _Efl_Ui_Tab_Page_Data Efl_Ui_Tab_Page_Data; + +struct _Efl_Ui_Tab_Page_Data +{ + Eo *content; + const char *tab_label; + const char *tab_icon; +}; + + +#define EFL_UI_TAB_PAGE_DATA_GET(o, sd) \ + Efl_Ui_Tab_Page_Data *sd = efl_data_scope_get(o, EFL_UI_TAB_PAGE_CLASS) + +#define EFL_UI_TAB_PAGE_DATA_GET_OR_RETURN(o, sd, ...) \ + Efl_Ui_Tab_Page_Data *sd = efl_data_scope_safe_get(o, EFL_UI_TAB_PAGE_CLASS); \ + if (EINA_UNLIKELY(!sd)) \ + { \ + ERR("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return __VA_ARGS__; \ + } + +#include "efl_ui_tab_page_part_tab.eo.h" + +#endif \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_pager.c b/src/lib/elementary/efl_ui_tab_pager.c new file mode 100644 index 0000000000..5fbae19c3c --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_pager.c @@ -0,0 +1,354 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#define EFL_UI_TAB_BAR_BETA + +#include +#include "elm_priv.h" + +#include "efl_ui_tab_pager_private.h" +#include "efl_ui_tab_page_private.h" +#include "efl_ui_widget_pager.h" + +#define MY_CLASS EFL_UI_TAB_PAGER_CLASS + +static void +_select(Eo *obj, int index) +{ + EFL_UI_TAB_PAGER_DATA_GET(obj, sd); + if (sd->cnt > index) sd->cur = index; + else sd->cur = 0; + + efl_ui_tab_bar_current_tab_set(sd->tab_bar, sd->cur); + efl_ui_pager_current_page_set(efl_super(obj, MY_CLASS), sd->cur); +} + +static void +_tab_select_cb(void *data, const Efl_Event *event) +{ + int index = (intptr_t)event->info; + _select(data, index); +} + +static void +_tab_changed_cb(void *data, const Efl_Event *event) +{ + Efl_Ui_Tab_Page_Tab_Changed_Event *ev = event->info; + int index; + + EFL_UI_TAB_PAGER_DATA_GET(data, sd); + EFL_UI_TAB_PAGE_DATA_GET(event->object, pd); + index = eina_list_data_idx(sd->tab_pages, event->object); + + switch (ev->changed_info) + { + case EFL_UI_TAB_PAGE_TAB_CHANGED_LABEL: + efl_ui_tab_bar_tab_label_set(sd->tab_bar, index, pd->tab_label); + break; + + case EFL_UI_TAB_PAGE_TAB_CHANGED_ICON: + efl_ui_tab_bar_tab_icon_set(sd->tab_bar, index, pd->tab_icon); + break; + + default: + break; + } +} + +EOLIAN static void +_efl_ui_tab_pager_tab_bar_set(Eo *obj, Efl_Ui_Tab_Pager_Data *sd, Efl_Canvas_Object *tab_bar) +{ + if (sd->tab_bar != NULL) + { + efl_event_callback_del(sd->tab_bar, EFL_UI_EVENT_SELECTED, _tab_select_cb, obj); + efl_content_unset(efl_part(obj, "efl.tab_root")); + efl_del(sd->tab_bar); + } + + sd->tab_bar = tab_bar; + efl_content_set(efl_part(obj, "efl.tab_root"), sd->tab_bar); + + efl_event_callback_add(sd->tab_bar, EFL_UI_EVENT_SELECTED, _tab_select_cb, obj); +} + +EOLIAN static Efl_Canvas_Object * +_efl_ui_tab_pager_tab_bar_get(const Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd) +{ + return sd->tab_bar; +} + +EOLIAN static void +_efl_ui_tab_pager_efl_ui_pager_current_page_set(Eo *obj, Efl_Ui_Tab_Pager_Data *sd EINA_UNUSED, int index) +{ + _select(obj, index); +} + +EOLIAN static void +_efl_ui_tab_pager_efl_object_destructor(Eo *obj, Efl_Ui_Tab_Pager_Data *sd) +{ + if (sd->tab_bar != NULL) + efl_event_callback_del(sd->tab_bar, EFL_UI_EVENT_SELECTED, _tab_select_cb, obj); + + efl_destructor(efl_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Object * +_efl_ui_tab_pager_efl_object_constructor(Eo *obj, Efl_Ui_Tab_Pager_Data *sd) +{ + if (!elm_widget_theme_klass_get(obj)) + elm_widget_theme_klass_set(obj, "tab_pager"); + + obj = efl_constructor(efl_super(obj, MY_CLASS)); + elm_widget_sub_object_parent_add(obj); + + efl_ui_widget_focus_allow_set(obj, EINA_TRUE); + + sd->tab_bar = NULL; + sd->cur = 0; + sd->cnt = 0; + + return obj; +} + +EOLIAN static int +_efl_ui_tab_pager_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Tab_Pager_Data *sd) +{ + return sd->cnt; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_pack_clear(Eo *obj, Efl_Ui_Tab_Pager_Data *sd) +{ + if (sd->tab_bar) + { + Eo *subobj; + Eina_List *l, *l_next; + int begin_index = 0; + EINA_LIST_FOREACH_SAFE(sd->tab_pages, l, l_next, subobj) + { + efl_event_callback_del(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + sd->tab_pages = eina_list_remove(sd->tab_pages, subobj); + sd->cnt--; + + efl_ui_tab_bar_tab_remove(sd->tab_bar, begin_index); + } + efl_pack_clear(efl_super(obj, MY_CLASS)); + + return EINA_TRUE; + } + return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_unpack_all(Eo *obj, Efl_Ui_Tab_Pager_Data *sd) +{ + if (sd->tab_bar) + { + Eo *subobj; + Eina_List *l, *l_next; + int begin_index = 0; + EINA_LIST_FOREACH_SAFE(sd->tab_pages, l, l_next, subobj) + { + efl_event_callback_del(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + sd->tab_pages = eina_list_remove(sd->tab_pages, subobj); + sd->cnt--; + + efl_ui_tab_bar_tab_remove(sd->tab_bar, begin_index); + } + efl_pack_unpack_all(efl_super(obj, MY_CLASS)); + + return EINA_TRUE; + } + return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_unpack(Eo *obj, Efl_Ui_Tab_Pager_Data *sd, Efl_Gfx_Entity *subobj) +{ + if (sd->tab_bar) + { + efl_event_callback_del(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + int index = eina_list_data_idx(sd->tab_pages, (void *)subobj); + + sd->tab_pages = eina_list_remove(sd->tab_pages, subobj); + sd->cnt--; + + efl_ui_tab_bar_tab_remove(sd->tab_bar, index); + efl_pack_unpack(efl_super(obj, MY_CLASS), subobj); + + + return EINA_TRUE; + } + return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_linear_pack_begin(Eo *obj, + Efl_Ui_Tab_Pager_Data *sd, + Efl_Gfx_Entity *subobj) +{ + if (sd->tab_bar) + { + EFL_UI_TAB_PAGE_DATA_GET(subobj, pd); + int begin_index = 0; + + sd->tab_pages = eina_list_prepend(sd->tab_pages, subobj); + sd->cnt ++; + + efl_ui_tab_bar_tab_add(sd->tab_bar, begin_index, pd->tab_label, pd->tab_icon); + efl_pack_begin(efl_super(obj, MY_CLASS), subobj); + + sd->cur ++; + + efl_event_callback_add(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + return EINA_TRUE; + } + else return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_linear_pack_end(Eo *obj, + Efl_Ui_Tab_Pager_Data *sd, + Efl_Gfx_Entity *subobj) +{ + if (sd->tab_bar) + { + EFL_UI_TAB_PAGE_DATA_GET(subobj, pd); + int end_index = efl_ui_tab_bar_tab_count(sd->tab_bar); + + sd->tab_pages = eina_list_append(sd->tab_pages, subobj); + sd->cnt ++; + + efl_ui_tab_bar_tab_add(sd->tab_bar, end_index, pd->tab_label, pd->tab_icon); + efl_pack_end(efl_super(obj, MY_CLASS), subobj); + + efl_event_callback_add(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + return EINA_TRUE; + } + else return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_linear_pack_before(Eo *obj, + Efl_Ui_Tab_Pager_Data *sd, + Efl_Gfx_Entity *subobj, + const Efl_Gfx_Entity *existing) +{ + if (sd->tab_bar) + { + EFL_UI_TAB_PAGE_DATA_GET(subobj, pd); + int before_index = eina_list_data_idx(sd->tab_pages, (void *)existing); + + sd->tab_pages = eina_list_prepend_relative(sd->tab_pages, subobj, existing); + sd->cnt ++; + + efl_ui_tab_bar_tab_add(sd->tab_bar, before_index, pd->tab_label, pd->tab_icon); + efl_pack_before(efl_super(obj, MY_CLASS), subobj, existing); + + if (sd->cur >= before_index) sd->cur ++; + + efl_event_callback_add(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + return EINA_TRUE; + } + else return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_linear_pack_after(Eo *obj, + Efl_Ui_Tab_Pager_Data *sd, + Efl_Gfx_Entity *subobj, + const Efl_Gfx_Entity *existing) +{ + if (sd->tab_bar) + { + EFL_UI_TAB_PAGE_DATA_GET(subobj, pd); + int after_index = eina_list_data_idx(sd->tab_pages, (void *)existing) + 1; + + sd->tab_pages = eina_list_append_relative(sd->tab_pages, subobj, existing); + sd->cnt ++; + + efl_ui_tab_bar_tab_add(sd->tab_bar, after_index, pd->tab_label, pd->tab_icon); + efl_pack_after(efl_super(obj, MY_CLASS), subobj, existing); + + if (sd->cur > after_index) sd->cur ++; + + efl_event_callback_add(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + return EINA_TRUE; + } + else return EINA_FALSE; +} + +EOLIAN static Eina_Bool +_efl_ui_tab_pager_efl_pack_linear_pack_at(Eo *obj, + Efl_Ui_Tab_Pager_Data *sd, + Efl_Gfx_Entity *subobj, + int index) +{ + if (sd->tab_bar) + { + Efl_Gfx_Entity *existing = NULL; + EFL_UI_TAB_PAGE_DATA_GET(subobj, pd); + + existing = eina_list_nth(sd->tab_pages, index); + sd->tab_pages = eina_list_prepend_relative(sd->tab_pages, subobj, existing); + sd->cnt ++; + + efl_ui_tab_bar_tab_add(sd->tab_bar, index, pd->tab_label, pd->tab_icon); + efl_pack_at(efl_super(obj, MY_CLASS), subobj, index); + + if (sd->cur >= index) sd->cur ++; + + efl_event_callback_add(subobj, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + return EINA_TRUE; + } + else return EINA_FALSE; +} + +EOLIAN static Efl_Gfx_Entity * +_efl_ui_tab_pager_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Tab_Pager_Data *sd, int index) +{ + if (sd->tab_bar) + { + Efl_Gfx_Entity *existing = NULL; + existing = eina_list_nth(sd->tab_pages, index); + if (!existing) return NULL; + + efl_event_callback_del(existing, EFL_UI_TAB_PAGE_EVENT_TAB_CHANGED, _tab_changed_cb, obj); + + sd->tab_pages = eina_list_remove(sd->tab_pages, existing); + sd->cnt--; + + efl_ui_tab_bar_tab_remove(sd->tab_bar, index); + efl_pack_unpack_at(efl_super(obj, MY_CLASS), index); + + return existing; + } + return NULL; +} + +EOLIAN static Efl_Gfx_Entity * +_efl_ui_tab_pager_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, + Efl_Ui_Tab_Pager_Data *sd, + int index) +{ + return eina_list_nth(sd->tab_pages, index); +} + +EOLIAN static int +_efl_ui_tab_pager_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, + Efl_Ui_Tab_Pager_Data *sd, + const Efl_Gfx_Entity *subobj) +{ + return eina_list_data_idx(sd->tab_pages, (void *)subobj); +} + +#include "efl_ui_tab_pager.eo.c" diff --git a/src/lib/elementary/efl_ui_tab_pager.eo b/src/lib/elementary/efl_ui_tab_pager.eo new file mode 100644 index 0000000000..ca469342d3 --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_pager.eo @@ -0,0 +1,28 @@ +class Efl.Ui.Tab_Pager (Efl.Ui.Pager) +{ + [[Tab Pager class]] + methods { + @property tab_bar { + values { + tab_bar: Efl.Canvas.Object; + } + } + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + Efl.Container.content_count; + Efl.Pack.pack_clear; // TODO + Efl.Pack.unpack_all; // TODO + Efl.Pack.unpack; // TODO + Efl.Pack_Linear.pack_begin; + Efl.Pack_Linear.pack_end; + Efl.Pack_Linear.pack_before; + Efl.Pack_Linear.pack_after; + Efl.Pack_Linear.pack_at; + Efl.Pack_Linear.pack_content_get; + Efl.Pack_Linear.pack_index_get; + Efl.Pack_Linear.pack_unpack_at; // TODO + Efl.Ui.Pager.current_page { set; } + } +} \ No newline at end of file diff --git a/src/lib/elementary/efl_ui_tab_pager_private.h b/src/lib/elementary/efl_ui_tab_pager_private.h new file mode 100644 index 0000000000..1a0bfd4bc1 --- /dev/null +++ b/src/lib/elementary/efl_ui_tab_pager_private.h @@ -0,0 +1,28 @@ +#ifndef EFL_UI_TAB_PAGER_PRIVATE_H +#define EFL_UI_TAB_PAGER_PRIVATE_H + +typedef struct _Efl_Ui_Tab_Pager_Data Efl_Ui_Tab_Pager_Data; + +struct _Efl_Ui_Tab_Pager_Data +{ + Eo *tab_bar; + + int cnt; + int cur; + Eina_List *tab_pages; +}; + + +#define EFL_UI_TAB_PAGER_DATA_GET(o, sd) \ + Efl_Ui_Tab_Pager_Data *sd = efl_data_scope_get(o, EFL_UI_TAB_PAGER_CLASS) + +#define EFL_UI_TAB_PAGER_DATA_GET_OR_RETURN(o, sd, ...) \ + Efl_Ui_Tab_Pager_Data *sd = efl_data_scope_safe_get(o, EFL_UI_TAB_PAGER_CLASS); \ + if (EINA_UNLIKELY(!sd)) \ + { \ + ERR("No widget data for object %p (%s)", \ + o, evas_object_type_get(o)); \ + return __VA_ARGS__; \ + } + +#endif