diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/elementary/src/lib/elm_hover.c | 852 |
1 files changed, 852 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elm_hover.c b/libraries/elementary/src/lib/elm_hover.c new file mode 100644 index 0000000..ec92a9c --- /dev/null +++ b/libraries/elementary/src/lib/elm_hover.c | |||
@@ -0,0 +1,852 @@ | |||
1 | #include <Elementary.h> | ||
2 | #include "elm_priv.h" | ||
3 | |||
4 | typedef struct _Widget_Data Widget_Data; | ||
5 | typedef struct _Content_Info Content_Info; | ||
6 | |||
7 | #ifndef MAX | ||
8 | # define MAX(a, b) (((a) > (b)) ? (a) : (b)) | ||
9 | #endif | ||
10 | |||
11 | #define ELM_HOVER_PARTS_FOREACH unsigned int i = 0; \ | ||
12 | for (i = 0; i < sizeof(wd->subs) / sizeof(wd->subs[0]); i++) | ||
13 | |||
14 | static const char *_directions[] = { | ||
15 | "left", | ||
16 | "top-left", | ||
17 | "top", | ||
18 | "top-right", | ||
19 | "right", | ||
20 | "bottom-right", | ||
21 | "bottom", | ||
22 | "bottom-left", | ||
23 | "middle" | ||
24 | }; | ||
25 | |||
26 | #define _HOV_LEFT (_directions[0]) | ||
27 | #define _HOV_TOP_LEFT (_directions[1]) | ||
28 | #define _HOV_TOP (_directions[2]) | ||
29 | #define _HOV_TOP_RIGHT (_directions[2]) | ||
30 | #define _HOV_RIGHT (_directions[4]) | ||
31 | #define _HOV_BOTTOM_RIGHT (_directions[5]) | ||
32 | #define _HOV_BOTTOM (_directions[6]) | ||
33 | #define _HOV_BOTTOM_LEFT (_directions[7]) | ||
34 | #define _HOV_MIDDLE (_directions[8]) | ||
35 | |||
36 | struct _Content_Info | ||
37 | { | ||
38 | const char *swallow; | ||
39 | Evas_Object *obj; | ||
40 | }; | ||
41 | |||
42 | struct _Widget_Data | ||
43 | { | ||
44 | Evas_Object *hov, *cov; | ||
45 | Evas_Object *offset, *size; | ||
46 | Evas_Object *parent, *target; | ||
47 | Evas_Object *smt_sub; | ||
48 | Content_Info subs[sizeof(_directions)/sizeof(_directions[0])]; | ||
49 | }; | ||
50 | |||
51 | static const char *widtype = NULL; | ||
52 | static void _del_pre_hook(Evas_Object *obj); | ||
53 | static void _del_hook(Evas_Object *obj); | ||
54 | static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); | ||
55 | static void _theme_hook(Evas_Object *obj); | ||
56 | static void _sizing_eval(Evas_Object *obj); | ||
57 | static void _reval_content(Evas_Object *obj); | ||
58 | static void _sub_del(void *data, Evas_Object *obj, void *event_info); | ||
59 | static void _hov_show_do(Evas_Object *obj); | ||
60 | static void _hov_move(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
61 | static void _hov_resize(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
62 | static void _hov_show(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
63 | static void _hov_hide(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
64 | static void _on_focus_hook(void *data, Evas_Object *obj); | ||
65 | static void _elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
66 | static void _elm_hover_sub_obj_placement_eval(Evas_Object *obj); | ||
67 | static void _content_set_hook(Evas_Object *obj, const char *swallow, Evas_Object *content); | ||
68 | static Evas_Object * _content_get_hook(const Evas_Object *obj, const char *swallow); | ||
69 | static Evas_Object * _content_unset_hook(Evas_Object *obj, const char *swallow); | ||
70 | |||
71 | static const char SIG_CLICKED[] = "clicked"; | ||
72 | static const char SIG_SMART_LOCATION_CHANGED[] = "smart,changed"; | ||
73 | static const Evas_Smart_Cb_Description _signals[] = { | ||
74 | {SIG_CLICKED, ""}, | ||
75 | {SIG_SMART_LOCATION_CHANGED, ""}, | ||
76 | {NULL, NULL} | ||
77 | }; | ||
78 | |||
79 | static void | ||
80 | _del_pre_hook(Evas_Object *obj) | ||
81 | { | ||
82 | Widget_Data *wd = elm_widget_data_get(obj); | ||
83 | if (!wd) | ||
84 | return; | ||
85 | |||
86 | if (evas_object_visible_get(obj)) | ||
87 | evas_object_smart_callback_call(obj, SIG_CLICKED, NULL); | ||
88 | elm_hover_target_set(obj, NULL); | ||
89 | elm_hover_parent_set(obj, NULL); | ||
90 | evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj); | ||
91 | evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj); | ||
92 | evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj); | ||
93 | evas_object_event_callback_del_full(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj); | ||
94 | } | ||
95 | |||
96 | static void | ||
97 | _del_hook(Evas_Object *obj) | ||
98 | { | ||
99 | Widget_Data *wd = elm_widget_data_get(obj); | ||
100 | if (!wd) return; | ||
101 | free(wd); | ||
102 | } | ||
103 | |||
104 | static void | ||
105 | _on_focus_hook(void *data __UNUSED__, Evas_Object *obj) | ||
106 | { | ||
107 | Widget_Data *wd = elm_widget_data_get(obj); | ||
108 | if (!wd) return; | ||
109 | if (elm_widget_focus_get(obj)) | ||
110 | { | ||
111 | edje_object_signal_emit(wd->cov, "elm,action,focus", "elm"); | ||
112 | evas_object_focus_set(wd->cov, EINA_TRUE); | ||
113 | } | ||
114 | else | ||
115 | { | ||
116 | edje_object_signal_emit(wd->cov, "elm,action,unfocus", "elm"); | ||
117 | evas_object_focus_set(wd->cov, EINA_FALSE); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static void | ||
122 | _mirrored_set(Evas_Object *obj, Eina_Bool rtl) | ||
123 | { | ||
124 | Widget_Data *wd = elm_widget_data_get(obj); | ||
125 | if (!wd) return; | ||
126 | edje_object_mirrored_set(wd->cov, rtl); | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | _theme_hook(Evas_Object *obj) | ||
131 | { | ||
132 | Widget_Data *wd = elm_widget_data_get(obj); | ||
133 | if (!wd) return; | ||
134 | _elm_widget_mirrored_reload(obj); | ||
135 | _mirrored_set(obj, elm_widget_mirrored_get(obj)); | ||
136 | // FIXME: hover contents doesn't seem to propagate resizes properly | ||
137 | _elm_theme_object_set(obj, wd->cov, "hover", "base", elm_widget_style_get(obj)); | ||
138 | edje_object_scale_set(wd->cov, elm_widget_scale_get(obj) * | ||
139 | _elm_config->scale); | ||
140 | |||
141 | if (wd->smt_sub) | ||
142 | _elm_hover_sub_obj_placement_eval(obj); | ||
143 | else | ||
144 | _reval_content(obj); | ||
145 | _sizing_eval(obj); | ||
146 | if (evas_object_visible_get(wd->cov)) _hov_show_do(obj); | ||
147 | } | ||
148 | |||
149 | static void | ||
150 | _signal_emit_hook(Evas_Object *obj, const char *emission, const char *source) | ||
151 | { | ||
152 | Widget_Data *wd; | ||
153 | |||
154 | wd = elm_widget_data_get(obj); | ||
155 | if (!wd) | ||
156 | return; | ||
157 | |||
158 | edje_object_signal_emit(wd->cov, emission, source); | ||
159 | } | ||
160 | |||
161 | static void | ||
162 | _signal_callback_add_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) | ||
163 | { | ||
164 | Widget_Data *wd; | ||
165 | |||
166 | wd = elm_widget_data_get(obj); | ||
167 | if (!wd) | ||
168 | return; | ||
169 | |||
170 | edje_object_signal_callback_add(wd->hov, emission, source, func_cb, data); | ||
171 | } | ||
172 | |||
173 | static void | ||
174 | _signal_callback_del_hook(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb func_cb, void *data) | ||
175 | { | ||
176 | Widget_Data *wd; | ||
177 | |||
178 | wd = elm_widget_data_get(obj); | ||
179 | |||
180 | edje_object_signal_callback_del_full(wd->hov, emission, source, func_cb, | ||
181 | data); | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | _elm_hover_left_space_calc(Widget_Data *wd, Evas_Coord *spc_l, Evas_Coord *spc_t, Evas_Coord *spc_r, Evas_Coord *spc_b) | ||
186 | { | ||
187 | Evas_Coord x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0; | ||
188 | |||
189 | if (wd->parent) | ||
190 | evas_object_geometry_get(wd->parent, &x, &y, &w, &h); | ||
191 | if (wd->target) | ||
192 | evas_object_geometry_get(wd->target, &x2, &y2, &w2, &h2); | ||
193 | |||
194 | *spc_l = x2 - x; | ||
195 | *spc_r = (x + w) - (x2 + w2); | ||
196 | if (*spc_l < 0) | ||
197 | *spc_l = 0; | ||
198 | if (*spc_r < 0) | ||
199 | *spc_r = 0; | ||
200 | |||
201 | *spc_t = y2 - y; | ||
202 | *spc_b = (y + h) - (y2 + h2); | ||
203 | if (*spc_t < 0) | ||
204 | *spc_t = 0; | ||
205 | if (*spc_b < 0) | ||
206 | *spc_b = 0; | ||
207 | } | ||
208 | |||
209 | static void | ||
210 | _sizing_eval(Evas_Object *obj) | ||
211 | { | ||
212 | Widget_Data *wd = elm_widget_data_get(obj); | ||
213 | Evas_Coord ofs_x, x = 0, y = 0, w = 0, h = 0, x2 = 0, y2 = 0, w2 = 0, h2 = 0; | ||
214 | if (!wd) return; | ||
215 | if (wd->parent) evas_object_geometry_get(wd->parent, &x, &y, &w, &h); | ||
216 | if (wd->hov) evas_object_geometry_get(wd->hov, &x2, &y2, &w2, &h2); | ||
217 | |||
218 | if (elm_widget_mirrored_get(obj)) | ||
219 | ofs_x = w - (x2 - x) - w2; | ||
220 | else | ||
221 | ofs_x = x2 - x; | ||
222 | |||
223 | evas_object_move(wd->cov, x, y); | ||
224 | evas_object_resize(wd->cov, w, h); | ||
225 | evas_object_size_hint_min_set(wd->offset, ofs_x, y2 - y); | ||
226 | evas_object_size_hint_min_set(wd->size, w2, h2); | ||
227 | edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset); | ||
228 | edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size); | ||
229 | } | ||
230 | |||
231 | static void | ||
232 | _reval_content(Evas_Object *obj) | ||
233 | { | ||
234 | Widget_Data *wd = elm_widget_data_get(obj); | ||
235 | if (!wd) | ||
236 | return; | ||
237 | |||
238 | ELM_HOVER_PARTS_FOREACH | ||
239 | { | ||
240 | char buf[1024]; | ||
241 | snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", wd->subs[i].swallow); | ||
242 | edje_object_part_swallow(wd->cov, buf, wd->subs[i].obj); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static const char * | ||
247 | _elm_hover_smart_content_location_get(Widget_Data *wd, Evas_Coord spc_l, Evas_Coord spc_t, Evas_Coord spc_r, Evas_Coord spc_b) | ||
248 | { | ||
249 | Evas_Coord c_w = 0, c_h = 0, mid_w, mid_h; | ||
250 | int max; | ||
251 | |||
252 | evas_object_size_hint_min_get(wd->smt_sub, &c_w, &c_h); | ||
253 | mid_w = c_w / 2; | ||
254 | mid_h = c_h / 2; | ||
255 | |||
256 | if (spc_l > spc_r) | ||
257 | goto left; | ||
258 | |||
259 | max = MAX(spc_t, spc_r); | ||
260 | max = MAX(max, spc_b); | ||
261 | |||
262 | if (max == spc_t) | ||
263 | { | ||
264 | if (mid_w > spc_l) | ||
265 | return _HOV_TOP_RIGHT; | ||
266 | |||
267 | return _HOV_TOP; | ||
268 | } | ||
269 | |||
270 | if (max == spc_r) | ||
271 | { | ||
272 | if (mid_h > spc_t) | ||
273 | return _HOV_BOTTOM_RIGHT; | ||
274 | else if (mid_h > spc_b) | ||
275 | return _HOV_TOP_RIGHT; | ||
276 | |||
277 | return _HOV_RIGHT; | ||
278 | } | ||
279 | |||
280 | if (mid_h > spc_l) | ||
281 | return _HOV_BOTTOM_RIGHT; | ||
282 | |||
283 | return _HOV_BOTTOM; | ||
284 | |||
285 | left: | ||
286 | max = MAX(spc_t, spc_l); | ||
287 | max = MAX(max, spc_b); | ||
288 | |||
289 | if (max == spc_t) | ||
290 | { | ||
291 | if (mid_w > spc_r) | ||
292 | return _HOV_TOP_LEFT; | ||
293 | |||
294 | return _HOV_TOP; | ||
295 | } | ||
296 | |||
297 | if (max == spc_l) | ||
298 | { | ||
299 | if (mid_h > spc_t) | ||
300 | return _HOV_BOTTOM_LEFT; | ||
301 | else if (mid_h > spc_b) | ||
302 | return _HOV_TOP_LEFT; | ||
303 | |||
304 | return _HOV_LEFT; | ||
305 | } | ||
306 | |||
307 | if (mid_h > spc_r) | ||
308 | return _HOV_BOTTOM_LEFT; | ||
309 | |||
310 | return _HOV_BOTTOM; | ||
311 | } | ||
312 | |||
313 | static void | ||
314 | _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info) | ||
315 | { | ||
316 | Widget_Data *wd; | ||
317 | Evas_Object *sub; | ||
318 | |||
319 | sub = event_info; | ||
320 | wd = elm_widget_data_get(obj); | ||
321 | if (!wd) | ||
322 | return; | ||
323 | |||
324 | if (wd->smt_sub) | ||
325 | { | ||
326 | if (wd->smt_sub == sub) | ||
327 | wd->smt_sub = NULL; | ||
328 | } | ||
329 | else | ||
330 | { | ||
331 | ELM_HOVER_PARTS_FOREACH | ||
332 | { | ||
333 | if (wd->subs[i].obj == sub) | ||
334 | { | ||
335 | wd->subs[i].obj = NULL; | ||
336 | break; | ||
337 | } | ||
338 | } | ||
339 | } | ||
340 | } | ||
341 | |||
342 | static void | ||
343 | _hov_show_do(Evas_Object *obj) | ||
344 | { | ||
345 | Widget_Data *wd = elm_widget_data_get(obj); | ||
346 | if (!wd) | ||
347 | return; | ||
348 | |||
349 | if (wd->cov) | ||
350 | { | ||
351 | evas_object_show(wd->cov); | ||
352 | edje_object_signal_emit(wd->cov, "elm,action,show", "elm"); | ||
353 | } | ||
354 | |||
355 | ELM_HOVER_PARTS_FOREACH | ||
356 | { | ||
357 | char buf[1024]; | ||
358 | |||
359 | if (wd->subs[i].obj) | ||
360 | { | ||
361 | snprintf(buf, sizeof(buf), "elm,action,slot,%s,show", | ||
362 | wd->subs[i].swallow); | ||
363 | edje_object_signal_emit(wd->cov, buf, "elm"); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | static void | ||
369 | _hov_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
370 | { | ||
371 | _sizing_eval(data); | ||
372 | } | ||
373 | |||
374 | static void | ||
375 | _hov_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
376 | { | ||
377 | _sizing_eval(data); | ||
378 | } | ||
379 | |||
380 | static void | ||
381 | _hov_show(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
382 | { | ||
383 | _hov_show_do(data); | ||
384 | } | ||
385 | |||
386 | static void | ||
387 | _hov_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
388 | { | ||
389 | Widget_Data *wd = elm_widget_data_get(data); | ||
390 | if (!wd) return; | ||
391 | if (wd->cov) | ||
392 | { | ||
393 | edje_object_signal_emit(wd->cov, "elm,action,hide", "elm"); | ||
394 | evas_object_hide(wd->cov); | ||
395 | } | ||
396 | |||
397 | ELM_HOVER_PARTS_FOREACH | ||
398 | { | ||
399 | char buf[1024]; | ||
400 | |||
401 | if (wd->subs[i].obj) | ||
402 | { | ||
403 | snprintf(buf, sizeof(buf), "elm,action,slot,%s,hide", | ||
404 | wd->subs[i].swallow); | ||
405 | edje_object_signal_emit(wd->cov, buf, "elm"); | ||
406 | } | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void | ||
411 | _target_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
412 | { | ||
413 | Widget_Data *wd = elm_widget_data_get(data); | ||
414 | if (!wd) return; | ||
415 | wd->target = NULL; | ||
416 | } | ||
417 | |||
418 | static void | ||
419 | _target_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
420 | { | ||
421 | Widget_Data *wd = elm_widget_data_get(data); | ||
422 | if (!wd) | ||
423 | return; | ||
424 | |||
425 | _sizing_eval(data); | ||
426 | _elm_hover_sub_obj_placement_eval(data); | ||
427 | } | ||
428 | |||
429 | static void | ||
430 | _signal_dismiss(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__) | ||
431 | { | ||
432 | Widget_Data *wd = elm_widget_data_get(data); | ||
433 | if (!wd) return; | ||
434 | evas_object_hide(data); | ||
435 | evas_object_smart_callback_call(data, SIG_CLICKED, NULL); | ||
436 | } | ||
437 | |||
438 | static void | ||
439 | _parent_move(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
440 | { | ||
441 | _sizing_eval(data); | ||
442 | } | ||
443 | |||
444 | static void | ||
445 | _parent_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
446 | { | ||
447 | _sizing_eval(data); | ||
448 | } | ||
449 | |||
450 | static void | ||
451 | _parent_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
452 | { | ||
453 | } | ||
454 | |||
455 | static void | ||
456 | _parent_hide(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
457 | { | ||
458 | Widget_Data *wd = elm_widget_data_get(data); | ||
459 | if (!wd) return; | ||
460 | evas_object_hide(wd->cov); | ||
461 | } | ||
462 | |||
463 | static void | ||
464 | _parent_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
465 | { | ||
466 | Widget_Data *wd = elm_widget_data_get(data); | ||
467 | if (!wd) return; | ||
468 | elm_hover_parent_set(data, NULL); | ||
469 | _sizing_eval(data); | ||
470 | } | ||
471 | |||
472 | EAPI Evas_Object * | ||
473 | elm_hover_add(Evas_Object *parent) | ||
474 | { | ||
475 | Evas_Object *obj; | ||
476 | Evas *e; | ||
477 | Widget_Data *wd; | ||
478 | |||
479 | ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL); | ||
480 | |||
481 | ELM_SET_WIDTYPE(widtype, "hover"); | ||
482 | elm_widget_type_set(obj, "hover"); | ||
483 | elm_widget_sub_object_add(parent, obj); | ||
484 | elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL); | ||
485 | elm_widget_data_set(obj, wd); | ||
486 | elm_widget_del_pre_hook_set(obj, _del_pre_hook); | ||
487 | elm_widget_theme_hook_set(obj, _theme_hook); | ||
488 | elm_widget_del_hook_set(obj, _del_hook); | ||
489 | elm_widget_can_focus_set(obj, EINA_TRUE); | ||
490 | elm_widget_signal_emit_hook_set(obj, _signal_emit_hook); | ||
491 | elm_widget_signal_callback_add_hook_set(obj, _signal_callback_add_hook); | ||
492 | elm_widget_signal_callback_del_hook_set(obj, _signal_callback_del_hook); | ||
493 | elm_widget_content_set_hook_set(obj, _content_set_hook); | ||
494 | elm_widget_content_get_hook_set(obj, _content_get_hook); | ||
495 | elm_widget_content_unset_hook_set(obj, _content_unset_hook); | ||
496 | |||
497 | ELM_HOVER_PARTS_FOREACH | ||
498 | wd->subs[i].swallow = _directions[i]; | ||
499 | |||
500 | wd->hov = evas_object_rectangle_add(e); | ||
501 | evas_object_pass_events_set(wd->hov, EINA_TRUE); | ||
502 | evas_object_color_set(wd->hov, 0, 0, 0, 0); | ||
503 | elm_widget_resize_object_set(obj, wd->hov); | ||
504 | evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_MOVE, _hov_move, obj); | ||
505 | evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_RESIZE, _hov_resize, obj); | ||
506 | evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_SHOW, _hov_show, obj); | ||
507 | evas_object_event_callback_add(wd->hov, EVAS_CALLBACK_HIDE, _hov_hide, obj); | ||
508 | |||
509 | wd->cov = edje_object_add(e); | ||
510 | _elm_theme_object_set(obj, wd->cov, "hover", "base", "default"); | ||
511 | elm_widget_sub_object_add(obj, wd->cov); | ||
512 | edje_object_signal_callback_add(wd->cov, "elm,action,dismiss", "", | ||
513 | _signal_dismiss, obj); | ||
514 | |||
515 | wd->offset = evas_object_rectangle_add(e); | ||
516 | evas_object_pass_events_set(wd->offset, EINA_TRUE); | ||
517 | evas_object_color_set(wd->offset, 0, 0, 0, 0); | ||
518 | elm_widget_sub_object_add(obj, wd->offset); | ||
519 | |||
520 | wd->size = evas_object_rectangle_add(e); | ||
521 | evas_object_pass_events_set(wd->size, EINA_TRUE); | ||
522 | evas_object_color_set(wd->size, 0, 0, 0, 0); | ||
523 | elm_widget_sub_object_add(obj, wd->size); | ||
524 | |||
525 | edje_object_part_swallow(wd->cov, "elm.swallow.offset", wd->offset); | ||
526 | edje_object_part_swallow(wd->cov, "elm.swallow.size", wd->size); | ||
527 | |||
528 | evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj); | ||
529 | |||
530 | elm_hover_parent_set(obj, parent); | ||
531 | evas_object_smart_callbacks_descriptions_set(obj, _signals); | ||
532 | |||
533 | _mirrored_set(obj, elm_widget_mirrored_get(obj)); | ||
534 | _sizing_eval(obj); | ||
535 | return obj; | ||
536 | } | ||
537 | |||
538 | EAPI void | ||
539 | elm_hover_target_set(Evas_Object *obj, Evas_Object *target) | ||
540 | { | ||
541 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
542 | Widget_Data *wd = elm_widget_data_get(obj); | ||
543 | |||
544 | if (wd->target) | ||
545 | { | ||
546 | evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_DEL, | ||
547 | _target_del, obj); | ||
548 | evas_object_event_callback_del_full(wd->target, EVAS_CALLBACK_MOVE, | ||
549 | _target_move, obj); | ||
550 | } | ||
551 | wd->target = target; | ||
552 | if (wd->target) | ||
553 | { | ||
554 | evas_object_event_callback_add(wd->target, EVAS_CALLBACK_DEL, | ||
555 | _target_del, obj); | ||
556 | evas_object_event_callback_add(wd->target, EVAS_CALLBACK_MOVE, | ||
557 | _target_move, obj); | ||
558 | elm_widget_hover_object_set(target, obj); | ||
559 | _sizing_eval(obj); | ||
560 | } | ||
561 | } | ||
562 | |||
563 | |||
564 | EAPI void | ||
565 | elm_hover_parent_set(Evas_Object *obj, Evas_Object *parent) | ||
566 | { | ||
567 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
568 | Widget_Data *wd = elm_widget_data_get(obj); | ||
569 | if (!wd) return; | ||
570 | if (wd->parent) | ||
571 | { | ||
572 | evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_MOVE, | ||
573 | _parent_move, obj); | ||
574 | evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, | ||
575 | _parent_resize, obj); | ||
576 | evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_SHOW, | ||
577 | _parent_show, obj); | ||
578 | evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_HIDE, | ||
579 | _parent_hide, obj); | ||
580 | evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_DEL, | ||
581 | _parent_del, obj); | ||
582 | } | ||
583 | wd->parent = parent; | ||
584 | if (wd->parent) | ||
585 | { | ||
586 | evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_MOVE, | ||
587 | _parent_move, obj); | ||
588 | evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_RESIZE, | ||
589 | _parent_resize, obj); | ||
590 | evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_SHOW, | ||
591 | _parent_show, obj); | ||
592 | evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_HIDE, | ||
593 | _parent_hide, obj); | ||
594 | evas_object_event_callback_add(wd->parent, EVAS_CALLBACK_DEL, | ||
595 | _parent_del, obj); | ||
596 | // elm_widget_sub_object_add(parent, obj); | ||
597 | } | ||
598 | _sizing_eval(obj); | ||
599 | } | ||
600 | |||
601 | EAPI Evas_Object * | ||
602 | elm_hover_target_get(const Evas_Object *obj) | ||
603 | { | ||
604 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
605 | Widget_Data *wd = elm_widget_data_get(obj); | ||
606 | if (!wd) return NULL; | ||
607 | |||
608 | return wd->target; | ||
609 | } | ||
610 | |||
611 | EAPI Evas_Object * | ||
612 | elm_hover_parent_get(const Evas_Object *obj) | ||
613 | { | ||
614 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
615 | Widget_Data *wd = elm_widget_data_get(obj); | ||
616 | if (!wd) return NULL; | ||
617 | |||
618 | return wd->parent; | ||
619 | } | ||
620 | |||
621 | static void | ||
622 | _elm_hover_subs_del(Widget_Data *wd) | ||
623 | { | ||
624 | ELM_HOVER_PARTS_FOREACH | ||
625 | { | ||
626 | if (wd->subs[i].obj) | ||
627 | { | ||
628 | evas_object_del(wd->subs[i].obj); | ||
629 | wd->subs[i].obj = NULL; | ||
630 | } | ||
631 | } | ||
632 | } | ||
633 | |||
634 | static void | ||
635 | _elm_hover_sub_obj_placement_eval(Evas_Object *obj) | ||
636 | { | ||
637 | Evas_Coord spc_l, spc_r, spc_t, spc_b; | ||
638 | const char *smart_dir; | ||
639 | Widget_Data *wd; | ||
640 | char buf[1024]; | ||
641 | |||
642 | wd = elm_widget_data_get(obj); | ||
643 | if (!wd->smt_sub) | ||
644 | return; | ||
645 | |||
646 | _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b); | ||
647 | |||
648 | edje_object_part_unswallow(wd->cov, wd->smt_sub); | ||
649 | |||
650 | smart_dir = _elm_hover_smart_content_location_get(wd, spc_l, spc_t, spc_r, | ||
651 | spc_b); | ||
652 | evas_object_smart_callback_call(obj, SIG_SMART_LOCATION_CHANGED, | ||
653 | (void *)smart_dir); | ||
654 | |||
655 | if (elm_widget_mirrored_get(obj)) | ||
656 | { | ||
657 | if (smart_dir == _HOV_BOTTOM_LEFT) | ||
658 | smart_dir = _HOV_BOTTOM_RIGHT; | ||
659 | else if (smart_dir == _HOV_BOTTOM_RIGHT) | ||
660 | smart_dir = _HOV_BOTTOM_LEFT; | ||
661 | else if (smart_dir == _HOV_RIGHT) | ||
662 | smart_dir = _HOV_LEFT; | ||
663 | else if (smart_dir == _HOV_LEFT) | ||
664 | smart_dir = _HOV_RIGHT; | ||
665 | else if (smart_dir == _HOV_TOP_RIGHT) | ||
666 | smart_dir = _HOV_TOP_LEFT; | ||
667 | else if (smart_dir == _HOV_TOP_LEFT) | ||
668 | smart_dir = _HOV_TOP_RIGHT; | ||
669 | } | ||
670 | snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", smart_dir); | ||
671 | edje_object_part_swallow(wd->cov, buf, wd->smt_sub); | ||
672 | } | ||
673 | |||
674 | static void | ||
675 | _elm_hover_sub_obj_placement_eval_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
676 | { | ||
677 | _elm_hover_sub_obj_placement_eval(data); | ||
678 | } | ||
679 | |||
680 | static void | ||
681 | _elm_hover_sub_obj_unparent(Evas_Object *obj) | ||
682 | { | ||
683 | Widget_Data *wd; | ||
684 | Evas_Object *smt_sub; | ||
685 | |||
686 | wd = elm_widget_data_get(obj); | ||
687 | if (!wd) return; | ||
688 | |||
689 | smt_sub = wd->smt_sub; | ||
690 | elm_widget_sub_object_del(obj, wd->smt_sub); | ||
691 | evas_object_event_callback_del_full(smt_sub, | ||
692 | EVAS_CALLBACK_CHANGED_SIZE_HINTS, | ||
693 | _elm_hover_sub_obj_placement_eval_cb, | ||
694 | obj); | ||
695 | edje_object_part_unswallow(wd->cov, smt_sub); | ||
696 | } | ||
697 | |||
698 | EAPI const char * | ||
699 | elm_hover_best_content_location_get(const Evas_Object *obj, Elm_Hover_Axis pref_axis) | ||
700 | { | ||
701 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
702 | |||
703 | Evas_Coord spc_l, spc_r, spc_t, spc_b; | ||
704 | Widget_Data *wd; | ||
705 | |||
706 | wd = elm_widget_data_get(obj); | ||
707 | if (!wd) | ||
708 | return NULL; | ||
709 | |||
710 | _elm_hover_left_space_calc(wd, &spc_l, &spc_t, &spc_r, &spc_b); | ||
711 | |||
712 | if (pref_axis == ELM_HOVER_AXIS_HORIZONTAL) | ||
713 | { | ||
714 | if (spc_l < spc_r) return _HOV_RIGHT; | ||
715 | else return _HOV_LEFT; | ||
716 | } | ||
717 | else if (pref_axis == ELM_HOVER_AXIS_VERTICAL) | ||
718 | { | ||
719 | if (spc_t < spc_b) return _HOV_BOTTOM; | ||
720 | else return _HOV_TOP; | ||
721 | } | ||
722 | |||
723 | if (spc_l < spc_r) | ||
724 | { | ||
725 | if (spc_t > spc_r) return _HOV_TOP; | ||
726 | else if (spc_b > spc_r) return _HOV_BOTTOM; | ||
727 | return _HOV_RIGHT; | ||
728 | } | ||
729 | if (spc_t > spc_r) return _HOV_TOP; | ||
730 | else if (spc_b > spc_r) return _HOV_BOTTOM; | ||
731 | return _HOV_LEFT; | ||
732 | } | ||
733 | |||
734 | EAPI void | ||
735 | elm_hover_dismiss(Evas_Object *obj) | ||
736 | { | ||
737 | Widget_Data *wd; | ||
738 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
739 | wd = elm_widget_data_get(obj); | ||
740 | if (!wd) return; | ||
741 | |||
742 | edje_object_signal_emit(wd->cov, "elm,action,dismiss", ""); | ||
743 | } | ||
744 | |||
745 | static void | ||
746 | _content_set_hook(Evas_Object *obj, const char *swallow, Evas_Object *content) | ||
747 | { | ||
748 | ELM_CHECK_WIDTYPE(obj, widtype); | ||
749 | Widget_Data *wd = elm_widget_data_get(obj); | ||
750 | if (!wd) return; | ||
751 | |||
752 | if (!strcmp(swallow, "smart")) | ||
753 | { | ||
754 | if (wd->smt_sub != content) | ||
755 | { | ||
756 | _elm_hover_subs_del(wd); | ||
757 | wd->smt_sub = content; | ||
758 | } | ||
759 | |||
760 | if (content) | ||
761 | { | ||
762 | elm_widget_sub_object_add(obj, content); | ||
763 | evas_object_event_callback_add(wd->smt_sub, | ||
764 | EVAS_CALLBACK_CHANGED_SIZE_HINTS, | ||
765 | _elm_hover_sub_obj_placement_eval_cb, | ||
766 | obj); | ||
767 | |||
768 | _elm_hover_sub_obj_placement_eval(obj); | ||
769 | } | ||
770 | |||
771 | goto end; | ||
772 | } | ||
773 | |||
774 | if (wd->smt_sub) | ||
775 | { | ||
776 | evas_object_del(wd->smt_sub); | ||
777 | wd->smt_sub = NULL; | ||
778 | } | ||
779 | |||
780 | ELM_HOVER_PARTS_FOREACH | ||
781 | { | ||
782 | if (!strcmp(swallow, wd->subs[i].swallow)) | ||
783 | { | ||
784 | if (content == wd->subs[i].obj) | ||
785 | return; | ||
786 | evas_object_del(wd->subs[i].obj); | ||
787 | wd->subs[i].obj = NULL; | ||
788 | |||
789 | if (content) | ||
790 | { | ||
791 | char buf[1024]; | ||
792 | |||
793 | snprintf(buf, sizeof(buf), "elm.swallow.slot.%s", swallow); | ||
794 | elm_widget_sub_object_add(obj, content); | ||
795 | edje_object_part_swallow(wd->cov, buf, content); | ||
796 | wd->subs[i].obj = content; | ||
797 | } | ||
798 | break; | ||
799 | } | ||
800 | } | ||
801 | end: | ||
802 | _sizing_eval(obj); | ||
803 | } | ||
804 | |||
805 | static Evas_Object * | ||
806 | _content_get_hook(const Evas_Object *obj, const char *swallow) | ||
807 | { | ||
808 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
809 | |||
810 | Widget_Data *wd = elm_widget_data_get(obj); | ||
811 | if (!wd) return NULL; | ||
812 | |||
813 | if (!strcmp(swallow, "smart")) | ||
814 | return wd->smt_sub; | ||
815 | |||
816 | ELM_HOVER_PARTS_FOREACH | ||
817 | if (!strcmp(swallow, wd->subs[i].swallow)) | ||
818 | return wd->subs[i].obj; | ||
819 | |||
820 | return NULL; | ||
821 | } | ||
822 | |||
823 | static Evas_Object * | ||
824 | _content_unset_hook(Evas_Object *obj, const char *swallow) | ||
825 | { | ||
826 | ELM_CHECK_WIDTYPE(obj, widtype) NULL; | ||
827 | |||
828 | Widget_Data *wd = elm_widget_data_get(obj); | ||
829 | if (!wd) return NULL; | ||
830 | |||
831 | if (!strcmp(swallow, "smart")) | ||
832 | { | ||
833 | if (!wd->smt_sub) return NULL; | ||
834 | Evas_Object *content = wd->smt_sub; | ||
835 | _elm_hover_sub_obj_unparent(obj); | ||
836 | return content; | ||
837 | } | ||
838 | |||
839 | ELM_HOVER_PARTS_FOREACH | ||
840 | { | ||
841 | if (!strcmp(swallow, wd->subs[i].swallow)) | ||
842 | { | ||
843 | if (!wd->subs[i].obj) return NULL; | ||
844 | Evas_Object *content = wd->subs[i].obj; | ||
845 | elm_widget_sub_object_del(obj, wd->subs[i].obj); | ||
846 | edje_object_part_unswallow(wd->cov, content); | ||
847 | return content; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | return NULL; | ||
852 | } | ||