summaryrefslogtreecommitdiff
path: root/src/lib/elementary/efl_ui_anchor_popup.c
diff options
context:
space:
mode:
authorJaehyun Cho <jae_hyun.cho@samsung.com>2018-11-16 11:11:50 +0100
committerXavi Artigas <xavierartigas@yahoo.es>2018-11-16 11:26:57 +0100
commitd4526f44b8c20010061c42a87ac0496796311afb (patch)
treea51fb132e5b0c5498d67ef441bc53dcb57846f63 /src/lib/elementary/efl_ui_anchor_popup.c
parent2d460e52e4a1f6b87bd04cdd8a99a2ec4f1ba659 (diff)
elementary: rename Efl.Ui.Popup classes
Summary: Efl.Ui.Popup classes are renamed intuitively from backward order to forward order. Efl.Ui.Popup_Alert -> Efl.Ui.Alert_Popup Efl.Ui.Popup_Alert_Scroll -> Efl.Ui.Scroll_Alert_Popup Efl.Ui.Popup_Alert_Text -> Efl.Ui.Text_Alert_Popup Reviewers: segfaultxavi, bu5hm4n, cedric Reviewed By: segfaultxavi Subscribers: herb, SanghyeonLee, woohyun, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7292
Diffstat (limited to 'src/lib/elementary/efl_ui_anchor_popup.c')
-rw-r--r--src/lib/elementary/efl_ui_anchor_popup.c354
1 files changed, 354 insertions, 0 deletions
diff --git a/src/lib/elementary/efl_ui_anchor_popup.c b/src/lib/elementary/efl_ui_anchor_popup.c
new file mode 100644
index 0000000..9b0e9c6
--- /dev/null
+++ b/src/lib/elementary/efl_ui_anchor_popup.c
@@ -0,0 +1,354 @@
1#ifdef HAVE_CONFIG_H
2# include "elementary_config.h"
3#endif
4
5#define EFL_UI_POPUP_PROTECTED
6#define EFL_UI_ANCHOR_POPUP_BETA
7
8#include <Elementary.h>
9
10#include "elm_priv.h"
11#include "efl_ui_popup_private.h"
12#include "efl_ui_anchor_popup_private.h"
13
14#define MY_CLASS EFL_UI_ANCHOR_POPUP_CLASS
15#define MY_CLASS_NAME "Efl.Ui.Anchor_Popup"
16
17static void
18_anchor_calc(Eo *obj)
19{
20 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
21 EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
22 EFL_UI_ANCHOR_POPUP_DATA_GET(obj, pd);
23
24 Eina_Position2D pos = {0, 0};
25
26 Eina_Rect a_geom = efl_gfx_entity_geometry_get(pd->anchor);
27 Eina_Rect o_geom = efl_gfx_entity_geometry_get(obj);
28 Eina_Rect p_geom = efl_gfx_entity_geometry_get(ppd->win_parent);
29
30 pd->used_align = EFL_UI_POPUP_ALIGN_NONE;
31
32 /* 1. Find align which display popup.
33 It enables to shifting popup from exact position.
34 LEFT, RIGHT - shift only y position within anchor object's height
35 TOP, BOTTOM - shift only x position within anchor object's width
36 CENTER - shift both x, y position within anchor object's area
37 */
38
39 for (int idx = 0; idx < 6; idx++)
40 {
41 Efl_Ui_Popup_Align cur_align;
42
43 if (idx == 0)
44 cur_align = ppd->align;
45 else
46 cur_align = pd->priority[idx - 1];
47
48 if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
49 continue;
50
51 switch(cur_align)
52 {
53 case EFL_UI_POPUP_ALIGN_TOP:
54 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
55 pos.y = (a_geom.y - o_geom.h);
56
57 if ((pos.y < 0) ||
58 ((pos.y + o_geom.h) > p_geom.h) ||
59 (o_geom.w > p_geom.w))
60 continue;
61 break;
62
63 case EFL_UI_POPUP_ALIGN_LEFT:
64 pos.x = (a_geom.x - o_geom.w);
65 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
66
67 if ((pos.x < 0) ||
68 ((pos.x + o_geom.w) > p_geom.w) ||
69 (o_geom.h > p_geom.h))
70 continue;
71 break;
72
73 case EFL_UI_POPUP_ALIGN_RIGHT:
74 pos.x = (a_geom.x + a_geom.w);
75 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
76
77 if ((pos.x < 0) ||
78 ((pos.x + o_geom.w) > p_geom.w) ||
79 (o_geom.h > p_geom.h))
80 continue;
81 break;
82
83 case EFL_UI_POPUP_ALIGN_BOTTOM:
84 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
85 pos.y = (a_geom.y + a_geom.h);
86
87 if ((pos.y < 0) ||
88 ((pos.y + o_geom.h) > p_geom.h) ||
89 (o_geom.w > p_geom.w))
90 continue;
91 break;
92
93 case EFL_UI_POPUP_ALIGN_CENTER:
94 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
95 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
96
97 if ((o_geom.w > p_geom.w) || (o_geom.h > p_geom.h))
98 continue;
99 break;
100
101 default:
102 continue;
103 }
104
105 if ((cur_align == EFL_UI_POPUP_ALIGN_TOP) ||
106 (cur_align == EFL_UI_POPUP_ALIGN_BOTTOM) ||
107 (cur_align == EFL_UI_POPUP_ALIGN_CENTER))
108 {
109 if (pos.x < 0)
110 pos.x = 0;
111 if ((pos.x + o_geom.w) > p_geom.w)
112 pos.x = p_geom.w - o_geom.w;
113
114 if ((pos.x > (a_geom.x + a_geom.w)) ||
115 ((pos.x + o_geom.w) < a_geom.x))
116 continue;
117 }
118
119 if ((cur_align == EFL_UI_POPUP_ALIGN_LEFT) ||
120 (cur_align == EFL_UI_POPUP_ALIGN_RIGHT) ||
121 (cur_align == EFL_UI_POPUP_ALIGN_CENTER))
122 {
123 if (pos.y < 0)
124 pos.y = 0;
125 if ((pos.y + o_geom.h) > p_geom.h)
126 pos.y = p_geom.h - o_geom.h;
127
128 if ((pos.y > (a_geom.y + a_geom.h)) ||
129 ((pos.y + o_geom.h) < a_geom.y))
130 continue;
131 }
132
133 pd->used_align = cur_align;
134 goto end;
135 }
136
137 /* 2. Move popup to fit first valid align although entire popup can't display */
138
139 for (int idx = 0; idx < 6; idx++)
140 {
141 Efl_Ui_Popup_Align cur_align;
142
143 if (idx == 0)
144 cur_align = ppd->align;
145 else
146 cur_align = pd->priority[idx - 1];
147
148 if (cur_align == EFL_UI_POPUP_ALIGN_NONE)
149 continue;
150
151 switch(cur_align)
152 {
153 case EFL_UI_POPUP_ALIGN_TOP:
154 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
155 pos.y = (a_geom.y - o_geom.h);
156 pd->used_align = cur_align;
157 goto end;
158 break;
159
160 case EFL_UI_POPUP_ALIGN_LEFT:
161 pos.x = (a_geom.x - o_geom.w);
162 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
163 pd->used_align = cur_align;
164 goto end;
165 break;
166
167 case EFL_UI_POPUP_ALIGN_RIGHT:
168 pos.x = (a_geom.x + a_geom.w);
169 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
170 pd->used_align = cur_align;
171 goto end;
172 break;
173
174 case EFL_UI_POPUP_ALIGN_BOTTOM:
175 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
176 pos.y = (a_geom.y + a_geom.h);
177 pd->used_align = cur_align;
178 goto end;
179 break;
180
181 case EFL_UI_POPUP_ALIGN_CENTER:
182 pos.x = a_geom.x + ((a_geom.w - o_geom.w) / 2);
183 pos.y = a_geom.y + ((a_geom.h - o_geom.h) / 2);
184 pd->used_align = cur_align;
185 goto end;
186 break;
187
188 default:
189 break;
190 }
191 }
192
193end:
194 if (pd->used_align != EFL_UI_POPUP_ALIGN_NONE)
195 efl_gfx_entity_position_set(efl_super(obj, EFL_UI_POPUP_CLASS), pos);
196}
197
198static void
199_anchor_geom_cb(void *data, const Efl_Event *ev EINA_UNUSED)
200{
201 _anchor_calc(data);
202}
203
204static void
205_anchor_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
206{
207 EFL_UI_POPUP_DATA_GET_OR_RETURN(data, ppd);
208 EFL_UI_ANCHOR_POPUP_DATA_GET(data, pd);
209
210 efl_event_callback_del(ppd->win_parent, EFL_GFX_ENTITY_EVENT_RESIZE, _anchor_geom_cb, data);
211
212 pd->anchor = NULL;
213 //Add align calc only
214 Eina_Bool needs_size_calc = ppd->needs_size_calc;
215 elm_layout_sizing_eval(data);
216 ppd->needs_size_calc = needs_size_calc;
217}
218
219static void
220_anchor_detach(Eo *obj)
221{
222 EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
223 EFL_UI_ANCHOR_POPUP_DATA_GET(obj, pd);
224
225 if (!pd->anchor) return;
226
227 efl_event_callback_del(ppd->win_parent, EFL_GFX_ENTITY_EVENT_RESIZE, _anchor_geom_cb, obj);
228 efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_RESIZE, _anchor_geom_cb, obj);
229 efl_event_callback_del(pd->anchor, EFL_GFX_ENTITY_EVENT_MOVE, _anchor_geom_cb, obj);
230 efl_event_callback_del(pd->anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
231}
232
233EOLIAN static void
234_efl_ui_anchor_popup_anchor_set(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd, Eo *anchor)
235{
236 EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
237
238 _anchor_detach(obj);
239 pd->anchor = anchor;
240
241 if (anchor)
242 {
243 efl_event_callback_add(ppd->win_parent, EFL_GFX_ENTITY_EVENT_RESIZE, _anchor_geom_cb, obj);
244 efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_RESIZE, _anchor_geom_cb, obj);
245 efl_event_callback_add(anchor, EFL_GFX_ENTITY_EVENT_MOVE, _anchor_geom_cb, obj);
246 efl_event_callback_add(anchor, EFL_EVENT_DEL, _anchor_del_cb, obj);
247 }
248
249 //Add align/anchor calc only
250 Eina_Bool needs_size_calc = ppd->needs_size_calc;
251 elm_layout_sizing_eval(obj);
252 ppd->needs_size_calc = needs_size_calc;
253}
254
255EOLIAN static Efl_Object *
256_efl_ui_anchor_popup_anchor_get(const Eo *obj EINA_UNUSED, Efl_Ui_Anchor_Popup_Data *pd)
257{
258 return pd->anchor;
259}
260
261EOLIAN static void
262_efl_ui_anchor_popup_align_priority_set(Eo *obj EINA_UNUSED,
263 Efl_Ui_Anchor_Popup_Data *pd,
264 Efl_Ui_Popup_Align first,
265 Efl_Ui_Popup_Align second,
266 Efl_Ui_Popup_Align third,
267 Efl_Ui_Popup_Align fourth,
268 Efl_Ui_Popup_Align fifth)
269{
270 pd->priority[0] = first;
271 pd->priority[1] = second;
272 pd->priority[2] = third;
273 pd->priority[3] = fourth;
274 pd->priority[4] = fifth;
275}
276
277EOLIAN static void
278_efl_ui_anchor_popup_align_priority_get(const Eo *obj EINA_UNUSED,
279 Efl_Ui_Anchor_Popup_Data *pd,
280 Efl_Ui_Popup_Align *first,
281 Efl_Ui_Popup_Align *second,
282 Efl_Ui_Popup_Align *third,
283 Efl_Ui_Popup_Align *fourth,
284 Efl_Ui_Popup_Align *fifth)
285{
286 if (first) *first = pd->priority[0];
287 if (second) *second = pd->priority[1];
288 if (third) *third = pd->priority[2];
289 if (fourth) *fourth = pd->priority[3];
290 if (fifth) *fifth = pd->priority[4];
291}
292
293EOLIAN static void
294_efl_ui_anchor_popup_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd, Eina_Position2D pos)
295{
296 _anchor_detach(obj);
297
298 pd->anchor = NULL;
299
300 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
301}
302
303EOLIAN static void
304_efl_ui_anchor_popup_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Anchor_Popup_Data *pd)
305{
306 EFL_UI_POPUP_DATA_GET_OR_RETURN(obj, ppd);
307 /* When elm_layout_sizing_eval() is called, just flag is set instead of size
308 * calculation.
309 * The actual size calculation is done here when the object is rendered to
310 * avoid duplicate size calculations. */
311 if (ppd->needs_group_calc)
312 {
313 if (pd->anchor)
314 ppd->needs_align_calc = EINA_FALSE;
315
316 efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
317
318 if (pd->anchor)
319 _anchor_calc(obj);
320 }
321}
322
323EOLIAN static Eo *
324_efl_ui_anchor_popup_efl_object_constructor(Eo *obj,
325 Efl_Ui_Anchor_Popup_Data *pd)
326{
327 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
328
329 if (!elm_widget_theme_klass_get(obj))
330 elm_widget_theme_klass_set(obj, "anchor_popup");
331 obj = efl_constructor(efl_super(obj, MY_CLASS));
332 efl_canvas_object_type_set(obj, MY_CLASS_NAME);
333
334 elm_widget_sub_object_parent_add(obj);
335
336 pd->priority[0] = EFL_UI_POPUP_ALIGN_TOP;
337 pd->priority[1] = EFL_UI_POPUP_ALIGN_LEFT;
338 pd->priority[2] = EFL_UI_POPUP_ALIGN_RIGHT;
339 pd->priority[3] = EFL_UI_POPUP_ALIGN_BOTTOM;
340 pd->priority[4] = EFL_UI_POPUP_ALIGN_CENTER;
341
342 return obj;
343}
344
345EOLIAN static void
346_efl_ui_anchor_popup_efl_object_destructor(Eo *obj,
347 Efl_Ui_Anchor_Popup_Data *pd EINA_UNUSED)
348{
349 _anchor_detach(obj);
350
351 efl_destructor(efl_super(obj, MY_CLASS));
352}
353
354#include "efl_ui_anchor_popup.eo.c"