jaehyun pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=c8c7ac8aae0574ad0c6ad56f284c119dfd2709df
commit c8c7ac8aae0574ad0c6ad56f284c119dfd2709df Author: JinYong Park <j4939.p...@samsung.com> Date: Wed Sep 20 19:36:39 2017 +0900 efl_ui_popup_anchor: add Efl.Ui.Popup.Anchor class Summary: Add initial code for Efl.Ui.Popup.Anchor class. It supports adding anchor object to popup. Test Plan: 1. run elementary_test -to efluipopupanchor Reviewers: Jaehyun_Cho, thiepha, herb, jpeg, cedric, woohyun Reviewed By: Jaehyun_Cho Differential Revision: https://phab.enlightenment.org/D5126 --- data/elementary/objects/test.edc | 78 +++++ src/Makefile_Elementary.am | 3 + src/bin/elementary/test.c | 2 + src/bin/elementary/test_popup.c | 116 ++++++++ src/lib/elementary/Elementary.h | 1 + src/lib/elementary/efl_ui_popup_anchor.c | 357 +++++++++++++++++++++++ src/lib/elementary/efl_ui_popup_anchor.eo | 40 +++ src/lib/elementary/efl_ui_popup_anchor_private.h | 18 ++ 8 files changed, 615 insertions(+) diff --git a/data/elementary/objects/test.edc b/data/elementary/objects/test.edc index 834bea4e27..6574ab3adf 100644 --- a/data/elementary/objects/test.edc +++ b/data/elementary/objects/test.edc @@ -933,4 +933,82 @@ collections { } } } + group { "efl_ui_popup_anchor_layout"; + parts { + spacer { "base"; + desc { "default"; + } + } + swallow { "anchor1"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.15 0.25; + rel2.relative: 0.15 0.25; + fixed: 1 1; + min: 50 50; + } + } + swallow { "anchor2"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.75 0.15; + rel2.relative: 0.75 0.15; + fixed: 1 1; + min: 50 50; + } + } + swallow { "anchor3"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.25 0.85; + rel2.relative: 0.25 0.85; + fixed: 1 1; + min: 50 50; + } + } + swallow { "anchor4"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.85 0.75; + rel2.relative: 0.85 0.75; + fixed: 1 1; + min: 50 50; + } + } + swallow { "anchor5"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.45 0.35; + rel2.relative: 0.45 0.35; + fixed: 1 1; + min: 50 50; + } + } + swallow { "anchor6"; + scale; + desc { "default"; + rel.to: "base"; + rel2.relative: 0.0 0.0; + rel1.offset: 150 300; + rel2.offset: 200 350; + fixed: 1 1; + } + } + swallow { "anchor_none"; + scale; + desc { "default"; + rel.to: "base"; + rel1.relative: 0.60 0.45; + rel2.relative: 0.60 0.45; + fixed: 1 1; + min: 70 50; + } + } + } + } } diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index cbee49167e..f62e9f2d9d 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -39,6 +39,7 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_popup_alert_scroll_part.eo \ lib/elementary/efl_ui_popup_alert_text.eo \ lib/elementary/efl_ui_popup_alert_text_part.eo \ + lib/elementary/efl_ui_popup_anchor.eo \ lib/elementary/efl_ui_text_editable.eo \ lib/elementary/efl_ui_text_async.eo \ lib/elementary/efl_ui_textpath.eo \ @@ -295,6 +296,7 @@ includesunstable_HEADERS = \ lib/elementary/efl_ui_popup_alert_private.h \ lib/elementary/efl_ui_popup_alert_scroll_private.h \ lib/elementary/efl_ui_popup_alert_text_private.h \ + lib/elementary/efl_ui_popup_anchor_private.h \ lib/elementary/elm_widget_index.h \ lib/elementary/elm_widget_inwin.h \ lib/elementary/elm_widget_label.h \ @@ -708,6 +710,7 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_popup_alert.c \ lib/elementary/efl_ui_popup_alert_scroll.c \ lib/elementary/efl_ui_popup_alert_text.c \ + lib/elementary/efl_ui_popup_anchor.c \ lib/elementary/efl_ui_grid.c \ lib/elementary/efl_ui_grid_static.c \ lib/elementary/efl_ui_grid_private.h \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index f5666e52ff..ae576feec8 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -278,6 +278,7 @@ void test_efl_ui_popup(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_popup_alert(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_popup_alert_scroll(void *data, Evas_Object *obj, void *event_info); void test_efl_ui_popup_alert_text(void *data, Evas_Object *obj, void *event_info); +void test_efl_ui_popup_anchor(void *data, Evas_Object *obj, void *event_info); void test_dayselector(void *data, Evas_Object *obj, void *event_info); void test_image(void *data, Evas_Object *obj, void *event_info); void test_image_scale_type(void *data, Evas_Object *obj, void *event_info); @@ -1050,6 +1051,7 @@ add_tests: ADD_TEST(NULL, "Popups", "Efl UI Popup Alert", test_efl_ui_popup_alert); ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Scroll", test_efl_ui_popup_alert_scroll); ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Text", test_efl_ui_popup_alert_text); + ADD_TEST(NULL, "Popups", "Efl UI Popup Anchor", test_efl_ui_popup_anchor); //------------------------------// ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar); diff --git a/src/bin/elementary/test_popup.c b/src/bin/elementary/test_popup.c index 2bb6edea45..701cd178b5 100644 --- a/src/bin/elementary/test_popup.c +++ b/src/bin/elementary/test_popup.c @@ -1,6 +1,8 @@ #ifdef HAVE_CONFIG_H # include "elementary_config.h" #endif + +#define EFL_UI_POPUP_ANCHOR_BETA #include <Elementary.h> #define POPUP_POINT_MAX 8 @@ -1205,3 +1207,117 @@ test_efl_ui_popup_alert_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE efl_event_callback_add(efl_ui_popup, EFL_UI_POPUP_ALERT_EVENT_CLICKED, efl_ui_popup_alert_clicked_cb, NULL); } + +static void +_anchor_set_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + efl_ui_popup_anchor_set(data, obj); +} + +static void +_anchor_unset_cb(void *data, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + efl_ui_popup_anchor_set(data, NULL); +} + +void +test_efl_ui_popup_anchor(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Evas_Object *win, *layout, *tbl, *btn; + char buf[PATH_MAX]; + + win = elm_win_util_standard_add("Efl UI AnchorPopup", "Efl UI AnchorPopup"); + elm_win_autodel_set(win, EINA_TRUE); + + evas_object_resize(win, 500, 500); + evas_object_show(win); + + layout = elm_layout_add(win); + snprintf(buf, sizeof(buf), "%s/objects/test.edj", elm_app_data_dir_get()); + elm_layout_file_set(layout, buf, "efl_ui_popup_anchor_layout"); + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, layout); + evas_object_show(layout); + + Evas_Object *efl_ui_popup= efl_add(EFL_UI_POPUP_ANCHOR_CLASS, win); + + efl_ui_popup_bg_repeat_events_set(efl_ui_popup, EINA_TRUE); + + //Default align priority order is top, left, right, bottom, center. + efl_ui_popup_anchor_align_priority_set(efl_ui_popup, EFL_UI_POPUP_ALIGN_TOP, + EFL_UI_POPUP_ALIGN_BOTTOM, + EFL_UI_POPUP_ALIGN_LEFT, + EFL_UI_POPUP_ALIGN_RIGHT, + EFL_UI_POPUP_ALIGN_CENTER); + + evas_object_move(efl_ui_popup, 80, 80); + evas_object_resize(efl_ui_popup, 160, 120); + evas_object_show(efl_ui_popup); + + for (int i = 0; i < 6; i++) + { + btn = elm_button_add(win); + elm_object_text_set(btn, "anchor"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_smart_callback_add(btn, "clicked", _anchor_set_cb, efl_ui_popup); + + snprintf(buf, sizeof(buf), "anchor%d", i+1); + elm_object_part_content_set(layout, buf, btn); + } + + btn = elm_button_add(win); + elm_object_text_set(btn, "anchor none"); + evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_smart_callback_add(btn, "clicked", _anchor_unset_cb, efl_ui_popup); + elm_object_part_content_set(layout, "anchor_none", btn); + + tbl = elm_table_add(efl_ui_popup); + evas_object_size_hint_weight_set(tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(tbl, EVAS_HINT_FILL, EVAS_HINT_FILL); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Center Align"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _center_align_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 0, 0, 1, 1); + evas_object_show(btn); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Left Align"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _left_align_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 1, 0, 1, 1); + evas_object_show(btn); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Right Align"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _right_align_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 2, 0, 1, 1); + evas_object_show(btn); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Top Align"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _top_align_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 0, 1, 1, 1); + evas_object_show(btn); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Bottom Align"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _bottom_align_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 1, 1, 1, 1); + evas_object_show(btn); + + btn = elm_button_add(efl_ui_popup); + elm_object_text_set(btn, "Position Set"); + evas_object_size_hint_min_set(btn, 70, 35); + evas_object_smart_callback_add(btn, "clicked", _position_set_cb, efl_ui_popup); + elm_table_pack(tbl, btn, 2, 1, 1, 1); + evas_object_show(btn); + + efl_content_set(efl_ui_popup, tbl); +} diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 6ea73c2de1..66b3c8fd14 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -305,6 +305,7 @@ EAPI extern Elm_Version *elm_version; # include <efl_ui_popup_alert.eo.h> # include <efl_ui_popup_alert_scroll.eo.h> # include <efl_ui_popup_alert_text.eo.h> +# include <efl_ui_popup_anchor.eo.h> # include <efl_ui_text_editable.eo.h> # include <efl_ui_text_async.eo.h> # include <efl_ui_clock.eo.h> diff --git a/src/lib/elementary/efl_ui_popup_anchor.c b/src/lib/elementary/efl_ui_popup_anchor.c new file mode 100644 index 0000000000..8ec41bc991 --- /dev/null +++ b/src/lib/elementary/efl_ui_popup_anchor.c @@ -0,0 +1,357 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#define EFL_UI_POPUP_PROTECTED +#define EFL_UI_POPUP_ANCHOR_BETA + +#include <Elementary.h> + +#include "elm_priv.h" +#include "efl_ui_popup_anchor_private.h" + +#define MY_CLASS EFL_UI_POPUP_ANCHOR_CLASS +#define MY_CLASS_NAME "Efl.Ui.Popup.Anchor" + +static void +_anchor_calc(Evas_Object *obj) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd); + + Evas_Coord_Rectangle anchor_geom = {0, 0, 0, 0}; + Evas_Coord_Size popup_size = {0, 0}; + Evas_Coord_Size parent_size = {0, 0}; + Eina_Position2D pos = {0, 0}; + + Evas_Object *parent = efl_ui_popup_parent_window_get(obj); + + evas_object_geometry_get(sd->anchor, &anchor_geom.x, &anchor_geom.y, &anchor_geom.w, &anchor_geom.h); + evas_object_geometry_get(obj, NULL, NULL, &popup_size.w, &popup_size.h); + evas_object_geometry_get(parent, NULL, NULL, &parent_size.w, &parent_size.h); + + sd->used_align = EFL_UI_POPUP_ALIGN_NONE; + + /* 1. Find align which display popup. + It enables to shifting popup from exact position. + LEFT, RIGHT - shift only y position within anchor object's height + TOP, BOTTOM - shift only x position within anchor object's width + CENTER - shift both x, y position within anchor object's area + */ + + for (int idx = 0; idx < 6; idx++) + { + Efl_Ui_Popup_Align cur_align; + + if (idx == 0) + cur_align = sd->align; + else + cur_align = sd->priority[idx - 1]; + + if (cur_align == EFL_UI_POPUP_ALIGN_NONE) + continue; + + switch(cur_align) + { + case EFL_UI_POPUP_ALIGN_TOP: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = (anchor_geom.y - popup_size.h); + + if ((pos.y < 0) || + ((pos.y + popup_size.h) > parent_size.h) || + (popup_size.w > parent_size.w)) + continue; + break; + + case EFL_UI_POPUP_ALIGN_LEFT: + pos.x = (anchor_geom.x - popup_size.w); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + + if ((pos.x < 0) || + ((pos.x + popup_size.w) > parent_size.w) || + (popup_size.h > parent_size.h)) + continue; + break; + + case EFL_UI_POPUP_ALIGN_RIGHT: + pos.x = (anchor_geom.x + anchor_geom.w); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + + if ((pos.x < 0) || + ((pos.x + popup_size.w) > parent_size.w) || + (popup_size.h > parent_size.h)) + continue; + break; + + case EFL_UI_POPUP_ALIGN_BOTTOM: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = (anchor_geom.y + anchor_geom.h); + + if ((pos.y < 0) || + ((pos.y + popup_size.h) > parent_size.h) || + (popup_size.w > parent_size.w)) + continue; + break; + + case EFL_UI_POPUP_ALIGN_CENTER: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + + if (popup_size.w > parent_size.w || popup_size.h > parent_size.h) + continue; + break; + + default: + continue; + } + + if ((cur_align == EFL_UI_POPUP_ALIGN_TOP) || + (cur_align == EFL_UI_POPUP_ALIGN_BOTTOM) || + (cur_align == EFL_UI_POPUP_ALIGN_CENTER)) + { + if (pos.x < 0) + pos.x = 0; + if ((pos.x + popup_size.w) > parent_size.w) + pos.x = parent_size.w - popup_size.w; + + if ((pos.x > (anchor_geom.x + anchor_geom.w)) || + ((pos.x + popup_size.w) < anchor_geom.x)) + continue; + } + + if ((cur_align == EFL_UI_POPUP_ALIGN_LEFT) || + (cur_align == EFL_UI_POPUP_ALIGN_RIGHT) || + (cur_align == EFL_UI_POPUP_ALIGN_CENTER)) + { + if (pos.y < 0) + pos.y = 0; + if ((pos.y + popup_size.h) > parent_size.h) + pos.y = parent_size.h - popup_size.h; + + if ((pos.y > (anchor_geom.y + anchor_geom.h)) || + ((pos.y + popup_size.h) < anchor_geom.y)) + continue; + } + + sd->used_align = cur_align; + goto end; + } + + /* 2. Move popup to fit first valid align although entire popup can't display */ + + for (int idx = 0; idx < 6; idx++) + { + Efl_Ui_Popup_Align cur_align; + + if (idx == 0) + cur_align = sd->align; + else + cur_align = sd->priority[idx - 1]; + + if (cur_align == EFL_UI_POPUP_ALIGN_NONE) + continue; + + switch(cur_align) + { + case EFL_UI_POPUP_ALIGN_TOP: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = (anchor_geom.y - popup_size.h); + sd->used_align = cur_align; + goto end; + break; + + case EFL_UI_POPUP_ALIGN_LEFT: + pos.x = (anchor_geom.x - popup_size.w); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + sd->used_align = cur_align; + goto end; + break; + + case EFL_UI_POPUP_ALIGN_RIGHT: + pos.x = (anchor_geom.x + anchor_geom.w); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + sd->used_align = cur_align; + goto end; + break; + + case EFL_UI_POPUP_ALIGN_BOTTOM: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = (anchor_geom.y + anchor_geom.h); + sd->used_align = cur_align; + goto end; + break; + + case EFL_UI_POPUP_ALIGN_CENTER: + pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2); + pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2); + sd->used_align = cur_align; + goto end; + break; + + default: + break; + } + } + +end: + if (sd->used_align != EFL_UI_POPUP_ALIGN_NONE) + efl_gfx_position_set(efl_super(obj, EFL_UI_POPUP_CLASS), pos); +} + +static void +_anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + _anchor_calc(data); +} + +static void +_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED) +{ + EFL_UI_POPUP_ANCHOR_DATA_GET(data, sd); + + efl_event_callback_del(efl_ui_popup_parent_window_get(data), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, data); + + sd->anchor = NULL; + efl_ui_popup_align_set(efl_super(data, MY_CLASS), sd->align); +} + +static void +_anchor_detach(Evas_Object *obj) +{ + EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd); + + if (sd->anchor == NULL) return; + + efl_event_callback_del(efl_ui_popup_parent_window_get(obj), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj); + efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj); + efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj); + efl_event_callback_del(sd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj); +} + +EOLIAN static void +_efl_ui_popup_anchor_anchor_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Evas_Object *anchor) +{ + _anchor_detach(obj); + pd->anchor = anchor; + + if (anchor == NULL) + efl_ui_popup_align_set(efl_super(obj, MY_CLASS), pd->align); + else + { + efl_ui_popup_align_set(efl_super(obj, MY_CLASS), EFL_UI_POPUP_ALIGN_NONE); + + _anchor_calc(obj); + + efl_event_callback_add(efl_ui_popup_parent_window_get(obj), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj); + efl_event_callback_add(anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj); + efl_event_callback_add(anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj); + efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj); + } +} + +EOLIAN static Efl_Object * +_efl_ui_popup_anchor_anchor_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd) +{ + return pd->anchor; +} + +EOLIAN static void +_efl_ui_popup_anchor_align_priority_set(Eo *obj EINA_UNUSED, + Efl_Ui_Popup_Anchor_Data *pd, + Efl_Ui_Popup_Align first, + Efl_Ui_Popup_Align second, + Efl_Ui_Popup_Align third, + Efl_Ui_Popup_Align fourth, + Efl_Ui_Popup_Align fifth) +{ + pd->priority[0] = first; + pd->priority[1] = second; + pd->priority[2] = third; + pd->priority[3] = fourth; + pd->priority[4] = fifth; +} + +EOLIAN static void +_efl_ui_popup_anchor_align_priority_get(Eo *obj EINA_UNUSED, + Efl_Ui_Popup_Anchor_Data *pd, + Efl_Ui_Popup_Align *first, + Efl_Ui_Popup_Align *second, + Efl_Ui_Popup_Align *third, + Efl_Ui_Popup_Align *fourth, + Efl_Ui_Popup_Align *fifth) +{ + if (first) *first = pd->priority[0]; + if (second) *second = pd->priority[1]; + if (third) *third = pd->priority[2]; + if (fourth) *fourth = pd->priority[3]; + if (fifth) *fifth = pd->priority[4]; +} + +EOLIAN static void +_efl_ui_popup_anchor_efl_gfx_position_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED, Eina_Position2D pos) +{ + _anchor_detach(obj); + + pd->anchor = NULL; + pd->align = EFL_UI_POPUP_ALIGN_NONE; + + efl_gfx_position_set(efl_super(obj, MY_CLASS), pos); +} + +EOLIAN static void +_efl_ui_popup_anchor_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED) +{ + elm_layout_sizing_eval(efl_super(obj, MY_CLASS)); + + if (pd->anchor != NULL) + _anchor_calc(obj); +} + +EOLIAN static void +_efl_ui_popup_anchor_efl_ui_popup_align_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Efl_Ui_Popup_Align type) +{ + pd->align = type; + if (pd->anchor == NULL) + efl_ui_popup_align_set(efl_super(obj, MY_CLASS), type); + else + _anchor_calc(obj); +} + +EOLIAN static Efl_Ui_Popup_Align +_efl_ui_popup_anchor_efl_ui_popup_align_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd) +{ + return pd->align; +} + +EOLIAN static void +_efl_ui_popup_anchor_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); + + efl_canvas_group_add(efl_super(obj, MY_CLASS)); + elm_widget_sub_object_parent_add(obj); + + pd->priority[0] = EFL_UI_POPUP_ALIGN_TOP; + pd->priority[1] = EFL_UI_POPUP_ALIGN_LEFT; + pd->priority[2] = EFL_UI_POPUP_ALIGN_RIGHT; + pd->priority[3] = EFL_UI_POPUP_ALIGN_BOTTOM; + pd->priority[4] = EFL_UI_POPUP_ALIGN_CENTER; +} + +EOLIAN static void +_efl_ui_popup_anchor_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED) +{ + efl_canvas_group_del(efl_super(obj, MY_CLASS)); +} + +EOLIAN static void +_efl_ui_popup_anchor_class_constructor(Efl_Class *klass) +{ + evas_smart_legacy_type_register(MY_CLASS_NAME, klass); +} + +#define EFL_UI_POPUP_ANCHOR_EXTRA_OPS \ + EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_popup_anchor), \ + ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_popup_anchor) + +#include "efl_ui_popup_anchor.eo.c" diff --git a/src/lib/elementary/efl_ui_popup_anchor.eo b/src/lib/elementary/efl_ui_popup_anchor.eo new file mode 100644 index 0000000000..1dc422dba0 --- /dev/null +++ b/src/lib/elementary/efl_ui_popup_anchor.eo @@ -0,0 +1,40 @@ +class Efl.Ui.Popup.Anchor(Efl.Ui.Popup) +{ + methods { + @property anchor { + set { + [[Set anchor popup follows the anchor object. + If anchor object is moved or parent window is resized, the anchor popup moves to the new position. + If anchor object is set NULL, the anchor popup stop to following anchor object. + When the popup is moved by using gfx_position_set, anchor is set NULL. + ]] + } + get { + [[Returns the anchor object which the popup is following.]] + } + values { + anchor: Efl.Canvas.Object; [[The object which popup is following.]] + } + } + @property align_priority @beta { + set { + [[Set the align priority of a popup.]] + } + get { + [[Get the align priority of a popup.]] + } + values { + first: Efl.Ui.Popup.Align; + second: Efl.Ui.Popup.Align; + third: Efl.Ui.Popup.Align; + fourth: Efl.Ui.Popup.Align; + fifth: Efl.Ui.Popup.Align; + } + } + } + implements { + class.constructor; + Efl.Gfx.position { set; } + Efl.Ui.Popup.align { set; get; } + } +} diff --git a/src/lib/elementary/efl_ui_popup_anchor_private.h b/src/lib/elementary/efl_ui_popup_anchor_private.h new file mode 100644 index 0000000000..e99094c591 --- /dev/null +++ b/src/lib/elementary/efl_ui_popup_anchor_private.h @@ -0,0 +1,18 @@ +#ifndef EFL_UI_POPUP_ANCHOR_H +#define EFL_UI_POPUP_ANCHOR_H + +#include "Elementary.h" + +typedef struct _Efl_Ui_Popup_Anchor_Data Efl_Ui_Popup_Anchor_Data; +struct _Efl_Ui_Popup_Anchor_Data +{ + Evas_Object *anchor; + Efl_Ui_Popup_Align align; + Efl_Ui_Popup_Align priority[5]; + Efl_Ui_Popup_Align used_align; +}; + +#define EFL_UI_POPUP_ANCHOR_DATA_GET(o, sd) \ + Efl_Ui_Popup_Anchor_Data * sd = efl_data_scope_get(o, EFL_UI_POPUP_ANCHOR_CLASS) + +#endif --