summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJinYong Park <j4939.park@samsung.com>2017-09-20 19:36:39 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2017-11-21 14:01:48 +0900
commit45694f20761668da7b57ada7af3103613a030c04 (patch)
treeab15b1ee34b302045f17c07f586e9a15f77c5a29
parente90b8a9be2098d4bf69ad868a20139796287f678 (diff)
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
-rw-r--r--data/elementary/objects/test.edc78
-rw-r--r--src/Makefile_Elementary.am3
-rw-r--r--src/bin/elementary/test.c2
-rw-r--r--src/bin/elementary/test_popup.c116
-rw-r--r--src/lib/elementary/Elementary.h1
-rw-r--r--src/lib/elementary/efl_ui_popup_anchor.c357
-rw-r--r--src/lib/elementary/efl_ui_popup_anchor.eo40
-rw-r--r--src/lib/elementary/efl_ui_popup_anchor_private.h18
8 files changed, 615 insertions, 0 deletions
diff --git a/data/elementary/objects/test.edc b/data/elementary/objects/test.edc
index 834bea4..6574ab3 100644
--- a/data/elementary/objects/test.edc
+++ b/data/elementary/objects/test.edc
@@ -933,4 +933,82 @@ collections {
933 } 933 }
934 } 934 }
935 } 935 }
936 group { "efl_ui_popup_anchor_layout";
937 parts {
938 spacer { "base";
939 desc { "default";
940 }
941 }
942 swallow { "anchor1";
943 scale;
944 desc { "default";
945 rel.to: "base";
946 rel1.relative: 0.15 0.25;
947 rel2.relative: 0.15 0.25;
948 fixed: 1 1;
949 min: 50 50;
950 }
951 }
952 swallow { "anchor2";
953 scale;
954 desc { "default";
955 rel.to: "base";
956 rel1.relative: 0.75 0.15;
957 rel2.relative: 0.75 0.15;
958 fixed: 1 1;
959 min: 50 50;
960 }
961 }
962 swallow { "anchor3";
963 scale;
964 desc { "default";
965 rel.to: "base";
966 rel1.relative: 0.25 0.85;
967 rel2.relative: 0.25 0.85;
968 fixed: 1 1;
969 min: 50 50;
970 }
971 }
972 swallow { "anchor4";
973 scale;
974 desc { "default";
975 rel.to: "base";
976 rel1.relative: 0.85 0.75;
977 rel2.relative: 0.85 0.75;
978 fixed: 1 1;
979 min: 50 50;
980 }
981 }
982 swallow { "anchor5";
983 scale;
984 desc { "default";
985 rel.to: "base";
986 rel1.relative: 0.45 0.35;
987 rel2.relative: 0.45 0.35;
988 fixed: 1 1;
989 min: 50 50;
990 }
991 }
992 swallow { "anchor6";
993 scale;
994 desc { "default";
995 rel.to: "base";
996 rel2.relative: 0.0 0.0;
997 rel1.offset: 150 300;
998 rel2.offset: 200 350;
999 fixed: 1 1;
1000 }
1001 }
1002 swallow { "anchor_none";
1003 scale;
1004 desc { "default";
1005 rel.to: "base";
1006 rel1.relative: 0.60 0.45;
1007 rel2.relative: 0.60 0.45;
1008 fixed: 1 1;
1009 min: 70 50;
1010 }
1011 }
1012 }
1013 }
936} 1014}
diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 6a65b9c..c39770a 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -37,6 +37,7 @@ elm_public_eolian_files = \
37 lib/elementary/efl_ui_popup_alert_scroll_part.eo \ 37 lib/elementary/efl_ui_popup_alert_scroll_part.eo \
38 lib/elementary/efl_ui_popup_alert_text.eo \ 38 lib/elementary/efl_ui_popup_alert_text.eo \
39 lib/elementary/efl_ui_popup_alert_text_part.eo \ 39 lib/elementary/efl_ui_popup_alert_text_part.eo \
40 lib/elementary/efl_ui_popup_anchor.eo \
40 lib/elementary/efl_ui_text_editable.eo \ 41 lib/elementary/efl_ui_text_editable.eo \
41 lib/elementary/efl_ui_text_async.eo \ 42 lib/elementary/efl_ui_text_async.eo \
42 lib/elementary/efl_ui_textpath.eo \ 43 lib/elementary/efl_ui_textpath.eo \
@@ -300,6 +301,7 @@ includesunstable_HEADERS = \
300 lib/elementary/efl_ui_popup_alert_private.h \ 301 lib/elementary/efl_ui_popup_alert_private.h \
301 lib/elementary/efl_ui_popup_alert_scroll_private.h \ 302 lib/elementary/efl_ui_popup_alert_scroll_private.h \
302 lib/elementary/efl_ui_popup_alert_text_private.h \ 303 lib/elementary/efl_ui_popup_alert_text_private.h \
304 lib/elementary/efl_ui_popup_anchor_private.h \
303 lib/elementary/elm_widget_index.h \ 305 lib/elementary/elm_widget_index.h \
304 lib/elementary/elm_widget_inwin.h \ 306 lib/elementary/elm_widget_inwin.h \
305 lib/elementary/elm_widget_label.h \ 307 lib/elementary/elm_widget_label.h \
@@ -714,6 +716,7 @@ lib_elementary_libelementary_la_SOURCES = \
714 lib/elementary/efl_ui_popup_alert.c \ 716 lib/elementary/efl_ui_popup_alert.c \
715 lib/elementary/efl_ui_popup_alert_scroll.c \ 717 lib/elementary/efl_ui_popup_alert_scroll.c \
716 lib/elementary/efl_ui_popup_alert_text.c \ 718 lib/elementary/efl_ui_popup_alert_text.c \
719 lib/elementary/efl_ui_popup_anchor.c \
717 lib/elementary/efl_ui_grid.c \ 720 lib/elementary/efl_ui_grid.c \
718 lib/elementary/efl_ui_grid_static.c \ 721 lib/elementary/efl_ui_grid_static.c \
719 lib/elementary/efl_ui_grid_private.h \ 722 lib/elementary/efl_ui_grid_private.h \
diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c
index adafcfa..f7dc6fa 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);
278void test_efl_ui_popup_alert(void *data, Evas_Object *obj, void *event_info); 278void test_efl_ui_popup_alert(void *data, Evas_Object *obj, void *event_info);
279void test_efl_ui_popup_alert_scroll(void *data, Evas_Object *obj, void *event_info); 279void test_efl_ui_popup_alert_scroll(void *data, Evas_Object *obj, void *event_info);
280void test_efl_ui_popup_alert_text(void *data, Evas_Object *obj, void *event_info); 280void test_efl_ui_popup_alert_text(void *data, Evas_Object *obj, void *event_info);
281void test_efl_ui_popup_anchor(void *data, Evas_Object *obj, void *event_info);
281void test_dayselector(void *data, Evas_Object *obj, void *event_info); 282void test_dayselector(void *data, Evas_Object *obj, void *event_info);
282void test_image(void *data, Evas_Object *obj, void *event_info); 283void test_image(void *data, Evas_Object *obj, void *event_info);
283void test_image_scale_type(void *data, Evas_Object *obj, void *event_info); 284void test_image_scale_type(void *data, Evas_Object *obj, void *event_info);
@@ -1014,6 +1015,7 @@ add_tests:
1014 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert", test_efl_ui_popup_alert); 1015 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert", test_efl_ui_popup_alert);
1015 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Scroll", test_efl_ui_popup_alert_scroll); 1016 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Scroll", test_efl_ui_popup_alert_scroll);
1016 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Text", test_efl_ui_popup_alert_text); 1017 ADD_TEST(NULL, "Popups", "Efl UI Popup Alert Text", test_efl_ui_popup_alert_text);
1018 ADD_TEST(NULL, "Popups", "Efl UI Popup Anchor", test_efl_ui_popup_anchor);
1017 1019
1018 //------------------------------// 1020 //------------------------------//
1019 ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar); 1021 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 2bb6ede..701cd17 100644
--- a/src/bin/elementary/test_popup.c
+++ b/src/bin/elementary/test_popup.c
@@ -1,6 +1,8 @@
1#ifdef HAVE_CONFIG_H 1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h" 2# include "elementary_config.h"
3#endif 3#endif
4
5#define EFL_UI_POPUP_ANCHOR_BETA
4#include <Elementary.h> 6#include <Elementary.h>
5 7
6#define POPUP_POINT_MAX 8 8#define POPUP_POINT_MAX 8
@@ -1205,3 +1207,117 @@ test_efl_ui_popup_alert_text(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSE
1205 1207
1206 efl_event_callback_add(efl_ui_popup, EFL_UI_POPUP_ALERT_EVENT_CLICKED, efl_ui_popup_alert_clicked_cb, NULL); 1208 efl_event_callback_add(efl_ui_popup, EFL_UI_POPUP_ALERT_EVENT_CLICKED, efl_ui_popup_alert_clicked_cb, NULL);
1207} 1209}
1210
1211static void
1212_anchor_set_cb(void *data, Evas_Object *obj EINA_UNUSED,
1213 void *event_info EINA_UNUSED)
1214{
1215 efl_ui_popup_anchor_set(data, obj);
1216}
1217
1218static void
1219_anchor_unset_cb(void *data, Evas_Object *obj EINA_UNUSED,
1220 void *event_info EINA_UNUSED)
1221{
1222 efl_ui_popup_anchor_set(data, NULL);
1223}
1224
1225void
1226test_efl_ui_popup_anchor(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
1227{
1228 Evas_Object *win, *layout, *tbl, *btn;
1229 char buf[PATH_MAX];
1230
1231 win = elm_win_util_standard_add("Efl UI AnchorPopup", "Efl UI AnchorPopup");
1232 elm_win_autodel_set(win, EINA_TRUE);
1233
1234 evas_object_resize(win, 500, 500);
1235 evas_object_show(win);
1236
1237 layout = elm_layout_add(win);
1238 snprintf(buf, sizeof(buf), "%s/objects/test.edj", elm_app_data_dir_get());
1239 elm_layout_file_set(layout, buf, "efl_ui_popup_anchor_layout");
1240 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1241 elm_win_resize_object_add(win, layout);
1242 evas_object_show(layout);
1243
1244 Evas_Object *efl_ui_popup= efl_add(EFL_UI_POPUP_ANCHOR_CLASS, win);
1245
1246 efl_ui_popup_bg_repeat_events_set(efl_ui_popup, EINA_TRUE);
1247
1248 //Default align priority order is top, left, right, bottom, center.
1249 efl_ui_popup_anchor_align_priority_set(efl_ui_popup, EFL_UI_POPUP_ALIGN_TOP,
1250 EFL_UI_POPUP_ALIGN_BOTTOM,
1251 EFL_UI_POPUP_ALIGN_LEFT,
1252 EFL_UI_POPUP_ALIGN_RIGHT,
1253 EFL_UI_POPUP_ALIGN_CENTER);
1254
1255 evas_object_move(efl_ui_popup, 80, 80);
1256 evas_object_resize(efl_ui_popup, 160, 120);
1257 evas_object_show(efl_ui_popup);
1258
1259 for (int i = 0; i < 6; i++)
1260 {
1261 btn = elm_button_add(win);
1262 elm_object_text_set(btn, "anchor");
1263 evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1264 evas_object_smart_callback_add(btn, "clicked", _anchor_set_cb, efl_ui_popup);
1265
1266 snprintf(buf, sizeof(buf), "anchor%d", i+1);
1267 elm_object_part_content_set(layout, buf, btn);
1268 }
1269
1270 btn = elm_button_add(win);
1271 elm_object_text_set(btn, "anchor none");
1272 evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1273 evas_object_smart_callback_add(btn, "clicked", _anchor_unset_cb, efl_ui_popup);
1274 elm_object_part_content_set(layout, "anchor_none", btn);
1275
1276 tbl = elm_table_add(efl_ui_popup);
1277 evas_object_size_hint_weight_set(tbl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1278 evas_object_size_hint_align_set(tbl, EVAS_HINT_FILL, EVAS_HINT_FILL);
1279
1280 btn = elm_button_add(efl_ui_popup);
1281 elm_object_text_set(btn, "Center Align");
1282 evas_object_size_hint_min_set(btn, 70, 35);
1283 evas_object_smart_callback_add(btn, "clicked", _center_align_cb, efl_ui_popup);
1284 elm_table_pack(tbl, btn, 0, 0, 1, 1);
1285 evas_object_show(btn);
1286
1287 btn = elm_button_add(efl_ui_popup);
1288 elm_object_text_set(btn, "Left Align");
1289 evas_object_size_hint_min_set(btn, 70, 35);
1290 evas_object_smart_callback_add(btn, "clicked", _left_align_cb, efl_ui_popup);
1291 elm_table_pack(tbl, btn, 1, 0, 1, 1);
1292 evas_object_show(btn);
1293
1294 btn = elm_button_add(efl_ui_popup);
1295 elm_object_text_set(btn, "Right Align");
1296 evas_object_size_hint_min_set(btn, 70, 35);
1297 evas_object_smart_callback_add(btn, "clicked", _right_align_cb, efl_ui_popup);
1298 elm_table_pack(tbl, btn, 2, 0, 1, 1);
1299 evas_object_show(btn);
1300
1301 btn = elm_button_add(efl_ui_popup);
1302 elm_object_text_set(btn, "Top Align");
1303 evas_object_size_hint_min_set(btn, 70, 35);
1304 evas_object_smart_callback_add(btn, "clicked", _top_align_cb, efl_ui_popup);
1305 elm_table_pack(tbl, btn, 0, 1, 1, 1);
1306 evas_object_show(btn);
1307
1308 btn = elm_button_add(efl_ui_popup);
1309 elm_object_text_set(btn, "Bottom Align");
1310 evas_object_size_hint_min_set(btn, 70, 35);
1311 evas_object_smart_callback_add(btn, "clicked", _bottom_align_cb, efl_ui_popup);
1312 elm_table_pack(tbl, btn, 1, 1, 1, 1);
1313 evas_object_show(btn);
1314
1315 btn = elm_button_add(efl_ui_popup);
1316 elm_object_text_set(btn, "Position Set");
1317 evas_object_size_hint_min_set(btn, 70, 35);
1318 evas_object_smart_callback_add(btn, "clicked", _position_set_cb, efl_ui_popup);
1319 elm_table_pack(tbl, btn, 2, 1, 1, 1);
1320 evas_object_show(btn);
1321
1322 efl_content_set(efl_ui_popup, tbl);
1323}
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 867baa9..5a084ec 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -285,6 +285,7 @@ EAPI extern Elm_Version *elm_version;
285# include <efl_ui_popup_alert.eo.h> 285# include <efl_ui_popup_alert.eo.h>
286# include <efl_ui_popup_alert_scroll.eo.h> 286# include <efl_ui_popup_alert_scroll.eo.h>
287# include <efl_ui_popup_alert_text.eo.h> 287# include <efl_ui_popup_alert_text.eo.h>
288# include <efl_ui_popup_anchor.eo.h>
288# include <efl_ui_text_editable.eo.h> 289# include <efl_ui_text_editable.eo.h>
289# include <efl_ui_text_async.eo.h> 290# include <efl_ui_text_async.eo.h>
290# include <efl_ui_clock.eo.h> 291# 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 0000000..8ec41bc
--- /dev/null
+++ b/src/lib/elementary/efl_ui_popup_anchor.c
@@ -0,0 +1,357 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_POPUP_PROTECTED
6#define EFL_UI_POPUP_ANCHOR_BETA
7
8#include <Elementary.h>
9
10#include "elm_priv.h"
11#include "efl_ui_popup_anchor_private.h"
12
13#define MY_CLASS EFL_UI_POPUP_ANCHOR_CLASS
14#define MY_CLASS_NAME "Efl.Ui.Popup.Anchor"
15
16static void
17_anchor_calc(Evas_Object *obj)
18{
19 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
20 EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
21
22 Evas_Coord_Rectangle anchor_geom = {0, 0, 0, 0};
23 Evas_Coord_Size popup_size = {0, 0};
24 Evas_Coord_Size parent_size = {0, 0};
25 Eina_Position2D pos = {0, 0};
26
27 Evas_Object *parent = efl_ui_popup_parent_window_get(obj);
28
29 evas_object_geometry_get(sd->anchor, &anchor_geom.x, &anchor_geom.y, &anchor_geom.w, &anchor_geom.h);
30 evas_object_geometry_get(obj, NULL, NULL, &popup_size.w, &popup_size.h);
31 evas_object_geometry_get(parent, NULL, NULL, &parent_size.w, &parent_size.h);
32
33 sd->used_align = EFL_UI_POPUP_ALIGN_NONE;
34
35 /* 1. Find align which display popup.
36 It enables to shifting popup from exact position.
37 LEFT, RIGHT - shift only y position within anchor object's height
38 TOP, BOTTOM - shift only x position within anchor object's width
39 CENTER - shift both x, y position within anchor object's area
40 */
41
42 for (int idx = 0; idx < 6; idx++)
43 {
44 Efl_Ui_Popup_Align cur_align;
45
46 if (idx == 0)
47 cur_align = sd->align;
48 else
49 cur_align = sd->priority[idx - 1];
50
51 if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
52 continue;
53
54 switch(cur_align)
55 {
56 case EFL_UI_POPUP_ALIGN_TOP:
57 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
58 pos.y = (anchor_geom.y - popup_size.h);
59
60 if ((pos.y < 0) ||
61 ((pos.y + popup_size.h) > parent_size.h) ||
62 (popup_size.w > parent_size.w))
63 continue;
64 break;
65
66 case EFL_UI_POPUP_ALIGN_LEFT:
67 pos.x = (anchor_geom.x - popup_size.w);
68 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
69
70 if ((pos.x < 0) ||
71 ((pos.x + popup_size.w) > parent_size.w) ||
72 (popup_size.h > parent_size.h))
73 continue;
74 break;
75
76 case EFL_UI_POPUP_ALIGN_RIGHT:
77 pos.x = (anchor_geom.x + anchor_geom.w);
78 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
79
80 if ((pos.x < 0) ||
81 ((pos.x + popup_size.w) > parent_size.w) ||
82 (popup_size.h > parent_size.h))
83 continue;
84 break;
85
86 case EFL_UI_POPUP_ALIGN_BOTTOM:
87 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
88 pos.y = (anchor_geom.y + anchor_geom.h);
89
90 if ((pos.y < 0) ||
91 ((pos.y + popup_size.h) > parent_size.h) ||
92 (popup_size.w > parent_size.w))
93 continue;
94 break;
95
96 case EFL_UI_POPUP_ALIGN_CENTER:
97 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
98 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
99
100 if (popup_size.w > parent_size.w || popup_size.h > parent_size.h)
101 continue;
102 break;
103
104 default:
105 continue;
106 }
107
108 if ((cur_align == EFL_UI_POPUP_ALIGN_TOP) ||
109 (cur_align == EFL_UI_POPUP_ALIGN_BOTTOM) ||
110 (cur_align == EFL_UI_POPUP_ALIGN_CENTER))
111 {
112 if (pos.x < 0)
113 pos.x = 0;
114 if ((pos.x + popup_size.w) > parent_size.w)
115 pos.x = parent_size.w - popup_size.w;
116
117 if ((pos.x > (anchor_geom.x + anchor_geom.w)) ||
118 ((pos.x + popup_size.w) < anchor_geom.x))
119 continue;
120 }
121
122 if ((cur_align == EFL_UI_POPUP_ALIGN_LEFT) ||
123 (cur_align == EFL_UI_POPUP_ALIGN_RIGHT) ||
124 (cur_align == EFL_UI_POPUP_ALIGN_CENTER))
125 {
126 if (pos.y < 0)
127 pos.y = 0;
128 if ((pos.y + popup_size.h) > parent_size.h)
129 pos.y = parent_size.h - popup_size.h;
130
131 if ((pos.y > (anchor_geom.y + anchor_geom.h)) ||
132 ((pos.y + popup_size.h) < anchor_geom.y))
133 continue;
134 }
135
136 sd->used_align = cur_align;
137 goto end;
138 }
139
140 /* 2. Move popup to fit first valid align although entire popup can't display */
141
142 for (int idx = 0; idx < 6; idx++)
143 {
144 Efl_Ui_Popup_Align cur_align;
145
146 if (idx == 0)
147 cur_align = sd->align;
148 else
149 cur_align = sd->priority[idx - 1];
150
151 if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
152 continue;
153
154 switch(cur_align)
155 {
156 case EFL_UI_POPUP_ALIGN_TOP:
157 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
158 pos.y = (anchor_geom.y - popup_size.h);
159 sd->used_align = cur_align;
160 goto end;
161 break;
162
163 case EFL_UI_POPUP_ALIGN_LEFT:
164 pos.x = (anchor_geom.x - popup_size.w);
165 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
166 sd->used_align = cur_align;
167 goto end;
168 break;
169
170 case EFL_UI_POPUP_ALIGN_RIGHT:
171 pos.x = (anchor_geom.x + anchor_geom.w);
172 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
173 sd->used_align = cur_align;
174 goto end;
175 break;
176
177 case EFL_UI_POPUP_ALIGN_BOTTOM:
178 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
179 pos.y = (anchor_geom.y + anchor_geom.h);
180 sd->used_align = cur_align;
181 goto end;
182 break;
183
184 case EFL_UI_POPUP_ALIGN_CENTER:
185 pos.x = anchor_geom.x + ((anchor_geom.w - popup_size.w) / 2);
186 pos.y = anchor_geom.y + ((anchor_geom.h - popup_size.h) / 2);
187 sd->used_align = cur_align;
188 goto end;
189 break;
190
191 default:
192 break;
193 }
194 }
195
196end:
197 if (sd->used_align != EFL_UI_POPUP_ALIGN_NONE)
198 efl_gfx_position_set(efl_super(obj, EFL_UI_POPUP_CLASS), pos);
199}
200
201static void
202_anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
203{
204 _anchor_calc(data);
205}
206
207static void
208_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
209{
210 EFL_UI_POPUP_ANCHOR_DATA_GET(data, sd);
211
212 efl_event_callback_del(efl_ui_popup_parent_window_get(data), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, data);
213
214 sd->anchor = NULL;
215 efl_ui_popup_align_set(efl_super(data, MY_CLASS), sd->align);
216}
217
218static void
219_anchor_detach(Evas_Object *obj)
220{
221 EFL_UI_POPUP_ANCHOR_DATA_GET(obj, sd);
222
223 if (sd->anchor == NULL) return;
224
225 efl_event_callback_del(efl_ui_popup_parent_window_get(obj), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
226 efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
227 efl_event_callback_del(sd->anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj);
228 efl_event_callback_del(sd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
229}
230
231EOLIAN static void
232_efl_ui_popup_anchor_anchor_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Evas_Object *anchor)
233{
234 _anchor_detach(obj);
235 pd->anchor = anchor;
236
237 if (anchor == NULL)
238 efl_ui_popup_align_set(efl_super(obj, MY_CLASS), pd->align);
239 else
240 {
241 efl_ui_popup_align_set(efl_super(obj, MY_CLASS), EFL_UI_POPUP_ALIGN_NONE);
242
243 _anchor_calc(obj);
244
245 efl_event_callback_add(efl_ui_popup_parent_window_get(obj), EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
246 efl_event_callback_add(anchor, EFL_GFX_EVENT_RESIZE, _anchor_geom_cb, obj);
247 efl_event_callback_add(anchor, EFL_GFX_EVENT_MOVE, _anchor_geom_cb, obj);
248 efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
249 }
250}
251
252EOLIAN static Efl_Object *
253_efl_ui_popup_anchor_anchor_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd)
254{
255 return pd->anchor;
256}
257
258EOLIAN static void
259_efl_ui_popup_anchor_align_priority_set(Eo *obj EINA_UNUSED,
260 Efl_Ui_Popup_Anchor_Data *pd,
261 Efl_Ui_Popup_Align first,
262 Efl_Ui_Popup_Align second,
263 Efl_Ui_Popup_Align third,
264 Efl_Ui_Popup_Align fourth,
265 Efl_Ui_Popup_Align fifth)
266{
267 pd->priority[0] = first;
268 pd->priority[1] = second;
269 pd->priority[2] = third;
270 pd->priority[3] = fourth;
271 pd->priority[4] = fifth;
272}
273
274EOLIAN static void
275_efl_ui_popup_anchor_align_priority_get(Eo *obj EINA_UNUSED,
276 Efl_Ui_Popup_Anchor_Data *pd,
277 Efl_Ui_Popup_Align *first,
278 Efl_Ui_Popup_Align *second,
279 Efl_Ui_Popup_Align *third,
280 Efl_Ui_Popup_Align *fourth,
281 Efl_Ui_Popup_Align *fifth)
282{
283 if (first) *first = pd->priority[0];
284 if (second) *second = pd->priority[1];
285 if (third) *third = pd->priority[2];
286 if (fourth) *fourth = pd->priority[3];
287 if (fifth) *fifth = pd->priority[4];
288}
289
290EOLIAN static void
291_efl_ui_popup_anchor_efl_gfx_position_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED, Eina_Position2D pos)
292{
293 _anchor_detach(obj);
294
295 pd->anchor = NULL;
296 pd->align = EFL_UI_POPUP_ALIGN_NONE;
297
298 efl_gfx_position_set(efl_super(obj, MY_CLASS), pos);
299}
300
301EOLIAN static void
302_efl_ui_popup_anchor_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
303{
304 elm_layout_sizing_eval(efl_super(obj, MY_CLASS));
305
306 if (pd->anchor != NULL)
307 _anchor_calc(obj);
308}
309
310EOLIAN static void
311_efl_ui_popup_anchor_efl_ui_popup_align_set(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd, Efl_Ui_Popup_Align type)
312{
313 pd->align = type;
314 if (pd->anchor == NULL)
315 efl_ui_popup_align_set(efl_super(obj, MY_CLASS), type);
316 else
317 _anchor_calc(obj);
318}
319
320EOLIAN static Efl_Ui_Popup_Align
321_efl_ui_popup_anchor_efl_ui_popup_align_get(Eo *obj EINA_UNUSED, Efl_Ui_Popup_Anchor_Data *pd)
322{
323 return pd->align;
324}
325
326EOLIAN static void
327_efl_ui_popup_anchor_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
328{
329 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
330
331 efl_canvas_group_add(efl_super(obj, MY_CLASS));
332 elm_widget_sub_object_parent_add(obj);
333
334 pd->priority[0] = EFL_UI_POPUP_ALIGN_TOP;
335 pd->priority[1] = EFL_UI_POPUP_ALIGN_LEFT;
336 pd->priority[2] = EFL_UI_POPUP_ALIGN_RIGHT;
337 pd->priority[3] = EFL_UI_POPUP_ALIGN_BOTTOM;
338 pd->priority[4] = EFL_UI_POPUP_ALIGN_CENTER;
339}
340
341EOLIAN static void
342_efl_ui_popup_anchor_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Popup_Anchor_Data *pd EINA_UNUSED)
343{
344 efl_canvas_group_del(efl_super(obj, MY_CLASS));
345}
346
347EOLIAN static void
348_efl_ui_popup_anchor_class_constructor(Efl_Class *klass)
349{
350 evas_smart_legacy_type_register(MY_CLASS_NAME, klass);
351}
352
353#define EFL_UI_POPUP_ANCHOR_EXTRA_OPS \
354 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_popup_anchor), \
355 ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_popup_anchor)
356
357#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 0000000..1dc422d
--- /dev/null
+++ b/src/lib/elementary/efl_ui_popup_anchor.eo
@@ -0,0 +1,40 @@
1class Efl.Ui.Popup.Anchor(Efl.Ui.Popup)
2{
3 methods {
4 @property anchor {
5 set {
6 [[Set anchor popup follows the anchor object.
7 If anchor object is moved or parent window is resized, the anchor popup moves to the new position.
8 If anchor object is set NULL, the anchor popup stop to following anchor object.
9 When the popup is moved by using gfx_position_set, anchor is set NULL.
10 ]]
11 }
12 get {
13 [[Returns the anchor object which the popup is following.]]
14 }
15 values {
16 anchor: Efl.Canvas.Object; [[The object which popup is following.]]
17 }
18 }
19 @property align_priority @beta {
20 set {
21 [[Set the align priority of a popup.]]
22 }
23 get {
24 [[Get the align priority of a popup.]]
25 }
26 values {
27 first: Efl.Ui.Popup.Align;
28 second: Efl.Ui.Popup.Align;
29 third: Efl.Ui.Popup.Align;
30 fourth: Efl.Ui.Popup.Align;
31 fifth: Efl.Ui.Popup.Align;
32 }
33 }
34 }
35 implements {
36 class.constructor;
37 Efl.Gfx.position { set; }
38 Efl.Ui.Popup.align { set; get; }
39 }
40}
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 0000000..e99094c
--- /dev/null
+++ b/src/lib/elementary/efl_ui_popup_anchor_private.h
@@ -0,0 +1,18 @@
1#ifndef EFL_UI_POPUP_ANCHOR_H
2#define EFL_UI_POPUP_ANCHOR_H
3
4#include "Elementary.h"
5
6typedef struct _Efl_Ui_Popup_Anchor_Data Efl_Ui_Popup_Anchor_Data;
7struct _Efl_Ui_Popup_Anchor_Data
8{
9 Evas_Object *anchor;
10 Efl_Ui_Popup_Align align;
11 Efl_Ui_Popup_Align priority[5];
12 Efl_Ui_Popup_Align used_align;
13};
14
15#define EFL_UI_POPUP_ANCHOR_DATA_GET(o, sd) \
16 Efl_Ui_Popup_Anchor_Data * sd = efl_data_scope_get(o, EFL_UI_POPUP_ANCHOR_CLASS)
17
18#endif