1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define ELM_LAYOUT_PROTECTED
7 #define EFL_UI_WIDGET_PART_BG_PROTECTED
8 #define EFL_PART_PROTECTED
9 #define EFL_LAYOUT_CALC_PROTECTED
10
11 #include <Elementary.h>
12
13 #include "elm_priv.h"
14 #include "elm_widget_layout.h"
15 #include "elm_part_helper.h"
16 #include "elm_entry_eo.h"
17
18 #define MY_CLASS EFL_UI_LAYOUT_BASE_CLASS
19 #define MY_CLASS_PFX efl_ui_layout
20
21 #define MY_CLASS_NAME "Efl.Ui.Layout"
22
23 Eo *_efl_ui_layout_pack_proxy_get(Efl_Ui_Layout *obj, Edje_Part_Type type, const char *part);
24 static void _efl_model_properties_changed_cb(void *, const Efl_Event *);
25 static Eina_Bool _efl_ui_layout_part_cursor_unset(Efl_Ui_Layout_Data *sd, const char *part_name);
26
27 static const char SIG_THEME_CHANGED[] = "theme,changed";
28 const char SIG_LAYOUT_FOCUSED[] = "focused";
29 const char SIG_LAYOUT_UNFOCUSED[] = "unfocused";
30
31 const char SIGNAL_PREFIX[] = "signal/";
32
33 /* smart callbacks coming from elm layout objects: */
34 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
35 {SIG_THEME_CHANGED, ""},
36 {SIG_LAYOUT_FOCUSED, ""},
37 {SIG_LAYOUT_UNFOCUSED, ""},
38 {SIG_WIDGET_LANG_CHANGED, ""}, /**< handled by elm_widget */
39 {SIG_WIDGET_ACCESS_CHANGED, ""}, /**< handled by elm_widget */
40 {NULL, NULL}
41 };
42
43 static const char efl_ui_default_text[] = "efl.text";
44 static const char efl_ui_default_content[] = "efl.content";
45
46 static const Elm_Layout_Part_Alias_Description _text_aliases[] =
47 {
48 {"default", "elm.text"},
49 {NULL, NULL}
50 };
51
52 static const Elm_Layout_Part_Alias_Description _content_aliases[] =
53 {
54 {"default", "elm.swallow.content"},
55 {NULL, NULL}
56 };
57
58 static const char *_elm_legacy_layout_swallow_parts[] = {
59 "elm.swallow.icon",
60 "elm.swallow.end",
61 "elm.swallow.background",
62 NULL
63 };
64
65 static const char *_efl_ui_layout_swallow_parts[] = {
66 "efl.content",
67 "efl.icon",
68 "efl.background",
69 "efl.extra",
70 NULL
71 };
72
73 typedef struct _Deferred_Version_Signal
74 {
75 Eina_Stringshare *old_sig;
76 Eina_Stringshare *new_sig;
77 unsigned int version_threshold;
78 } Deferred_Version_Signal;
79
80 typedef struct _Efl_Ui_Layout_Factory_Tracking Efl_Ui_Layout_Factory_Tracking;
81
82 struct _Efl_Ui_Layout_Factory_Tracking
83 {
84 Efl_Ui_Factory *factory;
85 Eina_Future *in_flight;
86 Eina_Stringshare *key;
87 };
88
89
90 /* these are data operated by layout's class functions internally, and
91 * should not be messed up by inhering classes */
92 typedef struct _Efl_Ui_Layout_Sub_Object_Data Efl_Ui_Layout_Sub_Object_Data;
93 typedef struct _Efl_Ui_Layout_Sub_Object_Cursor Efl_Ui_Layout_Sub_Object_Cursor;
94 typedef struct _Efl_Ui_Layout_Sub_Iterator Efl_Ui_Layout_Sub_Iterator;
95
96 struct _Efl_Ui_Layout_Sub_Iterator
97 {
98 Eina_Iterator iterator;
99 Eina_Iterator *real_iterator;
100 Efl_Ui_Layout *object;
101 };
102
103 struct _Efl_Ui_Layout_Sub_Object_Data
104 {
105 const char *part;
106 Evas_Object *obj;
107
108 enum {
109 SWALLOW,
110 BOX_APPEND,
111 BOX_PREPEND,
112 BOX_INSERT_BEFORE,
113 BOX_INSERT_AT,
114 TABLE_PACK,
115 TEXT
116 } type;
117
118 union {
119 union {
120 const Evas_Object *reference;
121 unsigned int pos;
122 } box;
123 struct
124 {
125 unsigned short col, row, colspan, rowspan;
126 } table;
127 } p;
128 };
129
130 struct _Efl_Ui_Layout_Sub_Object_Cursor
131 {
132 Evas_Object *obj;
133 const char *part;
134 const char *cursor;
135 const char *style;
136
137 Eina_Bool engine_only : 1;
138 };
139
140 #define MY_CLASS_NAME_LEGACY "elm_layout"
141
142 static void
_efl_ui_layout_base_class_constructor(Efl_Class * klass)143 _efl_ui_layout_base_class_constructor(Efl_Class *klass)
144 {
145 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
146 }
147
148 static void
_on_sub_object_size_hint_change(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)149 _on_sub_object_size_hint_change(void *data,
150 Evas *e EINA_UNUSED,
151 Evas_Object *obj EINA_UNUSED,
152 void *event_info EINA_UNUSED)
153 {
154 if (!efl_alive_get(data)) return;
155 ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
156 efl_canvas_group_change(data);
157 }
158
159 static void
_part_cursor_free(Efl_Ui_Layout_Sub_Object_Cursor * pc)160 _part_cursor_free(Efl_Ui_Layout_Sub_Object_Cursor *pc)
161 {
162 eina_stringshare_del(pc->part);
163 eina_stringshare_del(pc->style);
164 eina_stringshare_del(pc->cursor);
165
166 free(pc);
167 }
168
169 static void
_sizing_eval(Evas_Object * obj,Efl_Ui_Layout_Data * sd,Elm_Layout_Data * ld)170 _sizing_eval(Evas_Object *obj, Efl_Ui_Layout_Data *sd, Elm_Layout_Data *ld)
171 {
172 int minh = 0, minw = 0;
173 int rest_w = 0, rest_h = 0;
174 Eina_Size2D sz;
175 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
176
177 if (!efl_alive_get(obj)) return;
178 if (ld) ld->in_calc = EINA_TRUE;
179
180 if (sd->calc_subobjs && !evas_smart_objects_calculating_get(evas_object_evas_get(obj)))
181 {
182 Eo *subobj;
183 /* user has manually triggered a smart calc and wants subobjs to also calc */
184 for (unsigned int i = 0; i < eina_array_count(wd->children); ++i)
185 {
186 subobj = eina_array_data_get(wd->children, i);
187 efl_canvas_group_calculate(subobj);
188 }
189 }
190 elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, &rest_w,
191 sd->finger_size_multiplier_y, &rest_h);
192 if (ld && ld->user_min_sz)
193 sz = efl_gfx_hint_size_combined_min_get(obj);
194 else
195 sz = efl_gfx_hint_size_min_get(obj);
196 minw = sz.w;
197 minh = sz.h;
198
199 rest_w = MAX(minw, rest_w);
200 rest_h = MAX(minh, rest_h);
201
202 if (ld)
203 {
204 Eina_Size2D size = efl_gfx_entity_size_get(sd->obj);
205 if (ld->restricted_calc_w)
206 rest_w = MIN(size.w, rest_w);
207 if (ld->restricted_calc_h)
208 rest_h = MIN(size.h, rest_h);
209 }
210
211 edje_object_size_min_restricted_calc(wd->resize_obj, &minw, &minh,
212 rest_w, rest_h);
213 /* if desired, scale layout by finger size */
214 if (sd->finger_size_multiplier_x)
215 elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, &minw,
216 sd->finger_size_multiplier_y, NULL);
217 if (sd->finger_size_multiplier_y)
218 elm_coords_finger_size_adjust(sd->finger_size_multiplier_x, NULL,
219 sd->finger_size_multiplier_y, &minh);
220
221 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(minw, minh));
222
223 if (ld)
224 ld->in_calc = ld->restricted_calc_w = ld->restricted_calc_h = EINA_FALSE;
225 }
226
227 void
_efl_ui_layout_subobjs_calc_set(Eo * obj,Eina_Bool set)228 _efl_ui_layout_subobjs_calc_set(Eo *obj, Eina_Bool set)
229 {
230 Efl_Ui_Layout_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
231 EINA_SAFETY_ON_NULL_RETURN(sd);
232 sd->calc_subobjs = !!set;
233 }
234
235 static void
_defer_version_signal(Efl_Ui_Layout_Data * sd,Eina_Stringshare * old_sig,Eina_Stringshare * new_sig,unsigned int version_threshold)236 _defer_version_signal(Efl_Ui_Layout_Data *sd, Eina_Stringshare *old_sig, Eina_Stringshare *new_sig, unsigned int version_threshold)
237 {
238 Deferred_Version_Signal dvs;
239 if (!sd->deferred_signals)
240 sd->deferred_signals = eina_inarray_new(sizeof(Deferred_Version_Signal), 5);
241 EINA_SAFETY_ON_NULL_RETURN(sd->deferred_signals);
242 dvs.old_sig = old_sig;
243 dvs.new_sig = new_sig;
244 dvs.version_threshold = version_threshold;
245 eina_inarray_push(sd->deferred_signals, &dvs);
246 }
247
248 /* common content cases for layout objects: icon and text */
249 static inline void
_signals_emit(Efl_Ui_Layout_Data * sd,const char * type,Eina_Bool set)250 _signals_emit(Efl_Ui_Layout_Data *sd,
251 const char *type,
252 Eina_Bool set)
253 {
254 char buf[1024];
255
256 if (elm_widget_is_legacy(sd->obj))
257 {
258 snprintf(buf, sizeof(buf), "elm,state,%s,%s", type,
259 set ? "visible" : "hidden");
260 efl_layout_signal_emit(sd->obj, buf, "elm");
261 }
262 else
263 {
264 char buf2[1024];
265 char *use = buf;
266 if (sd->version >= 123) // efl,state,(content|text),(set|unset) -> efl,(content|text),(set|unset)
267 use = buf2;
268 snprintf(buf, sizeof(buf), "efl,state,%s,%s", type, set ? "set" : "unset");
269 snprintf(buf2, sizeof(buf2), "efl,%s,%s", type, set ? "set" : "unset");
270 if (efl_isa(sd->obj, EFL_UI_LAYOUT_CLASS) || efl_finalized_get(sd->obj))
271 efl_layout_signal_emit(sd->obj, use, "efl");
272 else
273 _defer_version_signal(sd, eina_stringshare_add(buf), eina_stringshare_add(buf2), 123);
274 }
275 }
276
277 static inline void
_icon_signal_emit(Efl_Ui_Layout_Data * sd,Efl_Ui_Layout_Sub_Object_Data * sub_d,Eina_Bool visible)278 _icon_signal_emit(Efl_Ui_Layout_Data *sd,
279 Efl_Ui_Layout_Sub_Object_Data *sub_d,
280 Eina_Bool visible)
281 {
282 const char *type;
283 Eo *edje;
284 int i;
285
286 edje = elm_widget_resize_object_get(sd->obj);
287 if (!edje) return;
288
289 //FIXME: Don't limit to the icon and end here.
290 // send signals for all contents after elm 2.0
291 if (sub_d->type != SWALLOW) return;
292 if (elm_widget_is_legacy(sd->obj))
293 {
294 for (i = 0;; i++)
295 {
296 if (!_elm_legacy_layout_swallow_parts[i]) return;
297 if (!strcmp(sub_d->part, _elm_legacy_layout_swallow_parts[i])) break;
298 }
299 }
300 else
301 {
302 for (i = 0;; i++)
303 {
304 if (!_efl_ui_layout_swallow_parts[i]) return;
305 if (!strcmp(sub_d->part, _efl_ui_layout_swallow_parts[i])) break;
306 }
307 }
308
309 if (elm_widget_is_legacy(sd->obj))
310 {
311 if (!strncmp(sub_d->part, "elm.swallow.", strlen("elm.swallow.")))
312 type = sub_d->part + strlen("elm.swallow.");
313 else
314 type = sub_d->part;
315 }
316 else
317 {
318 if (!strncmp(sub_d->part, "efl.", strlen("efl.")))
319 type = sub_d->part + strlen("efl.");
320 else
321 type = sub_d->part;
322 }
323
324 _signals_emit(sd, type, visible);
325
326 /* themes might need immediate action here */
327 efl_layout_signal_process(sd->obj, EINA_FALSE);
328 }
329
330 static inline void
_text_signal_emit(Efl_Ui_Layout_Data * sd,Efl_Ui_Layout_Sub_Object_Data * sub_d,Eina_Bool visible)331 _text_signal_emit(Efl_Ui_Layout_Data *sd,
332 Efl_Ui_Layout_Sub_Object_Data *sub_d,
333 Eina_Bool visible)
334 {
335 char buf[1024];
336 const char *type;
337
338 //FIXME: Don't limit to "elm.text" prefix.
339 //Send signals for all text parts after elm 2.0
340 if (sub_d->type != TEXT) return;
341
342 if (elm_widget_is_legacy(sd->obj))
343 {
344 if (!((!strcmp("elm.text", sub_d->part)) ||
345 (!strncmp("elm.text.", sub_d->part, 9))))
346 return;
347 }
348 else
349 {
350 if (!((!strcmp("efl.text", sub_d->part)) ||
351 (!strncmp("efl.text.", sub_d->part, 9))))
352 return;
353 }
354
355 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
356
357 if (elm_widget_is_legacy(sd->obj))
358 {
359 if (!strncmp(sub_d->part, "elm.text.", strlen("elm.text.")))
360 type = sub_d->part + strlen("elm.text.");
361 else
362 type = sub_d->part;
363 }
364 else
365 {
366 if (!strncmp(sub_d->part, "efl.", strlen("efl.")))
367 type = sub_d->part + strlen("efl.");
368 else
369 type = sub_d->part;
370 }
371
372 _signals_emit(sd, type, visible);
373
374 /* TODO: is this right? It was like that, but IMO it should be removed: */
375
376 if (elm_widget_is_legacy(sd->obj))
377 {
378 snprintf(buf, sizeof(buf),
379 visible ? "elm,state,text,visible" : "elm,state,text,hidden");
380 efl_layout_signal_emit(sd->obj, buf, "elm");
381 }
382
383 /* themes might need immediate action here */
384 efl_layout_signal_process(sd->obj, EINA_FALSE);
385 }
386
387 static void
_parts_signals_emit(Efl_Ui_Layout_Data * sd)388 _parts_signals_emit(Efl_Ui_Layout_Data *sd)
389 {
390 const Eina_List *l;
391 Efl_Ui_Layout_Sub_Object_Data *sub_d;
392
393 EINA_LIST_FOREACH(sd->subs, l, sub_d)
394 {
395 _icon_signal_emit(sd, sub_d, EINA_TRUE);
396 _text_signal_emit(sd, sub_d, EINA_TRUE);
397 }
398 }
399
400 static void
_part_cursor_part_apply(const Efl_Ui_Layout_Sub_Object_Cursor * pc)401 _part_cursor_part_apply(const Efl_Ui_Layout_Sub_Object_Cursor *pc)
402 {
403 elm_object_cursor_set(pc->obj, pc->cursor);
404 elm_object_cursor_style_set(pc->obj, pc->style);
405 elm_object_cursor_theme_search_enabled_set(pc->obj, !pc->engine_only);
406 }
407
408 static void
_parts_cursors_apply(Efl_Ui_Layout_Data * sd)409 _parts_cursors_apply(Efl_Ui_Layout_Data *sd)
410 {
411 const Eina_List *l;
412 const char *file, *group;
413 Efl_Ui_Layout_Sub_Object_Cursor *pc;
414 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd);
415
416 edje_object_file_get(wd->resize_obj, &file, &group);
417
418 EINA_LIST_FOREACH(sd->parts_cursors, l, pc)
419 {
420 Evas_Object *obj;
421
422 edje_object_freeze(wd->resize_obj);
423 obj = (Evas_Object *)edje_object_part_object_get
424 (wd->resize_obj, pc->part);
425 edje_object_thaw(wd->resize_obj);
426
427 if (!obj)
428 {
429 pc->obj = NULL;
430 WRN("no part '%s' in group '%s' of file '%s'. "
431 "Cannot set cursor '%s'",
432 pc->part, group, file, pc->cursor);
433 continue;
434 }
435 else if (evas_object_pass_events_get(obj))
436 {
437 pc->obj = NULL;
438 WRN("part '%s' in group '%s' of file '%s' has mouse_events: 0. "
439 "Cannot set cursor '%s'",
440 pc->part, group, file, pc->cursor);
441 continue;
442 }
443
444 pc->obj = obj;
445 _part_cursor_part_apply(pc);
446 }
447 }
448
449 static void
_efl_ui_layout_highlight_in_theme(Evas_Object * obj)450 _efl_ui_layout_highlight_in_theme(Evas_Object *obj)
451 {
452 const char *fh;
453
454 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
455
456 fh = edje_object_data_get
457 (wd->resize_obj, "focus_highlight");
458 if ((fh) && (!strcmp(fh, "on")))
459 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
460 else
461 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
462
463 fh = edje_object_data_get
464 (wd->resize_obj, "access_highlight");
465 if ((fh) && (!strcmp(fh, "on")))
466 elm_widget_access_highlight_in_theme_set(obj, EINA_TRUE);
467 else
468 elm_widget_access_highlight_in_theme_set(obj, EINA_FALSE);
469 }
470
471 static void
_flush_mirrored_state(Eo * obj)472 _flush_mirrored_state(Eo *obj)
473 {
474 char prefix[4], state[10], signal[100];
475 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
476
477 if (!wd->resize_obj) return;
478
479 if (efl_ui_widget_disabled_get(obj))
480 snprintf(state, sizeof(state), "disabled");
481 else
482 snprintf(state, sizeof(state), "enabled");
483
484 if (!elm_widget_is_legacy(obj))
485 snprintf(prefix, sizeof(prefix), "efl");
486 else
487 snprintf(prefix, sizeof(prefix), "elm");
488
489 snprintf(signal, sizeof(signal), "%s,state,%s", prefix, state);
490 efl_layout_signal_emit(obj, signal, prefix);
491 }
492
493 static Eina_Bool
_visuals_refresh(Evas_Object * obj,Efl_Ui_Layout_Data * sd)494 _visuals_refresh(Evas_Object *obj,
495 Efl_Ui_Layout_Data *sd)
496 {
497 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
498
499 _parts_signals_emit(sd);
500 _parts_cursors_apply(sd);
501
502 edje_object_mirrored_set
503 (wd->resize_obj, efl_ui_mirrored_get(obj));
504
505 edje_object_scale_set
506 (wd->resize_obj,
507 efl_gfx_entity_scale_get(obj) * elm_config_scale_get());
508
509 _efl_ui_layout_highlight_in_theme(obj);
510 _flush_mirrored_state(obj);
511
512 efl_canvas_group_change(obj);
513
514 return EINA_TRUE;
515 }
516
517 EOLIAN static void
_efl_ui_layout_base_efl_ui_widget_disabled_set(Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,Eina_Bool disabled)518 _efl_ui_layout_base_efl_ui_widget_disabled_set(Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, Eina_Bool disabled)
519 {
520 efl_ui_widget_disabled_set(efl_super(obj, MY_CLASS), disabled);
521 _flush_mirrored_state(obj);
522 }
523
524 static Eina_Error
_efl_ui_layout_theme_internal(Eo * obj,Efl_Ui_Layout_Data * sd,Elm_Widget_Smart_Data ** widget_data)525 _efl_ui_layout_theme_internal(Eo *obj, Efl_Ui_Layout_Data *sd, Elm_Widget_Smart_Data **widget_data)
526 {
527 Eina_Error ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
528
529 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_UI_THEME_APPLY_ERROR_GENERIC);
530
531 *widget_data = wd;
532 /* function already prints error messages, if any */
533 if (!sd->file_set)
534 {
535 ret = elm_widget_theme_object_set
536 (obj, wd->resize_obj,
537 elm_widget_theme_klass_get(obj),
538 elm_widget_theme_element_get(obj),
539 elm_widget_theme_style_get(obj));
540 }
541
542 if (ret != EFL_UI_THEME_APPLY_ERROR_GENERIC)
543 {
544 if (sd->cb_theme_changed)
545 efl_event_callback_call(obj, EFL_UI_LAYOUT_EVENT_THEME_CHANGED, NULL);
546 if (elm_widget_is_legacy(obj))
547 evas_object_smart_callback_call(obj, "theme,changed", NULL);
548 }
549
550 if (!_visuals_refresh(obj, sd))
551 ret = EFL_UI_THEME_APPLY_ERROR_GENERIC;
552
553 return ret;
554 }
555
556 static void
_deferred_signals_emit(Efl_Ui_Layout_Data * pd)557 _deferred_signals_emit(Efl_Ui_Layout_Data *pd)
558 {
559 do
560 {
561 Deferred_Version_Signal *dvs = eina_inarray_pop(pd->deferred_signals);
562
563 if (pd->version < dvs->version_threshold)
564 efl_layout_signal_emit(pd->obj, dvs->old_sig, "efl");
565 else
566 efl_layout_signal_emit(pd->obj, dvs->new_sig, "efl");
567 eina_stringshare_del(dvs->old_sig);
568 eina_stringshare_del(dvs->new_sig);
569 } while (eina_inarray_count(pd->deferred_signals));
570 ELM_SAFE_FREE(pd->deferred_signals, eina_inarray_free);
571 }
572
573 EOLIAN static Eina_Error
_efl_ui_layout_base_efl_ui_widget_theme_apply(Eo * obj,Efl_Ui_Layout_Data * sd)574 _efl_ui_layout_base_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Layout_Data *sd)
575 {
576 Eina_Error theme_apply_ret, theme_apply_internal_ret;
577 Elm_Widget_Smart_Data *wd = NULL;
578 char buf[64];
579 Eina_Bool legacy;
580 static unsigned int version = 0;
581
582 sd->needs_theme_apply = EINA_FALSE;
583
584 theme_apply_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
585 if (theme_apply_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
586
587 theme_apply_internal_ret = _efl_ui_layout_theme_internal(obj, sd, &wd);
588 if (theme_apply_internal_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC)
589 return EFL_UI_THEME_APPLY_ERROR_GENERIC;
590
591 if ((theme_apply_ret == EFL_UI_THEME_APPLY_ERROR_DEFAULT) ||
592 (theme_apply_internal_ret == EFL_UI_THEME_APPLY_ERROR_DEFAULT))
593 return EFL_UI_THEME_APPLY_ERROR_DEFAULT;
594
595 legacy = elm_widget_is_legacy(obj);
596 /* unset existing size hints to force accurate recalc */
597 efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(0, 0));
598 if (legacy)
599 efl_gfx_hint_size_min_set(obj, EINA_SIZE2D(0, 0));
600 else
601 {
602 const char *theme_version = edje_object_data_get(wd->resize_obj, "version");
603 if (!theme_version)
604 {
605 ERR("Widget(%p) with type '%s' is not providing a version in its theme!", obj,
606 efl_class_name_get(efl_class_get(obj)));
607 ERR("Group '%s' should have data.item: \"version\" \"%d%d\";",
608 efl_file_key_get(wd->resize_obj), EFL_VERSION_MAJOR, EFL_VERSION_MINOR);
609 return EFL_UI_THEME_APPLY_ERROR_VERSION;
610 }
611 else
612 {
613 errno = 0;
614 sd->version = strtoul(theme_version, NULL, 10);
615 if (errno)
616 {
617 ERR("Widget(%p) with type '%s' is not providing a valid version in its theme!", obj,
618 efl_class_name_get(efl_class_get(obj)));
619 ERR("Group '%s' should have data.item: \"version\" \"%d%d\";",
620 efl_file_key_get(wd->resize_obj), EFL_VERSION_MAJOR, EFL_VERSION_MINOR);
621 sd->version = 0;
622 return EFL_UI_THEME_APPLY_ERROR_VERSION;
623 }
624 }
625 }
626 if (sd->deferred_signals)
627 _deferred_signals_emit(sd);
628 if (legacy) return EFL_UI_THEME_APPLY_ERROR_NONE;
629
630 if (!version)
631 {
632 snprintf(buf, sizeof(buf), "%d%d", EFL_VERSION_MAJOR, EFL_VERSION_MINOR + (EFL_VERSION_MICRO == 99 ? 1 : 0));
633 errno = 0;
634 version = strtoul(buf, NULL, 10);
635 if (errno)
636 {
637 ERR("something broke in theme parsing, this system is probably busted");
638 version = 0;
639 }
640 }
641 if (version && (!_running_in_tree))
642 {
643 if (sd->version < version)
644 WRN("Widget(%p) with type '%s' is providing a potentially old version in its theme: found %u, should be %u", obj,
645 efl_class_name_get(efl_class_get(obj)), sd->version, version);
646 else if (sd->version > version)
647 {
648 CRI("Widget(%p) with type '%s' is attempting to use a theme that is too new: found %u, should be %u", obj,
649 efl_class_name_get(efl_class_get(obj)), sd->version, version);
650 CRI("\tTheme file: %s\tTheme group: %s", efl_file_get(obj), efl_file_key_get(obj));
651 return EFL_UI_THEME_APPLY_ERROR_VERSION;
652 }
653 }
654
655 return EFL_UI_THEME_APPLY_ERROR_NONE;
656 }
657
658 EOLIAN static int
_efl_ui_layout_base_theme_version_get(const Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * pd)659 _efl_ui_layout_base_theme_version_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd)
660 {
661 return pd->version;
662 }
663
664 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_ui_focus_object_on_focus_update(Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED)665 _efl_ui_layout_base_efl_ui_focus_object_on_focus_update(Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED)
666 {
667 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
668
669 if (!elm_widget_can_focus_get(obj)) return EINA_FALSE;
670
671 if (efl_ui_focus_object_focus_get(obj))
672 {
673 if (elm_widget_is_legacy(obj))
674 elm_layout_signal_emit(obj, "elm,action,focus", "elm");
675 else
676 elm_layout_signal_emit(obj, "efl,action,focus", "efl");
677 evas_object_focus_set(wd->resize_obj, EINA_TRUE);
678 }
679 else
680 {
681 if (elm_widget_is_legacy(obj))
682 elm_layout_signal_emit(obj, "elm,action,unfocus", "elm");
683 else
684 elm_layout_signal_emit(obj, "efl,action,unfocus", "efl");
685 evas_object_focus_set(wd->resize_obj, EINA_FALSE);
686 }
687
688 efl_ui_focus_object_on_focus_update(efl_super(obj, MY_CLASS));
689
690 if (efl_isa(wd->resize_obj, EFL_CANVAS_LAYOUT_CLASS))
691 edje_object_message_signal_process(wd->resize_obj);
692
693 return EINA_TRUE;
694 }
695
696 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_ui_widget_widget_sub_object_add(Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,Evas_Object * sobj)697 _efl_ui_layout_base_efl_ui_widget_widget_sub_object_add(Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, Evas_Object *sobj)
698 {
699 Eina_Bool int_ret = EINA_FALSE;
700
701 if (evas_object_data_get(sobj, "elm-parent") == obj) return EINA_TRUE;
702
703 int_ret = elm_widget_sub_object_add(efl_super(obj, MY_CLASS), sobj);
704 if (!int_ret) return EINA_FALSE;
705
706 evas_object_event_callback_add
707 (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
708 _on_sub_object_size_hint_change, obj);
709
710 return EINA_TRUE;
711 }
712
713 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_ui_widget_widget_sub_object_del(Eo * obj,Efl_Ui_Layout_Data * sd,Evas_Object * sobj)714 _efl_ui_layout_base_efl_ui_widget_widget_sub_object_del(Eo *obj, Efl_Ui_Layout_Data *sd, Evas_Object *sobj)
715 {
716 Eina_List *l;
717 Efl_Ui_Layout_Sub_Object_Data *sub_d;
718
719 Eina_Bool int_ret = EINA_FALSE;
720
721 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
722
723 evas_object_event_callback_del_full
724 (sobj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
725 _on_sub_object_size_hint_change, obj);
726
727 int_ret = elm_widget_sub_object_del(efl_super(obj, MY_CLASS), sobj);
728 if (!int_ret) return EINA_FALSE;
729 if (sd->destructed_is) return EINA_TRUE;
730
731 EINA_LIST_FOREACH(sd->subs, l, sub_d)
732 {
733 if (sub_d->obj != sobj) continue;
734
735 sd->subs = eina_list_remove_list(sd->subs, l);
736
737 _icon_signal_emit(sd, sub_d, EINA_FALSE);
738
739 eina_stringshare_del(sub_d->part);
740 free(sub_d);
741
742 break;
743 }
744
745 // No need to resize object during destruction
746 if (wd->resize_obj && efl_alive_get(obj))
747 efl_canvas_group_change(obj);
748
749 return EINA_TRUE;
750 }
751
752 static void
_edje_signal_callback(void * data,Evas_Object * obj EINA_UNUSED,const char * emission,const char * source)753 _edje_signal_callback(void *data,
754 Evas_Object *obj EINA_UNUSED,
755 const char *emission,
756 const char *source)
757 {
758 Edje_Signal_Data *esd = data;
759
760 esd->func(esd->data, esd->obj, emission, source);
761 }
762
763 EAPI Eina_Bool
_elm_layout_part_aliasing_eval(const Evas_Object * obj,const char ** part,Eina_Bool is_text)764 _elm_layout_part_aliasing_eval(const Evas_Object *obj,
765 const char **part,
766 Eina_Bool is_text)
767 {
768 const Elm_Layout_Part_Alias_Description *aliases = NULL;
769
770 if (!elm_widget_is_legacy(obj))
771 {
772 if (!*part)
773 {
774 if (is_text)
775 *part = efl_ui_default_text;
776 else
777 *part = efl_ui_default_content;
778 return EINA_TRUE;
779 }
780 }
781
782 if (is_text)
783 aliases = efl_ui_layout_text_aliases_get(obj);
784 else
785 aliases = efl_ui_layout_content_aliases_get(obj);
786
787 while (aliases && aliases->alias && aliases->real_part)
788 {
789 /* NULL matches the 1st */
790 if ((!*part) || (!strcmp(*part, aliases->alias)))
791 {
792 *part = aliases->real_part;
793 break;
794 }
795
796 aliases++;
797 }
798
799 if (!*part)
800 {
801 ERR("no default content part set for object %p -- "
802 "part must not be NULL", obj);
803 return EINA_FALSE;
804 }
805
806 /* if no match, part goes on with the same value */
807
808 return EINA_TRUE;
809 }
810
811 static void
_eo_unparent_helper(Eo * child,Eo * parent)812 _eo_unparent_helper(Eo *child, Eo *parent)
813 {
814 if (efl_parent_get(child) == parent)
815 {
816 efl_parent_set(child, evas_object_evas_get(parent));
817 }
818 }
819
820 static void
_box_reference_del(void * data,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)821 _box_reference_del(void *data,
822 Evas *e EINA_UNUSED,
823 Evas_Object *obj EINA_UNUSED,
824 void *event_info EINA_UNUSED)
825 {
826 Efl_Ui_Layout_Sub_Object_Data *sub_d = data;
827 sub_d->p.box.reference = NULL;
828 }
829
830 static Evas_Object *
_sub_box_remove(Evas_Object * obj,Efl_Ui_Layout_Data * sd,Efl_Ui_Layout_Sub_Object_Data * sub_d)831 _sub_box_remove(Evas_Object *obj,
832 Efl_Ui_Layout_Data *sd,
833 Efl_Ui_Layout_Sub_Object_Data *sub_d)
834 {
835 Evas_Object *child = sub_d->obj; /* sub_d will die in
836 * _efl_ui_layout_smart_widget_sub_object_del */
837
838 if (sub_d->type == BOX_INSERT_BEFORE)
839 evas_object_event_callback_del_full
840 ((Evas_Object *)sub_d->p.box.reference,
841 EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
842
843 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd, NULL);
844 edje_object_part_box_remove
845 (wd->resize_obj, sub_d->part, child);
846
847 _eo_unparent_helper(child, obj);
848 if (!_elm_widget_sub_object_redirect_to_top(obj, child))
849 {
850 ERR("could not remove sub object %p from %p", child, obj);
851 return NULL;
852 }
853
854 return child;
855 }
856
857 static Eina_Bool
_sub_box_is(const Efl_Ui_Layout_Sub_Object_Data * sub_d)858 _sub_box_is(const Efl_Ui_Layout_Sub_Object_Data *sub_d)
859 {
860 switch (sub_d->type)
861 {
862 case BOX_APPEND:
863 case BOX_PREPEND:
864 case BOX_INSERT_BEFORE:
865 case BOX_INSERT_AT:
866 return EINA_TRUE;
867
868 default:
869 return EINA_FALSE;
870 }
871 }
872
873 static Evas_Object *
_sub_table_remove(Evas_Object * obj,Efl_Ui_Layout_Data * sd,Efl_Ui_Layout_Sub_Object_Data * sub_d)874 _sub_table_remove(Evas_Object *obj,
875 Efl_Ui_Layout_Data *sd,
876 Efl_Ui_Layout_Sub_Object_Data *sub_d)
877 {
878 Evas_Object *child;
879 ELM_WIDGET_DATA_GET_OR_RETURN(sd->obj, wd, NULL);
880
881 child = sub_d->obj; /* sub_d will die in _efl_ui_layout_smart_widget_sub_object_del */
882
883 edje_object_part_table_unpack
884 (wd->resize_obj, sub_d->part, child);
885
886 _eo_unparent_helper(child, obj);
887
888 if (!_elm_widget_sub_object_redirect_to_top(obj, child))
889 {
890 ERR("could not remove sub object %p from %p", child, obj);
891 return NULL;
892 }
893
894 return child;
895 }
896
897 static void
_on_size_evaluate_signal(void * data,Evas_Object * obj EINA_UNUSED,const char * emission EINA_UNUSED,const char * source EINA_UNUSED)898 _on_size_evaluate_signal(void *data,
899 Evas_Object *obj EINA_UNUSED,
900 const char *emission EINA_UNUSED,
901 const char *source EINA_UNUSED)
902 {
903 efl_canvas_group_change(data);
904 efl_canvas_group_calculate(data);
905 }
906
907 EOLIAN static void
_efl_ui_layout_base_efl_canvas_group_group_add(Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED)908 _efl_ui_layout_base_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED)
909 {
910 Evas_Object *edje;
911
912 /* has to be there *before* parent's smart_add() */
913 edje = edje_object_add(evas_object_evas_get(obj));
914 elm_widget_resize_object_set(obj, edje);
915
916 efl_canvas_group_add(efl_super(obj, MY_CLASS));
917
918 elm_widget_can_focus_set(obj, EINA_FALSE);
919
920 if (elm_widget_is_legacy(obj))
921 edje_object_signal_callback_add
922 (edje, "size,eval", "elm", _on_size_evaluate_signal, obj);
923 else
924 edje_object_signal_callback_add
925 (edje, "size,eval", "efl", _on_size_evaluate_signal, obj);
926 }
927
928 EOLIAN static void
_efl_ui_layout_base_efl_canvas_group_group_del(Eo * obj,Efl_Ui_Layout_Data * sd)929 _efl_ui_layout_base_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Layout_Data *sd)
930 {
931 Efl_Ui_Layout_Sub_Object_Data *sub_d;
932 Efl_Ui_Layout_Sub_Object_Cursor *pc;
933 Edje_Signal_Data *esd;
934 Efl_Model *model;
935
936 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
937
938 /* freeze edje object if it exists */
939 if (wd->resize_obj)
940 elm_layout_freeze(obj);
941
942 EINA_LIST_FREE(sd->subs, sub_d)
943 {
944 eina_stringshare_del(sub_d->part);
945 free(sub_d);
946 }
947
948 EINA_LIST_FREE(sd->parts_cursors, pc)
949 _part_cursor_free(pc);
950
951 EINA_LIST_FREE(sd->edje_signals, esd)
952 {
953 edje_object_signal_callback_del_full
954 (wd->resize_obj, esd->emission, esd->source,
955 _edje_signal_callback, esd);
956 eina_stringshare_del(esd->emission);
957 eina_stringshare_del(esd->source);
958 free(esd);
959 }
960
961 model = efl_ui_view_model_get(obj);
962 if(model)
963 {
964 efl_event_callback_del(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
965 _efl_model_properties_changed_cb, sd);
966 }
967
968 eina_hash_free(sd->connect.properties);
969 sd->connect.properties = NULL;
970 eina_hash_free(sd->connect.signals);
971 sd->connect.signals = NULL;
972 eina_hash_free(sd->connect.factories);
973 sd->connect.factories = NULL;
974 if (sd->deferred_signals)
975 {
976 do
977 {
978 Deferred_Version_Signal *dvs = eina_inarray_pop(sd->deferred_signals);
979
980 eina_stringshare_del(dvs->old_sig);
981 eina_stringshare_del(dvs->new_sig);
982 } while (eina_inarray_count(sd->deferred_signals));
983 ELM_SAFE_FREE(sd->deferred_signals, eina_inarray_free);
984 }
985
986 /* let's make our Edje object the *last* to be processed, since it
987 * may (smart) parent other sub objects here */
988 {
989 unsigned int resize_id = 0;
990 if (eina_array_find(wd->children, wd->resize_obj, &resize_id))
991 {
992 //exchange with last
993 eina_array_data_set(wd->children, resize_id, eina_array_data_get(wd->children, eina_array_count(wd->children) - 1));
994 eina_array_data_set(wd->children, eina_array_count(wd->children) - 1, wd->resize_obj);
995 }
996 }
997
998 sd->destructed_is = EINA_TRUE;
999
1000 efl_canvas_group_del(efl_super(obj, MY_CLASS));
1001 }
1002
1003 /* rewrite or extend this one on your derived class as to suit your
1004 * needs */
1005 EOLIAN static void
_efl_ui_layout_base_efl_canvas_group_group_calculate(Eo * obj,Efl_Ui_Layout_Data * sd)1006 _efl_ui_layout_base_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Layout_Data *sd)
1007 {
1008 Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
1009 efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
1010 if ((!ld) || ld->needs_size_calc)
1011 _sizing_eval(obj, sd, ld);
1012 if (ld) ld->needs_size_calc = EINA_FALSE;
1013 }
1014
1015 EOLIAN static void
_efl_ui_layout_base_finger_size_multiplier_get(const Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd,unsigned int * mult_x,unsigned int * mult_y)1016 _efl_ui_layout_base_finger_size_multiplier_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd, unsigned int *mult_x, unsigned int *mult_y)
1017 {
1018 if (mult_x)
1019 *mult_x = sd->finger_size_multiplier_x;
1020 if (mult_y)
1021 *mult_y = sd->finger_size_multiplier_y;
1022 }
1023
1024 EOLIAN static void
_efl_ui_layout_base_finger_size_multiplier_set(Eo * obj,Efl_Ui_Layout_Data * sd,unsigned int mult_x,unsigned int mult_y)1025 _efl_ui_layout_base_finger_size_multiplier_set(Eo *obj, Efl_Ui_Layout_Data *sd, unsigned int mult_x, unsigned int mult_y)
1026 {
1027 if ((sd->finger_size_multiplier_x == mult_x) &&
1028 (sd->finger_size_multiplier_y == mult_y))
1029 return;
1030 sd->finger_size_multiplier_x = mult_x;
1031 sd->finger_size_multiplier_y = mult_y;
1032 if (efl_alive_get(obj))
1033 efl_canvas_group_change(obj);
1034 }
1035
1036 static Efl_Ui_Layout_Sub_Object_Cursor *
_parts_cursors_find(Efl_Ui_Layout_Data * sd,const char * part)1037 _parts_cursors_find(Efl_Ui_Layout_Data *sd,
1038 const char *part)
1039 {
1040 const Eina_List *l;
1041 Efl_Ui_Layout_Sub_Object_Cursor *pc;
1042
1043 EINA_LIST_FOREACH(sd->parts_cursors, l, pc)
1044 {
1045 if (!strcmp(pc->part, part))
1046 return pc;
1047 }
1048
1049 return NULL;
1050 }
1051
1052 /* The public functions down here are meant to operate on whichever
1053 * widget inheriting from elm_layout */
1054
1055 EOLIAN static void
_efl_ui_layout_efl_file_unload(Eo * obj,void * _pd EINA_UNUSED)1056 _efl_ui_layout_efl_file_unload(Eo *obj, void *_pd EINA_UNUSED)
1057 {
1058 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
1059
1060 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1061
1062 efl_file_unload(wd->resize_obj);
1063 sd->file_set = EINA_FALSE;
1064 }
1065
1066 EOLIAN static Eina_Error
_efl_ui_layout_efl_file_load(Eo * obj,void * _pd EINA_UNUSED)1067 _efl_ui_layout_efl_file_load(Eo *obj, void *_pd EINA_UNUSED)
1068 {
1069 Eina_Error err;
1070 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
1071
1072 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1073
1074 if (efl_file_loaded_get(obj)) return 0;
1075 err = efl_file_load(wd->resize_obj);
1076
1077 if (!err)
1078 {
1079 sd->file_set = EINA_TRUE;
1080 _visuals_refresh(obj, sd);
1081 }
1082 else
1083 ERR("failed to set edje file '%s', group '%s': %s",
1084 efl_file_get(wd->resize_obj), efl_file_key_get(wd->resize_obj),
1085 edje_load_error_str
1086 (edje_object_load_error_get(wd->resize_obj)));
1087
1088 return err;
1089 }
1090
1091 EOLIAN static Eina_Error
_efl_ui_layout_efl_file_file_set(Eo * obj,void * _pd EINA_UNUSED,const char * file)1092 _efl_ui_layout_efl_file_file_set(Eo *obj, void *_pd EINA_UNUSED, const char *file)
1093 {
1094 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_GFX_IMAGE_LOAD_ERROR_GENERIC);
1095 return efl_file_set(wd->resize_obj, file);
1096 }
1097
1098 EOLIAN static const char *
_efl_ui_layout_efl_file_file_get(const Eo * obj,void * _pd EINA_UNUSED)1099 _efl_ui_layout_efl_file_file_get(const Eo *obj, void *_pd EINA_UNUSED)
1100 {
1101 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1102 return efl_file_get(wd->resize_obj);
1103 }
1104
1105 EOLIAN static void
_efl_ui_layout_efl_file_key_set(Eo * obj,void * _pd EINA_UNUSED,const char * key)1106 _efl_ui_layout_efl_file_key_set(Eo *obj, void *_pd EINA_UNUSED, const char *key)
1107 {
1108 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1109 return efl_file_key_set(wd->resize_obj, key);
1110 }
1111
1112 EOLIAN static const char *
_efl_ui_layout_efl_file_key_get(const Eo * obj,void * _pd EINA_UNUSED)1113 _efl_ui_layout_efl_file_key_get(const Eo *obj, void *_pd EINA_UNUSED)
1114 {
1115 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1116 return efl_file_key_get(wd->resize_obj);
1117 }
1118
1119 EOLIAN static Eina_Error
_efl_ui_layout_efl_file_mmap_set(Eo * obj,void * _pd EINA_UNUSED,const Eina_File * file)1120 _efl_ui_layout_efl_file_mmap_set(Eo *obj, void *_pd EINA_UNUSED, const Eina_File *file)
1121 {
1122 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1123 return efl_file_mmap_set(wd->resize_obj, file);
1124 }
1125
1126 EOLIAN static const Eina_File *
_efl_ui_layout_efl_file_mmap_get(const Eo * obj,void * _pd EINA_UNUSED)1127 _efl_ui_layout_efl_file_mmap_get(const Eo *obj, void *_pd EINA_UNUSED)
1128 {
1129 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1130 return efl_file_mmap_get(wd->resize_obj);
1131 }
1132
1133 EOLIAN static void
_efl_ui_layout_base_theme_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char ** klass,const char ** group,const char ** style)1134 _efl_ui_layout_base_theme_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char **klass, const char **group, const char **style)
1135 {
1136 if (klass) *klass = elm_widget_theme_klass_get(obj);
1137 if (group) *group = elm_widget_theme_element_get(obj);
1138 if (style) *style = elm_widget_theme_style_get(obj);
1139 }
1140
1141 EOLIAN static Eina_Error
_efl_ui_layout_base_theme_set(Eo * obj,Efl_Ui_Layout_Data * sd,const char * klass,const char * group,const char * style)1142 _efl_ui_layout_base_theme_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *klass, const char *group, const char *style)
1143 {
1144 Eina_Bool changed = EINA_FALSE;
1145
1146 if (!elm_widget_is_legacy(obj) && efl_finalized_get(obj))
1147 {
1148 ERR("Efl.Ui.Layout_theme can only be set before finalize!");
1149 return EFL_UI_THEME_APPLY_ERROR_GENERIC;
1150 }
1151
1152 if (sd->file_set) sd->file_set = EINA_FALSE;
1153
1154 changed |= elm_widget_theme_klass_set(obj, klass);
1155 changed |= elm_widget_theme_element_set(obj, group);
1156 changed |= elm_widget_theme_style_set(obj, style);
1157
1158 if (changed)
1159 return efl_ui_widget_theme_apply(obj);
1160 return EFL_UI_THEME_APPLY_ERROR_NONE;
1161 }
1162
1163 EOLIAN static void
_efl_ui_layout_base_efl_layout_signal_signal_emit(Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,const char * emission,const char * source)1164 _efl_ui_layout_base_efl_layout_signal_signal_emit(Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, const char *emission, const char *source)
1165 {
1166 // Don't do anything else than call forward here
1167 EINA_SAFETY_ON_TRUE_RETURN(efl_invalidated_get(obj));
1168 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
1169 efl_layout_signal_emit(wd->resize_obj, emission, source);
1170 }
1171
1172 static Eina_Bool
_efl_ui_layout_base_efl_layout_signal_signal_callback_add(Eo * obj,Efl_Ui_Layout_Data * pd EINA_UNUSED,const char * emission,const char * source,void * func_data,EflLayoutSignalCb func,Eina_Free_Cb func_free_cb)1173 _efl_ui_layout_base_efl_layout_signal_signal_callback_add(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, const char *emission, const char *source, void *func_data, EflLayoutSignalCb func, Eina_Free_Cb func_free_cb)
1174 {
1175 // Don't do anything else than call forward here
1176 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1177 return efl_layout_signal_callback_add(wd->resize_obj, emission, source, func_data, func, func_free_cb);
1178 }
1179
1180 static Eina_Bool
_efl_ui_layout_base_efl_layout_signal_signal_callback_del(Eo * obj,Efl_Ui_Layout_Data * pd EINA_UNUSED,const char * emission,const char * source,void * func_data,EflLayoutSignalCb func,Eina_Free_Cb func_free_cb)1181 _efl_ui_layout_base_efl_layout_signal_signal_callback_del(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, const char *emission, const char *source, void *func_data, EflLayoutSignalCb func, Eina_Free_Cb func_free_cb)
1182 {
1183 // Don't do anything else than call forward here
1184 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1185 return efl_layout_signal_callback_del(wd->resize_obj, emission, source, func_data, func, func_free_cb);
1186 }
1187
1188 // TODO:
1189 // - message_send
1190 // - message_signal_process
1191 // and also message handler (not implemented yet as an EO interface!)
1192
1193 EAPI Eina_Bool
elm_layout_content_set(Evas_Object * obj,const char * swallow,Evas_Object * content)1194 elm_layout_content_set(Evas_Object *obj, const char *swallow, Evas_Object *content)
1195 {
1196 EFL_UI_LAYOUT_CHECK(obj) EINA_FALSE;
1197 if (!swallow)
1198 {
1199 swallow = efl_ui_widget_default_content_part_get(obj);
1200 if (!swallow) return EINA_FALSE;
1201 }
1202 else if (!_elm_layout_part_aliasing_eval(obj, &swallow, EINA_FALSE))
1203 return EINA_FALSE;
1204
1205 return efl_content_set(efl_part(obj, swallow), content);
1206 }
1207
1208 static Eina_Bool
_efl_ui_layout_content_set(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * content)1209 _efl_ui_layout_content_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *content)
1210 {
1211 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1212 Eina_List *l;
1213
1214 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1215
1216 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1217 {
1218 if (sub_d->type == SWALLOW)
1219 {
1220 if (!strcmp(part, sub_d->part))
1221 {
1222 if (content == sub_d->obj) goto end;
1223 if (efl_alive_get(sub_d->obj))
1224 {
1225 _eo_unparent_helper(sub_d->obj, obj);
1226 evas_object_del(sub_d->obj);
1227 }
1228 break;
1229 }
1230 /* was previously swallowed at another part -- mimic
1231 * edje_object_part_swallow()'s behavior, then */
1232 else if (content == sub_d->obj)
1233 {
1234 sd->subs = eina_list_remove_list(sd->subs, l);
1235 _icon_signal_emit(sd, sub_d, EINA_FALSE);
1236 eina_stringshare_del(sub_d->part);
1237 free(sub_d);
1238
1239 _elm_widget_sub_object_redirect_to_top(obj, content);
1240 break;
1241 }
1242 }
1243 }
1244
1245 if (content)
1246 {
1247 if (!elm_widget_sub_object_add(obj, content))
1248 return EINA_FALSE;
1249
1250 if (!edje_object_part_swallow
1251 (wd->resize_obj, part, content))
1252 {
1253 ERR("could not swallow %p into part '%s'", content, part);
1254 _elm_widget_sub_object_redirect_to_top(obj, content);
1255 return EINA_FALSE;
1256 }
1257 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1258 if (!sub_d)
1259 {
1260 ERR("failed to allocate memory!");
1261 edje_object_part_unswallow(wd->resize_obj, content);
1262 _elm_widget_sub_object_redirect_to_top(obj, content);
1263 return EINA_FALSE;
1264 }
1265 sub_d->type = SWALLOW;
1266 sub_d->part = eina_stringshare_add(part);
1267 sub_d->obj = content;
1268 sd->subs = eina_list_append(sd->subs, sub_d);
1269
1270 efl_parent_set(content, obj);
1271 _icon_signal_emit(sd, sub_d, EINA_TRUE);
1272 }
1273
1274 efl_canvas_group_change(obj);
1275
1276 end:
1277 return EINA_TRUE;
1278 }
1279
1280 EAPI Evas_Object *
elm_layout_content_get(const Evas_Object * obj,const char * swallow)1281 elm_layout_content_get(const Evas_Object *obj, const char *swallow)
1282 {
1283 EFL_UI_LAYOUT_CHECK(obj) NULL;
1284 // If the object is already dead, their shouldn't be any part in it
1285 if (efl_invalidated_get(obj)) return NULL;
1286 if (!swallow)
1287 {
1288 swallow = efl_ui_widget_default_content_part_get(obj);
1289 if (!swallow) return NULL;
1290 }
1291 else if (!_elm_layout_part_aliasing_eval(obj, &swallow, EINA_FALSE))
1292 return NULL;
1293
1294 return efl_content_get(efl_part(obj, swallow));
1295 }
1296
1297 static Evas_Object*
_efl_ui_layout_content_get(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part)1298 _efl_ui_layout_content_get(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part)
1299 {
1300 const Eina_List *l;
1301 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1302
1303 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1304 {
1305 if ((sub_d->type != TEXT) && !strcmp(part, sub_d->part))
1306 {
1307 if (sub_d->type == SWALLOW)
1308 return sub_d->obj;
1309 }
1310 }
1311
1312 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1313 return efl_content_get(efl_part(wd->resize_obj, part));
1314 }
1315
1316 EAPI Evas_Object *
elm_layout_content_unset(Evas_Object * obj,const char * swallow)1317 elm_layout_content_unset(Evas_Object *obj, const char *swallow)
1318 {
1319 EFL_UI_LAYOUT_CHECK(obj) NULL;
1320 if (!swallow)
1321 {
1322 swallow = efl_ui_widget_default_content_part_get(obj);
1323 if (!swallow) return NULL;
1324 }
1325 else if (!_elm_layout_part_aliasing_eval(obj, &swallow, EINA_FALSE))
1326 return NULL;
1327
1328 return efl_content_unset(efl_part(obj, swallow));
1329 }
1330
1331 static Evas_Object*
_efl_ui_layout_content_unset(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part)1332 _efl_ui_layout_content_unset(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part)
1333 {
1334 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1335 Eina_List *l;
1336
1337 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1338
1339 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1340 {
1341 if ((sub_d->type == SWALLOW) && (!strcmp(part, sub_d->part)))
1342 {
1343 Evas_Object *content;
1344
1345 if (!sub_d->obj) return NULL;
1346
1347 content = sub_d->obj; /* sub_d will die in
1348 * _efl_ui_layout_smart_widget_sub_object_del */
1349
1350 if (!_elm_widget_sub_object_redirect_to_top(obj, content))
1351 {
1352 ERR("could not remove sub object %p from %p", content, obj);
1353 return NULL;
1354 }
1355
1356 edje_object_part_unswallow
1357 (wd->resize_obj, content);
1358 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1359 {
1360 if (sub_d->obj == content)
1361 {
1362 sd->subs = eina_list_remove_list(sd->subs, l);
1363 _icon_signal_emit(sd, sub_d, EINA_FALSE);
1364 eina_stringshare_del(sub_d->part);
1365 free(sub_d);
1366 break;
1367 }
1368 }
1369 _eo_unparent_helper(content, obj);
1370 return content;
1371 }
1372 }
1373
1374 return NULL;
1375 }
1376
1377 /* legacy only - eo is iterator */
1378 EAPI Eina_List *
elm_layout_content_swallow_list_get(const Evas_Object * obj)1379 elm_layout_content_swallow_list_get(const Evas_Object *obj)
1380 {
1381 EFL_UI_LAYOUT_CHECK(obj) NULL;
1382 Eina_List *ret = NULL;
1383 Efl_Ui_Layout_Sub_Object_Data *sub_d = NULL;
1384 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
1385 Eina_List *l = NULL;
1386
1387 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1388 {
1389 if (sub_d->type == SWALLOW)
1390 ret = eina_list_append(ret, sub_d->obj);
1391 }
1392
1393 return ret;
1394 }
1395
1396 static Eina_Bool
_sub_iterator_next(Efl_Ui_Layout_Sub_Iterator * it,void ** data)1397 _sub_iterator_next(Efl_Ui_Layout_Sub_Iterator *it, void **data)
1398 {
1399 Efl_Ui_Layout_Sub_Object_Data *sub;
1400
1401 if (!eina_iterator_next(it->real_iterator, (void **)&sub))
1402 return EINA_FALSE;
1403
1404 if (data) *data = sub->obj;
1405 return EINA_TRUE;
1406 }
1407
1408 static Efl_Ui_Layout *
_sub_iterator_get_container(Efl_Ui_Layout_Sub_Iterator * it)1409 _sub_iterator_get_container(Efl_Ui_Layout_Sub_Iterator *it)
1410 {
1411 return it->object;
1412 }
1413
1414 static void
_sub_iterator_free(Efl_Ui_Layout_Sub_Iterator * it)1415 _sub_iterator_free(Efl_Ui_Layout_Sub_Iterator *it)
1416 {
1417 eina_iterator_free(it->real_iterator);
1418 free(it);
1419 }
1420
1421 static Eina_Iterator *
_sub_iterator_create(Eo * eo_obj,Efl_Ui_Layout_Data * sd)1422 _sub_iterator_create(Eo *eo_obj, Efl_Ui_Layout_Data *sd)
1423 {
1424 Efl_Ui_Layout_Sub_Iterator *it;
1425
1426 it = calloc(1, sizeof(*it));
1427 if (!it) return NULL;
1428
1429 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
1430
1431 it->real_iterator = eina_list_iterator_new(sd->subs);
1432 it->iterator.version = EINA_ITERATOR_VERSION;
1433 it->iterator.next = FUNC_ITERATOR_NEXT(_sub_iterator_next);
1434 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_sub_iterator_get_container);
1435 it->iterator.free = FUNC_ITERATOR_FREE(_sub_iterator_free);
1436 it->object = eo_obj;
1437
1438 return &it->iterator;
1439 }
1440
1441 EOLIAN static Eina_Iterator *
_efl_ui_layout_base_efl_container_content_iterate(Eo * eo_obj EINA_UNUSED,Efl_Ui_Layout_Data * sd)1442 _efl_ui_layout_base_efl_container_content_iterate(Eo *eo_obj EINA_UNUSED, Efl_Ui_Layout_Data *sd)
1443 {
1444 return _sub_iterator_create(eo_obj, sd);
1445 }
1446
1447 EOLIAN static int
_efl_ui_layout_base_efl_container_content_count(Eo * eo_obj EINA_UNUSED,Efl_Ui_Layout_Data * sd)1448 _efl_ui_layout_base_efl_container_content_count(Eo *eo_obj EINA_UNUSED, Efl_Ui_Layout_Data *sd)
1449 {
1450 return eina_list_count(sd->subs);
1451 }
1452
1453 static Eina_Bool
_efl_ui_layout_text_generic_set(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,const char * text,Eina_Bool is_markup)1454 _efl_ui_layout_text_generic_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, const char *text, Eina_Bool is_markup)
1455 {
1456 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1457
1458 Efl_Ui_Layout_Sub_Object_Data *sub_d = NULL;
1459 Eina_List *l;
1460 Efl_Model *model;
1461
1462 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1463 {
1464 if ((sub_d->type == TEXT) && (!strcmp(part, sub_d->part)))
1465 {
1466 if (!text)
1467 {
1468 _text_signal_emit(sd, sub_d, EINA_FALSE);
1469 eina_stringshare_del(sub_d->part);
1470 free(sub_d);
1471 edje_object_part_text_escaped_set
1472 (wd->resize_obj, part, NULL);
1473 sd->subs = eina_list_remove_list(sd->subs, l);
1474 efl_canvas_group_change(obj);
1475 return EINA_TRUE;
1476 }
1477 else
1478 break;
1479 }
1480 }
1481
1482 if (!text) return EINA_TRUE;
1483
1484 if (elm_widget_is_legacy(obj))
1485 {
1486 if (!edje_object_part_text_escaped_set
1487 (wd->resize_obj, part, text))
1488 return EINA_FALSE;
1489 }
1490 else if (is_markup)
1491 {
1492 efl_text_markup_set(efl_part(wd->resize_obj, part), text);
1493 }
1494 else
1495 {
1496 efl_text_set(efl_part(wd->resize_obj, part), text);
1497 }
1498
1499 if (!sub_d)
1500 {
1501 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1502 if (!sub_d) return EINA_FALSE;
1503 sub_d->type = TEXT;
1504 sub_d->part = eina_stringshare_add(part);
1505 sd->subs = eina_list_append(sd->subs, sub_d);
1506 }
1507
1508 _text_signal_emit(sd, sub_d, EINA_TRUE);
1509
1510 efl_canvas_group_change(obj);
1511
1512 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON &&
1513 sd->can_access && !(sub_d->obj))
1514 sub_d->obj = _elm_access_edje_object_part_object_register
1515 (obj, elm_layout_edje_get(obj), part);
1516
1517 model = efl_ui_view_model_get(obj);
1518 if (model && !sd->connect.updating)
1519 {
1520 char *property = eina_hash_find(sd->connect.properties, sub_d->part);
1521
1522 if (property)
1523 {
1524 Eina_Value v = EINA_VALUE_EMPTY;
1525
1526 eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
1527 eina_value_set(&v, text);
1528
1529 efl_model_property_set(model, property, &v);
1530 }
1531 }
1532
1533 return EINA_TRUE;
1534 }
1535
1536 static Eina_Bool
_efl_ui_layout_text_set(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,const char * text)1537 _efl_ui_layout_text_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, const char *text)
1538 {
1539 return _efl_ui_layout_text_generic_set(obj, sd, part, text, EINA_FALSE);
1540 }
1541
1542 static const char*
_efl_ui_layout_text_get(Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char * part)1543 _efl_ui_layout_text_get(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *part)
1544 {
1545 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1546
1547 if (elm_widget_is_legacy(obj))
1548 {
1549 return edje_object_part_text_get(wd->resize_obj, part);
1550 }
1551 return efl_text_get(efl_part(wd->resize_obj, part));
1552 }
1553
1554 static const char*
_efl_ui_layout_text_markup_get(Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char * part)1555 _efl_ui_layout_text_markup_get(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *part)
1556 {
1557 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1558
1559 return efl_text_markup_get(efl_part(wd->resize_obj, part));
1560 }
1561
1562 static Eina_Bool
_efl_ui_layout_text_markup_set(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,const char * text)1563 _efl_ui_layout_text_markup_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, const char *text)
1564 {
1565 return _efl_ui_layout_text_generic_set(obj, sd, part, text, EINA_TRUE);
1566 }
1567
1568 static void
_layout_box_subobj_init(Efl_Ui_Layout_Data * sd,Efl_Ui_Layout_Sub_Object_Data * sub_d,const char * part,Evas_Object * child)1569 _layout_box_subobj_init(Efl_Ui_Layout_Data *sd, Efl_Ui_Layout_Sub_Object_Data *sub_d, const char *part, Evas_Object *child)
1570 {
1571 sub_d->part = eina_stringshare_add(part);
1572 sub_d->obj = child;
1573 sd->subs = eina_list_append(sd->subs, sub_d);
1574 efl_parent_set(child, sd->obj);
1575 }
1576
1577 Eina_Bool
_efl_ui_layout_box_append(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child)1578 _efl_ui_layout_box_append(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child)
1579 {
1580 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1581
1582 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1583
1584 if (!edje_object_part_box_append
1585 (wd->resize_obj, part, child))
1586 {
1587 ERR("child %p could not be appended to box part '%s'", child, part);
1588 return EINA_FALSE;
1589 }
1590
1591 if (!elm_widget_sub_object_add(obj, child))
1592 {
1593 edje_object_part_box_remove
1594 (wd->resize_obj, part, child);
1595 return EINA_FALSE;
1596 }
1597
1598 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1599 if (!sub_d)
1600 {
1601 ERR("failed to allocate memory!");
1602 _elm_widget_sub_object_redirect_to_top(obj, child);
1603 edje_object_part_box_remove(wd->resize_obj, part, child);
1604 return EINA_FALSE;
1605 }
1606 sub_d->type = BOX_APPEND;
1607 _layout_box_subobj_init(sd, sub_d, part, child);
1608
1609 efl_canvas_group_change(obj);
1610
1611 return EINA_TRUE;
1612 }
1613
1614 Eina_Bool
_efl_ui_layout_box_prepend(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child)1615 _efl_ui_layout_box_prepend(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child)
1616 {
1617 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1618
1619 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1620
1621 if (!edje_object_part_box_prepend
1622 (wd->resize_obj, part, child))
1623 {
1624 ERR("child %p could not be prepended to box part '%s'", child, part);
1625 return EINA_FALSE;
1626 }
1627
1628 if (!elm_widget_sub_object_add(obj, child))
1629 {
1630 edje_object_part_box_remove
1631 (wd->resize_obj, part, child);
1632 return EINA_FALSE;
1633 }
1634
1635 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1636 if (!sub_d)
1637 {
1638 ERR("failed to allocate memory!");
1639 _elm_widget_sub_object_redirect_to_top(obj, child);
1640 edje_object_part_box_remove(wd->resize_obj, part, child);
1641 return EINA_FALSE;
1642 }
1643 sub_d->type = BOX_PREPEND;
1644 _layout_box_subobj_init(sd, sub_d, part, child);
1645
1646 efl_canvas_group_change(obj);
1647
1648 return EINA_TRUE;
1649 }
1650
1651 Eina_Bool
_efl_ui_layout_box_insert_before(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child,const Evas_Object * reference)1652 _efl_ui_layout_box_insert_before(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child, const Evas_Object *reference)
1653 {
1654 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1655
1656 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1657
1658 if (!edje_object_part_box_insert_before
1659 (wd->resize_obj, part, child, reference))
1660 {
1661 ERR("child %p could not be inserted before %p inf box part '%s'",
1662 child, reference, part);
1663 return EINA_FALSE;
1664 }
1665
1666 if (!elm_widget_sub_object_add(obj, child))
1667 {
1668 edje_object_part_box_remove
1669 (wd->resize_obj, part, child);
1670 return EINA_FALSE;
1671 }
1672
1673 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1674 if (!sub_d)
1675 {
1676 ERR("failed to allocate memory!");
1677 _elm_widget_sub_object_redirect_to_top(obj, child);
1678 edje_object_part_box_remove(wd->resize_obj, part, child);
1679 return EINA_FALSE;
1680 }
1681 sub_d->type = BOX_INSERT_BEFORE;
1682 sub_d->p.box.reference = reference;
1683 _layout_box_subobj_init(sd, sub_d, part, child);
1684
1685 evas_object_event_callback_add
1686 ((Evas_Object *)reference, EVAS_CALLBACK_DEL, _box_reference_del, sub_d);
1687
1688 efl_canvas_group_change(obj);
1689
1690 return EINA_TRUE;
1691 }
1692
1693 Eina_Bool
_efl_ui_layout_box_insert_at(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child,unsigned int pos)1694 _efl_ui_layout_box_insert_at(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child, unsigned int pos)
1695 {
1696 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1697 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1698
1699 if (!edje_object_part_box_insert_at
1700 (wd->resize_obj, part, child, pos))
1701 {
1702 ERR("child %p could not be inserted at %u to box part '%s'",
1703 child, pos, part);
1704 return EINA_FALSE;
1705 }
1706
1707 if (!elm_widget_sub_object_add(obj, child))
1708 {
1709 edje_object_part_box_remove
1710 (wd->resize_obj, part, child);
1711 return EINA_FALSE;
1712 }
1713
1714 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1715 if (!sub_d)
1716 {
1717 ERR("failed to allocate memory!");
1718 _elm_widget_sub_object_redirect_to_top(obj, child);
1719 edje_object_part_box_remove(wd->resize_obj, part, child);
1720 return EINA_FALSE;
1721 }
1722 sub_d->type = BOX_INSERT_AT;
1723 sub_d->p.box.pos = pos;
1724 _layout_box_subobj_init(sd, sub_d, part, child);
1725
1726 efl_canvas_group_change(obj);
1727
1728 return EINA_TRUE;
1729 }
1730
1731 Evas_Object *
_efl_ui_layout_box_remove(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child)1732 _efl_ui_layout_box_remove(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child)
1733 {
1734
1735 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
1736 EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL);
1737
1738
1739 const Eina_List *l;
1740 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1741
1742 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1743 {
1744 if (!_sub_box_is(sub_d)) continue;
1745 if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
1746 return _sub_box_remove(obj, sd, sub_d);
1747 }
1748
1749 return NULL;
1750 }
1751
1752 Eina_Bool
_efl_ui_layout_box_remove_all(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Eina_Bool clear)1753 _efl_ui_layout_box_remove_all(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Eina_Bool clear)
1754 {
1755 EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE);
1756
1757 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1758
1759 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1760 Eina_List *lst;
1761
1762 lst = eina_list_clone(sd->subs);
1763 EINA_LIST_FREE(lst, sub_d)
1764 {
1765 if (!_sub_box_is(sub_d)) continue;
1766 if (!strcmp(sub_d->part, part))
1767 {
1768 /* original item's deletion handled at sub-obj-del */
1769 Evas_Object *child = _sub_box_remove(obj, sd, sub_d);
1770 if ((clear) && (child)) evas_object_del(child);
1771 }
1772 }
1773
1774 /* eventually something may not be added with elm_layout, delete them
1775 * as well */
1776 edje_object_part_box_remove_all
1777 (wd->resize_obj, part, clear);
1778
1779 return EINA_TRUE;
1780 }
1781
1782 Eina_Bool
_efl_ui_layout_table_pack(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child,unsigned short col,unsigned short row,unsigned short colspan,unsigned short rowspan)1783 _efl_ui_layout_table_pack(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
1784 {
1785 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1786
1787 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1788
1789 if (!edje_object_part_table_pack
1790 (wd->resize_obj, part, child, col,
1791 row, colspan, rowspan))
1792 {
1793 ERR("child %p could not be packed into table part '%s' col=%uh, row=%hu,"
1794 " colspan=%hu, rowspan=%hu", child, part, col, row, colspan,
1795 rowspan);
1796 return EINA_FALSE;
1797 }
1798
1799 if (!elm_widget_sub_object_add(obj, child))
1800 {
1801 edje_object_part_table_unpack
1802 (wd->resize_obj, part, child);
1803 return EINA_FALSE;
1804 }
1805
1806 sub_d = ELM_NEW(Efl_Ui_Layout_Sub_Object_Data);
1807 if (!sub_d)
1808 {
1809 ERR("failed to allocate memory!");
1810 _elm_widget_sub_object_redirect_to_top(obj, child);
1811 edje_object_part_table_unpack(wd->resize_obj, part, child);
1812 return EINA_FALSE;
1813 }
1814 sub_d->type = TABLE_PACK;
1815 sub_d->part = eina_stringshare_add(part);
1816 sub_d->obj = child;
1817 sub_d->p.table.col = col;
1818 sub_d->p.table.row = row;
1819 sub_d->p.table.colspan = colspan;
1820 sub_d->p.table.rowspan = rowspan;
1821 sd->subs = eina_list_append(sd->subs, sub_d);
1822 efl_parent_set(child, obj);
1823
1824 efl_canvas_group_change(obj);
1825
1826 return EINA_TRUE;
1827 }
1828
1829 Evas_Object *
_efl_ui_layout_table_unpack(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Evas_Object * child)1830 _efl_ui_layout_table_unpack(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Evas_Object *child)
1831 {
1832
1833 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
1834 EINA_SAFETY_ON_NULL_RETURN_VAL(child, NULL);
1835
1836 const Eina_List *l;
1837 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1838
1839 EINA_LIST_FOREACH(sd->subs, l, sub_d)
1840 {
1841 if (sub_d->type != TABLE_PACK) continue;
1842 if ((sub_d->obj == child) && (!strcmp(sub_d->part, part)))
1843 {
1844 return _sub_table_remove(obj, sd, sub_d);
1845 }
1846 }
1847
1848 return NULL;
1849 }
1850
1851 Eina_Bool
_efl_ui_layout_table_clear(Eo * obj,Efl_Ui_Layout_Data * sd,const char * part,Eina_Bool clear)1852 _efl_ui_layout_table_clear(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, Eina_Bool clear)
1853 {
1854 EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE);
1855
1856 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1857
1858 Efl_Ui_Layout_Sub_Object_Data *sub_d;
1859 Eina_List *lst;
1860
1861 lst = eina_list_clone(sd->subs);
1862 EINA_LIST_FREE(lst, sub_d)
1863 {
1864 if (sub_d->type != TABLE_PACK) continue;
1865 if (!strcmp(sub_d->part, part))
1866 {
1867 /* original item's deletion handled at sub-obj-del */
1868 Evas_Object *child = _sub_table_remove(obj, sd, sub_d);
1869 if ((clear) && (child)) evas_object_del(child);
1870 }
1871 }
1872
1873 /* eventually something may not be added with elm_layout, delete them
1874 * as well */
1875 edje_object_part_table_clear(wd->resize_obj, part, clear);
1876
1877 return EINA_TRUE;
1878 }
1879
1880 EAPI Evas_Object*
elm_layout_edje_get(const Eo * obj)1881 elm_layout_edje_get(const Eo *obj)
1882 {
1883 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(obj, MY_CLASS), NULL);
1884 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1885
1886 return wd->resize_obj;
1887 }
1888
1889 EOLIAN static const char *
_efl_ui_layout_base_efl_layout_group_group_data_get(const Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,const char * key)1890 _efl_ui_layout_base_efl_layout_group_group_data_get(const Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, const char *key)
1891 {
1892 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
1893
1894 return efl_layout_group_data_get(wd->resize_obj, key);
1895 }
1896
1897 EOLIAN static Eina_Size2D
_efl_ui_layout_base_efl_layout_group_group_size_min_get(const Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED)1898 _efl_ui_layout_base_efl_layout_group_group_size_min_get(const Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED)
1899 {
1900 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_SIZE2D(0, 0));
1901
1902 return efl_layout_group_size_min_get(wd->resize_obj);
1903 }
1904
1905 EOLIAN static Eina_Size2D
_efl_ui_layout_base_efl_layout_group_group_size_max_get(const Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED)1906 _efl_ui_layout_base_efl_layout_group_group_size_max_get(const Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED)
1907 {
1908 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_SIZE2D(0, 0));
1909
1910 return efl_layout_group_size_max_get(wd->resize_obj);
1911 }
1912
1913 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_layout_group_part_exist_get(const Eo * obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,const char * part)1914 _efl_ui_layout_base_efl_layout_group_part_exist_get(const Eo *obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, const char *part)
1915 {
1916 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
1917
1918 return efl_layout_group_part_exist_get(wd->resize_obj, part);
1919 }
1920
1921 EOLIAN static void
_efl_ui_layout_base_efl_canvas_group_group_change(Eo * obj,Efl_Ui_Layout_Data * sd)1922 _efl_ui_layout_base_efl_canvas_group_group_change(Eo *obj, Efl_Ui_Layout_Data *sd)
1923 {
1924 if (sd->frozen)
1925 /* cleared in thaw */
1926 sd->frozen_changed = EINA_TRUE;
1927 else
1928 efl_canvas_group_change(efl_super(obj, MY_CLASS));
1929 }
1930
1931 EOLIAN static void
_elm_layout_efl_canvas_group_change(Eo * obj,Elm_Layout_Data * ld)1932 _elm_layout_efl_canvas_group_change(Eo *obj, Elm_Layout_Data *ld)
1933 {
1934 Efl_Ui_Layout_Data *sd;
1935
1936 sd = efl_data_scope_safe_get(obj, EFL_UI_LAYOUT_BASE_CLASS);
1937 EINA_SAFETY_ON_NULL_RETURN(sd);
1938 if (sd->frozen) return;
1939 ld->needs_size_calc = EINA_TRUE;
1940 efl_canvas_group_change(efl_super(obj, ELM_LAYOUT_MIXIN));
1941 }
1942
1943 EOLIAN static void
_elm_layout_efl_gfx_hint_size_restricted_min_set(Eo * obj,Elm_Layout_Data * ld,Eina_Size2D sz)1944 _elm_layout_efl_gfx_hint_size_restricted_min_set(Eo *obj, Elm_Layout_Data *ld, Eina_Size2D sz)
1945 {
1946 /* correctly handle legacy case where the user has set a min size hint on the object:
1947 * in legacy code, only restricted_min existed, which resulted in conflicts between
1948 * internal sizing and user-expected sizing. we attempt to simulate this now in a more controlled
1949 * manner by only checking this hint during sizing calcs if the user has set it
1950 */
1951 if (!ld->in_calc)
1952 ld->user_min_sz = (sz.w > 0) || (sz.h > 0);
1953 efl_gfx_hint_size_restricted_min_set(efl_super(obj, ELM_LAYOUT_MIXIN), sz);
1954 }
1955
1956 /* layout's sizing evaluation is deferred. evaluation requests are
1957 * queued up and only flag the object as 'changed'. when it comes to
1958 * Evas's rendering phase, it will be addressed, finally (see
1959 * _efl_ui_layout_smart_calculate()). */
1960 EOLIAN static void
_elm_layout_sizing_eval(Eo * obj,Elm_Layout_Data * ld)1961 _elm_layout_sizing_eval(Eo *obj, Elm_Layout_Data *ld)
1962 {
1963 _elm_layout_efl_canvas_group_change(obj, ld);
1964 }
1965
1966 EAPI void
elm_layout_sizing_restricted_eval(Eo * obj,Eina_Bool w,Eina_Bool h)1967 elm_layout_sizing_restricted_eval(Eo *obj, Eina_Bool w, Eina_Bool h)
1968 {
1969 Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
1970
1971 EINA_SAFETY_ON_NULL_RETURN(ld);
1972 ld->restricted_calc_w = !!w;
1973 ld->restricted_calc_h = !!h;
1974
1975 efl_canvas_group_change(obj);
1976 }
1977
1978 EOLIAN static int
_efl_ui_layout_base_efl_layout_calc_calc_freeze(Eo * obj,Efl_Ui_Layout_Data * sd)1979 _efl_ui_layout_base_efl_layout_calc_calc_freeze(Eo *obj, Efl_Ui_Layout_Data *sd)
1980 {
1981 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, 0);
1982 sd->frozen = EINA_TRUE;
1983 return edje_object_freeze(wd->resize_obj);
1984 }
1985
1986 EOLIAN static int
_efl_ui_layout_base_efl_layout_calc_calc_thaw(Eo * obj,Efl_Ui_Layout_Data * sd)1987 _efl_ui_layout_base_efl_layout_calc_calc_thaw(Eo *obj, Efl_Ui_Layout_Data *sd)
1988 {
1989 int ret;
1990 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, 0);
1991
1992 ret = edje_object_thaw(wd->resize_obj);
1993
1994 if (!ret)
1995 {
1996 sd->frozen = EINA_FALSE;
1997 if (sd->frozen_changed)
1998 efl_canvas_group_change(obj);
1999 sd->frozen_changed = EINA_FALSE;
2000 }
2001
2002 return ret;
2003 }
2004
2005 EOLIAN void
_efl_ui_layout_base_efl_layout_calc_calc_auto_update_hints_set(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd EINA_UNUSED,Eina_Bool update)2006 _efl_ui_layout_base_efl_layout_calc_calc_auto_update_hints_set(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd EINA_UNUSED, Eina_Bool update)
2007 {
2008 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2009 efl_layout_calc_auto_update_hints_set(wd->resize_obj, update);
2010 }
2011
2012 EOLIAN Eina_Bool
_efl_ui_layout_base_efl_layout_calc_calc_auto_update_hints_get(const Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd EINA_UNUSED)2013 _efl_ui_layout_base_efl_layout_calc_calc_auto_update_hints_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd EINA_UNUSED)
2014 {
2015 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
2016 return efl_layout_calc_auto_update_hints_get(wd->resize_obj);
2017 }
2018
2019 EOLIAN Eina_Size2D
_efl_ui_layout_base_efl_layout_calc_calc_size_min(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd EINA_UNUSED,Eina_Size2D restricted)2020 _efl_ui_layout_base_efl_layout_calc_calc_size_min(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd EINA_UNUSED, Eina_Size2D restricted)
2021 {
2022 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, restricted);
2023 return efl_layout_calc_size_min(wd->resize_obj, restricted);
2024 }
2025
2026 EOLIAN Eina_Rect
_efl_ui_layout_base_efl_layout_calc_calc_parts_extends(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd EINA_UNUSED)2027 _efl_ui_layout_base_efl_layout_calc_calc_parts_extends(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd EINA_UNUSED)
2028 {
2029 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, (Eina_Rect){.rect = {0, 0, 0, 0}});
2030 return efl_layout_calc_parts_extends(wd->resize_obj);
2031 }
2032
2033 EOLIAN void
_efl_ui_layout_base_efl_layout_calc_calc_force(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * sd)2034 _efl_ui_layout_base_efl_layout_calc_calc_force(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *sd)
2035 {
2036 Eina_Bool prev_frozen = sd->frozen;
2037 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2038 sd->frozen = EINA_FALSE;
2039 efl_layout_calc_force(wd->resize_obj);
2040 sd->frozen = prev_frozen;
2041 }
2042
2043 static Eina_Bool
_efl_ui_layout_part_cursor_set(Efl_Ui_Layout_Data * sd,const char * part_name,const char * cursor)2044 _efl_ui_layout_part_cursor_set(Efl_Ui_Layout_Data *sd, const char *part_name, const char *cursor)
2045 {
2046 Evas_Object *part_obj;
2047 Efl_Ui_Layout_Sub_Object_Cursor *pc;
2048 Eo *obj = sd->obj;
2049
2050 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE);
2051 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE);
2052
2053 if (!cursor) return _efl_ui_layout_part_cursor_unset(sd, part_name);
2054
2055 edje_object_freeze(wd->resize_obj);
2056 part_obj = (Evas_Object *)edje_object_part_object_get
2057 (wd->resize_obj, part_name);
2058 edje_object_thaw(wd->resize_obj);
2059
2060 if (!part_obj)
2061 {
2062 const char *group, *file;
2063
2064 edje_object_file_get(wd->resize_obj, &file, &group);
2065 ERR("no part '%s' in group '%s' of file '%s'. Cannot set cursor '%s'",
2066 part_name, group, file, cursor);
2067 return EINA_FALSE;
2068 }
2069 if (evas_object_pass_events_get(part_obj))
2070 {
2071 const char *group, *file;
2072
2073 edje_object_file_get(wd->resize_obj, &file, &group);
2074 ERR("part '%s' in group '%s' of file '%s' has mouse_events: 0. "
2075 "Cannot set cursor '%s'",
2076 part_name, group, file, cursor);
2077 return EINA_FALSE;
2078 }
2079
2080 pc = _parts_cursors_find(sd, part_name);
2081 if (pc) eina_stringshare_replace(&pc->cursor, cursor);
2082 else
2083 {
2084 pc = calloc(1, sizeof(*pc));
2085 if (!pc)
2086 {
2087 ERR("failed to allocate memory!");
2088 return EINA_FALSE;
2089 }
2090 pc->part = eina_stringshare_add(part_name);
2091 pc->cursor = eina_stringshare_add(cursor);
2092 pc->style = eina_stringshare_add("default");
2093 sd->parts_cursors = eina_list_append(sd->parts_cursors, pc);
2094 }
2095
2096 pc->obj = part_obj;
2097 elm_object_sub_cursor_set(part_obj, obj, pc->cursor);
2098
2099 return EINA_TRUE;
2100 }
2101
2102 static const char *
_efl_ui_layout_part_cursor_get(Efl_Ui_Layout_Data * sd,const char * part_name)2103 _efl_ui_layout_part_cursor_get(Efl_Ui_Layout_Data *sd, const char *part_name)
2104 {
2105 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, NULL);
2106
2107 Efl_Ui_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name);
2108 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, NULL);
2109 EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, NULL);
2110
2111 return elm_object_cursor_get(pc->obj);
2112 }
2113
2114 static Eina_Bool
_efl_ui_layout_part_cursor_unset(Efl_Ui_Layout_Data * sd,const char * part_name)2115 _efl_ui_layout_part_cursor_unset(Efl_Ui_Layout_Data *sd, const char *part_name)
2116 {
2117 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE);
2118
2119 Eina_List *l;
2120 Efl_Ui_Layout_Sub_Object_Cursor *pc;
2121
2122 EINA_LIST_FOREACH(sd->parts_cursors, l, pc)
2123 {
2124 if (!strcmp(part_name, pc->part))
2125 {
2126 if (pc->obj) elm_object_cursor_unset(pc->obj);
2127 _part_cursor_free(pc);
2128 sd->parts_cursors = eina_list_remove_list(sd->parts_cursors, l);
2129 return EINA_TRUE;
2130 }
2131 }
2132
2133 return EINA_FALSE;
2134 }
2135
2136 static Eina_Bool
_efl_ui_layout_part_cursor_style_set(Efl_Ui_Layout_Data * sd,const char * part_name,const char * style)2137 _efl_ui_layout_part_cursor_style_set(Efl_Ui_Layout_Data *sd, const char *part_name, const char *style)
2138 {
2139 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE);
2140
2141 Efl_Ui_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name);
2142 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE);
2143 EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE);
2144
2145 eina_stringshare_replace(&pc->style, style);
2146 elm_object_cursor_style_set(pc->obj, pc->style);
2147
2148 return EINA_TRUE;
2149 }
2150
2151 static const char*
_efl_ui_layout_part_cursor_style_get(Efl_Ui_Layout_Data * sd,const char * part_name)2152 _efl_ui_layout_part_cursor_style_get(Efl_Ui_Layout_Data *sd, const char *part_name)
2153 {
2154 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, NULL);
2155
2156 Efl_Ui_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name);
2157 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, NULL);
2158 EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, NULL);
2159
2160 return elm_object_cursor_style_get(pc->obj);
2161 }
2162
2163 static Eina_Bool
_efl_ui_layout_part_cursor_engine_only_set(Efl_Ui_Layout_Data * sd,const char * part_name,Eina_Bool engine_only)2164 _efl_ui_layout_part_cursor_engine_only_set(Efl_Ui_Layout_Data *sd, const char *part_name, Eina_Bool engine_only)
2165 {
2166 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE);
2167
2168 Efl_Ui_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name);
2169 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE);
2170 EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE);
2171
2172 pc->engine_only = !!engine_only;
2173 elm_object_cursor_theme_search_enabled_set(pc->obj, !pc->engine_only);
2174
2175 return EINA_TRUE;
2176 }
2177
2178 static Eina_Bool
_efl_ui_layout_part_cursor_engine_only_get(Efl_Ui_Layout_Data * sd,const char * part_name)2179 _efl_ui_layout_part_cursor_engine_only_get(Efl_Ui_Layout_Data *sd, const char *part_name)
2180 {
2181 EINA_SAFETY_ON_NULL_RETURN_VAL(part_name, EINA_FALSE);
2182
2183 Efl_Ui_Layout_Sub_Object_Cursor *pc = _parts_cursors_find(sd, part_name);
2184 EINA_SAFETY_ON_NULL_RETURN_VAL(pc, EINA_FALSE);
2185 EINA_SAFETY_ON_NULL_RETURN_VAL(pc->obj, EINA_FALSE);
2186
2187 return !elm_object_cursor_theme_search_enabled_get(pc->obj);
2188 }
2189
2190 EAPI Eina_Bool
elm_layout_edje_object_can_access_set(Eo * obj,Eina_Bool can_access)2191 elm_layout_edje_object_can_access_set(Eo *obj, Eina_Bool can_access)
2192 {
2193 Efl_Ui_Layout_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2194 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
2195 sd->can_access = !!can_access;
2196 return EINA_TRUE;
2197 }
2198
2199 EAPI Eina_Bool
elm_layout_edje_object_can_access_get(const Eo * obj)2200 elm_layout_edje_object_can_access_get(const Eo *obj)
2201 {
2202 Efl_Ui_Layout_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2203 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
2204 return sd->can_access;
2205 }
2206
2207 EOLIAN static void
_efl_ui_layout_base_efl_object_dbg_info_get(Eo * eo_obj,Efl_Ui_Layout_Data * _pd EINA_UNUSED,Efl_Dbg_Info * root)2208 _efl_ui_layout_base_efl_object_dbg_info_get(Eo *eo_obj, Efl_Ui_Layout_Data *_pd EINA_UNUSED, Efl_Dbg_Info *root)
2209 {
2210 efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
2211 ELM_WIDGET_DATA_GET_OR_RETURN(eo_obj, wd);
2212
2213 if (wd->resize_obj && efl_isa(wd->resize_obj, EFL_CANVAS_LAYOUT_CLASS))
2214 {
2215 Efl_Dbg_Info *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
2216 const char *file, *edje_group;
2217 Evas_Object *edje_obj = wd->resize_obj;
2218 Edje_Load_Error error;
2219
2220 efl_file_simple_get(edje_obj, &file, &edje_group);
2221 EFL_DBG_INFO_APPEND(group, "File", EINA_VALUE_TYPE_STRING, file);
2222 EFL_DBG_INFO_APPEND(group, "Group", EINA_VALUE_TYPE_STRING, edje_group);
2223
2224 error = edje_object_load_error_get(edje_obj);
2225 if (error != EDJE_LOAD_ERROR_NONE)
2226 {
2227 EFL_DBG_INFO_APPEND(group, "Error", EINA_VALUE_TYPE_STRING,
2228 edje_load_error_str(error));
2229 }
2230 }
2231 }
2232
2233 static void
_efl_ui_layout_view_model_property_update(Efl_Ui_Layout_Data * pd,const char * part,const char * fetch)2234 _efl_ui_layout_view_model_property_update(Efl_Ui_Layout_Data *pd, const char *part, const char *fetch)
2235 {
2236 Eina_Value *v = NULL;
2237 char *value = NULL;
2238 Efl_Model *model;
2239
2240 model = efl_ui_view_model_get(pd->obj);
2241 v = efl_model_property_get(model, fetch);
2242 if (!v) return;
2243
2244 if (eina_value_type_get(v) != EINA_VALUE_TYPE_ERROR)
2245 value = eina_value_to_string(v);
2246
2247 pd->connect.updating = EINA_TRUE; // Prevent recursive call to property_set while updating text
2248 efl_text_set(efl_part(pd->obj, part), value);
2249 pd->connect.updating = EINA_FALSE;
2250
2251 eina_value_free(v);
2252 free(value);
2253 }
2254
2255 static void
_efl_ui_layout_view_model_signal_update(Efl_Ui_Layout_Data * pd,const char * signal,const char * fetch)2256 _efl_ui_layout_view_model_signal_update(Efl_Ui_Layout_Data *pd, const char *signal, const char *fetch)
2257 {
2258 Eina_Value *v = NULL;
2259 Eina_Strbuf *buf;
2260 char *value = NULL;
2261 Efl_Model *model;
2262 Eina_Bool eval = EINA_FALSE;
2263 Eina_Bool is_bool = EINA_FALSE;
2264
2265 model = efl_ui_view_model_get(pd->obj);
2266 v = efl_model_property_get(model, fetch);
2267 if (!v) return;
2268
2269 if (eina_value_type_get(v) == EINA_VALUE_TYPE_ERROR)
2270 {
2271 Eina_Error error;
2272
2273 eina_value_get(v, &error);
2274 if (error != EAGAIN) ERR("Failed to fetch signal value %s for property %s got error: %s", signal, fetch, eina_error_msg_get(error));
2275 return;
2276 }
2277
2278 is_bool = (eina_value_type_get(v) == EINA_VALUE_TYPE_BOOL);
2279 if (is_bool)
2280 {
2281 eina_value_bool_get(v, &eval);
2282 }
2283 value = eina_value_to_string(v);
2284
2285 buf = eina_strbuf_new();
2286 // FIXME: is it really the form of signal we want to send ?
2287 const char *ini = signal;
2288 for (;;)
2289 {
2290 const char *last = ini;
2291 ini = strstr(last, "%{");
2292 if (!ini)
2293 {
2294 eina_strbuf_append(buf, last);
2295 break;
2296 }
2297 if (!is_bool)
2298 {
2299 ERR("Using signal connection `%%{;}' with a property that is not boolean. Signal: `%s'; Property: `%s'.", signal, fetch);
2300 goto on_error;
2301 }
2302 eina_strbuf_append_length(buf, last, (size_t)(ini-last));
2303 const char *sep = strchr(ini+2, ';');
2304 if (!sep)
2305 {
2306 ERR("Could not find separator `;'.");
2307 goto on_error;
2308 }
2309 const char *fin = strchr(sep+1, '}');
2310 if (!fin)
2311 {
2312 ERR("Could not find terminator `}'.");
2313 goto on_error;
2314 }
2315 if (eval)
2316 eina_strbuf_append_length(buf, ini+2, (size_t)(sep-(ini+2)));
2317 else
2318 eina_strbuf_append_length(buf, sep+1, (size_t)(fin-(sep+1)));
2319 ini = fin+1;
2320 }
2321 eina_strbuf_replace_all(buf, "%v", value);
2322
2323 elm_layout_signal_emit(pd->obj, eina_strbuf_string_get(buf),
2324 elm_widget_is_legacy(pd->obj) ? "elm" : "efl");
2325
2326 on_error:
2327 eina_strbuf_free(buf);
2328 eina_value_free(v);
2329 free(value);
2330 }
2331
2332 typedef struct _Efl_Ui_Layout_Factory_Request Efl_Ui_Layout_Factory_Request;
2333 struct _Efl_Ui_Layout_Factory_Request
2334 {
2335 Efl_Ui_Layout_Factory_Tracking *tracking;
2336 Efl_Ui_Layout_Data *pd;
2337 Efl_Ui_Factory *factory;
2338 const char *key;
2339 };
2340
2341 static Eina_Value
_content_created(Eo * obj,void * data,const Eina_Value value)2342 _content_created(Eo *obj, void *data, const Eina_Value value)
2343 {
2344 Efl_Ui_Layout_Factory_Request *request = data;
2345 Efl_Gfx_Entity *content = NULL;
2346 Efl_Gfx_Entity *old_content[1];
2347 int len, i;
2348
2349 EINA_VALUE_ARRAY_FOREACH(&value, len, i, content)
2350 {
2351 // Recycle old content
2352 old_content[0] = efl_content_get(efl_part(obj, request->key));
2353 if (old_content[0]) efl_ui_factory_release(request->factory, EINA_C_ARRAY_ITERATOR_NEW(old_content));
2354
2355 // Set new content
2356 efl_content_set(efl_part(obj, request->key), content);
2357 }
2358
2359 return value;
2360 }
2361
2362 static void
_clean_request(Eo * obj EINA_UNUSED,void * data,const Eina_Future * dead_future EINA_UNUSED)2363 _clean_request(Eo *obj EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
2364 {
2365 Efl_Ui_Layout_Factory_Request *request = data;
2366
2367 request->tracking->in_flight = NULL;
2368 eina_stringshare_del(request->key);
2369 efl_unref(request->factory);
2370 free(request);
2371 }
2372
2373 static void
_efl_ui_layout_view_model_content_update(Efl_Ui_Layout_Data * pd,Efl_Ui_Layout_Factory_Tracking * tracking,const char * key)2374 _efl_ui_layout_view_model_content_update(Efl_Ui_Layout_Data *pd, Efl_Ui_Layout_Factory_Tracking *tracking, const char *key)
2375 {
2376 Efl_Ui_Layout_Factory_Request *request;
2377 Eina_Future *f;
2378 Efl_Model *models[1];
2379
2380 request = calloc(1, sizeof (Efl_Ui_Layout_Factory_Request));
2381 if (!request) return ;
2382
2383 if (tracking->in_flight) eina_future_cancel(tracking->in_flight);
2384
2385 request->key = eina_stringshare_ref(key);
2386 request->pd = pd;
2387 request->factory = efl_ref(tracking->factory);
2388 request->tracking = tracking;
2389
2390 models[0] = efl_ui_view_model_get(pd->obj);
2391 f = efl_ui_view_factory_create_with_event(tracking->factory, EINA_C_ARRAY_ITERATOR_NEW(models));
2392 f = efl_future_then(pd->obj, f,
2393 .success = _content_created,
2394 .success_type = EINA_VALUE_TYPE_ARRAY,
2395 .data = request,
2396 .free = _clean_request);
2397 }
2398
2399 static void
_efl_ui_layout_view_model_update(Efl_Ui_Layout_Data * pd)2400 _efl_ui_layout_view_model_update(Efl_Ui_Layout_Data *pd)
2401 {
2402 Eina_Hash_Tuple *tuple;
2403 Eina_Iterator *it;
2404
2405 if (!efl_ui_view_model_get(pd->obj)) return ;
2406
2407 it = eina_hash_iterator_tuple_new(pd->connect.properties);
2408 EINA_ITERATOR_FOREACH(it, tuple)
2409 _efl_ui_layout_view_model_property_update(pd, tuple->data, tuple->key);
2410 eina_iterator_free(it);
2411
2412 it = eina_hash_iterator_tuple_new(pd->connect.signals);
2413 EINA_ITERATOR_FOREACH(it, tuple)
2414 _efl_ui_layout_view_model_signal_update(pd, tuple->data, tuple->key);
2415 eina_iterator_free(it);
2416
2417 it = eina_hash_iterator_tuple_new(pd->connect.factories);
2418 EINA_ITERATOR_FOREACH(it, tuple)
2419 {
2420 Efl_Ui_Layout_Factory_Tracking *factory = tuple->data;
2421
2422 _efl_ui_layout_view_model_content_update(pd, factory, tuple->key);
2423 }
2424 eina_iterator_free(it);
2425 }
2426
2427 static void
_efl_model_properties_changed_cb(void * data,const Efl_Event * event)2428 _efl_model_properties_changed_cb(void *data, const Efl_Event *event)
2429 {
2430 Efl_Model_Property_Event *evt = event->info;
2431 Efl_Ui_Layout_Data *pd = data;
2432 const char *prop;
2433 Eina_Array_Iterator it;
2434 unsigned int i;
2435
2436 if (!evt->changed_properties) return ;
2437
2438 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
2439 {
2440 const char *part;
2441 const char *signal;
2442 Efl_Ui_Layout_Factory_Tracking *factory;
2443
2444 part = eina_hash_find(pd->connect.properties, prop);
2445 if (part) _efl_ui_layout_view_model_property_update(pd, part, prop);
2446
2447 signal = eina_hash_find(pd->connect.signals, prop);
2448 if (signal) _efl_ui_layout_view_model_signal_update(pd, signal, prop);
2449
2450 factory = eina_hash_find(pd->connect.factories, prop);
2451 if (factory) _efl_ui_layout_view_model_content_update(pd, factory, prop);
2452 }
2453 }
2454
2455 static void
_efl_ui_layout_factory_free(Efl_Ui_Layout_Factory_Tracking * tracking)2456 _efl_ui_layout_factory_free(Efl_Ui_Layout_Factory_Tracking *tracking)
2457 {
2458 if (tracking->in_flight) eina_future_cancel(tracking->in_flight);
2459 efl_unref(tracking->factory);
2460 eina_stringshare_del(tracking->key);
2461 free(tracking);
2462 }
2463
2464 static void
_efl_ui_layout_connect_hash(Efl_Ui_Layout_Data * pd)2465 _efl_ui_layout_connect_hash(Efl_Ui_Layout_Data *pd)
2466 {
2467 if (pd->connect.properties) return ;
2468
2469 pd->connect.properties = eina_hash_stringshared_new(EINA_FREE_CB(free)); // Hash of property targeting a part
2470 pd->connect.signals = eina_hash_stringshared_new(EINA_FREE_CB(free)); // Hash of property triggering a signal
2471 pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free)); // Hash of property triggering a content creation
2472 }
2473
2474
2475 static void
_efl_ui_layout_base_model_unregister(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * pd,Efl_Model * model)2476 _efl_ui_layout_base_model_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd,
2477 Efl_Model *model)
2478 {
2479 if (!model) return ;
2480 if (!pd->model_bound) return ;
2481
2482 efl_event_callback_del(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
2483 _efl_model_properties_changed_cb, pd);
2484
2485 pd->model_bound = EINA_FALSE;
2486 }
2487
2488 static void
_efl_ui_layout_base_model_register(Eo * obj,Efl_Ui_Layout_Data * pd,Efl_Model * model)2489 _efl_ui_layout_base_model_register(Eo *obj, Efl_Ui_Layout_Data *pd,
2490 Efl_Model *model)
2491 {
2492 Eina_Stringshare *key;
2493 Eina_Hash_Tuple *tuple;
2494 Eina_Iterator *it;
2495
2496 if (!model) return ;
2497 if (pd->model_bound) return;
2498 pd->model_bound = EINA_TRUE;
2499
2500 efl_event_callback_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
2501 _efl_model_properties_changed_cb, pd);
2502
2503 _efl_ui_layout_connect_hash(pd);
2504
2505 // Reset to empty state
2506 it = eina_hash_iterator_key_new(pd->connect.properties);
2507 EINA_ITERATOR_FOREACH(it, key)
2508 {
2509 efl_text_set(efl_part(obj, key), NULL);
2510 }
2511 eina_iterator_free(it);
2512
2513 it = eina_hash_iterator_tuple_new(pd->connect.factories);
2514 EINA_ITERATOR_FOREACH(it, tuple)
2515 {
2516 Efl_Ui_Layout_Factory_Tracking *factory;
2517 Efl_Gfx_Entity *content[1];
2518
2519 key = tuple->key;
2520 factory = tuple->data;
2521
2522 // Cancel in flight creation request
2523 if (factory->in_flight) eina_future_cancel(factory->in_flight);
2524
2525 // Cleanup content
2526 content[0] = efl_content_get(efl_part(obj, key));
2527 efl_content_unset(efl_part(obj, key));
2528
2529 // And recycle it
2530 if (content[0]) efl_ui_factory_release(factory->factory, EINA_C_ARRAY_ITERATOR_NEW(content));
2531 }
2532 eina_iterator_free(it);
2533
2534 // Refresh content if necessary
2535 _efl_ui_layout_view_model_update(pd);
2536 }
2537
2538 static void
_efl_ui_layout_base_model_update(void * data,const Efl_Event * event)2539 _efl_ui_layout_base_model_update(void *data, const Efl_Event *event)
2540 {
2541 Efl_Ui_Layout_Data *pd = data;
2542 Efl_Model_Changed_Event *ev = event->info;
2543
2544 _efl_ui_layout_base_model_unregister(event->object, pd, ev->previous);
2545 _efl_ui_layout_base_model_register(event->object, pd, ev->current);
2546 }
2547
2548 static void
_efl_ui_layout_base_model_watch(Eo * obj,Efl_Ui_Layout_Data * pd)2549 _efl_ui_layout_base_model_watch(Eo *obj, Efl_Ui_Layout_Data *pd)
2550 {
2551 Efl_Model *model;
2552
2553 if (pd->model_watch) return ;
2554 pd->model_watch = EINA_TRUE;
2555
2556 efl_event_callback_add(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
2557 _efl_ui_layout_base_model_update, pd);
2558 model = efl_ui_view_model_get(obj);
2559 if (!model) return ;
2560 _efl_ui_layout_base_model_register(obj, pd, model);
2561 }
2562
2563 EOLIAN static Eina_Error
_efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo * obj,Efl_Ui_Layout_Data * pd,const char * key,const char * property)2564 _efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Layout_Data *pd, const char *key, const char *property)
2565 {
2566 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EFL_PROPERTY_ERROR_INVALID_KEY);
2567 Eina_Stringshare *sprop;
2568 Eina_Stringshare *sk;
2569 Eina_Hash *hash = NULL;
2570 char *data = NULL;
2571 Efl_Model *model;
2572 Eina_Error r;
2573
2574 // First try binding with property on the Widget
2575 r = efl_ui_property_bind(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS), key, property);
2576 if (!r) return r;
2577
2578 // Before trying to bind on the part of this object.
2579 if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
2580 return EFL_PROPERTY_ERROR_INVALID_KEY;
2581
2582 // Check if there is a model and register it
2583 _efl_ui_layout_base_model_watch(obj, pd);
2584
2585 _efl_ui_layout_connect_hash(pd);
2586
2587 sprop = eina_stringshare_add(property);
2588
2589 // FIXME: prevent double connect of key to multiple property ?
2590 if (strncmp(SIGNAL_PREFIX, key, sizeof(SIGNAL_PREFIX) - 1) == 0)
2591 {
2592 hash = pd->connect.signals;
2593 data = strdup(key + sizeof(SIGNAL_PREFIX) - 1);
2594 }
2595 else
2596 {
2597 hash = pd->connect.properties;
2598 data = strdup(key);
2599 }
2600
2601 if (!sprop)
2602 {
2603 // FIXME: remove the entry from the hash ?
2604 }
2605 else
2606 {
2607 eina_hash_add(hash, sprop, data);
2608 }
2609
2610 // Update display right away if possible
2611 model = efl_ui_view_model_get(obj);
2612 if (model)
2613 {
2614 if (hash == pd->connect.signals)
2615 _efl_ui_layout_view_model_signal_update(pd, data, sprop);
2616 else
2617 _efl_ui_layout_view_model_property_update(pd, data, sprop);
2618 }
2619
2620 sk = eina_stringshare_add(key);
2621 efl_event_callback_call(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) sk);
2622 eina_stringshare_del(sk);
2623
2624 if (!sprop)
2625 free(data);
2626
2627 return 0;
2628 }
2629
2630 EOLIAN static Eina_Error
_efl_ui_layout_base_efl_ui_factory_bind_factory_bind(Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * pd,const char * key,Efl_Ui_Factory * factory)2631 _efl_ui_layout_base_efl_ui_factory_bind_factory_bind(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd,
2632 const char *key, Efl_Ui_Factory *factory)
2633 {
2634 EINA_SAFETY_ON_NULL_RETURN_VAL(key, EFL_PROPERTY_ERROR_INVALID_KEY);
2635 Efl_Ui_Layout_Factory_Tracking *tracking;
2636 Eina_Stringshare *ss_key;
2637
2638 if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
2639 return EFL_PROPERTY_ERROR_INVALID_KEY;
2640
2641 // Check if there is a model and register it
2642 _efl_ui_layout_base_model_watch(obj, pd);
2643
2644 if (!pd->connect.factories)
2645 pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free));
2646
2647 ss_key = eina_stringshare_add(key);
2648
2649 // First undo the old one if there is one
2650 tracking = eina_hash_find(pd->connect.factories, ss_key);
2651 if (tracking)
2652 {
2653 Efl_Gfx_Entity *old[1];
2654
2655 // Unset and recycle
2656 old[0] = efl_content_get(efl_part(obj, ss_key));
2657 efl_content_unset(efl_part(obj, ss_key));
2658 if (old[0]) efl_ui_factory_release(tracking->factory, EINA_C_ARRAY_ITERATOR_NEW(old));
2659
2660 // Stop in flight request
2661 if (tracking->in_flight) eina_future_cancel(tracking->in_flight);
2662
2663 // Release previous factory
2664 efl_replace(&tracking->factory, NULL);
2665 }
2666 else
2667 {
2668 tracking = calloc(1, sizeof (Efl_Ui_Layout_Factory_Tracking));
2669 if (!tracking) return ENOMEM;
2670
2671 tracking->key = ss_key;
2672
2673 eina_hash_add(pd->connect.factories, ss_key, tracking);
2674 }
2675
2676 // And update content with the new factory
2677 tracking->factory = efl_ref(factory);
2678
2679 _efl_ui_layout_view_model_content_update(pd, tracking, ss_key);
2680
2681 return EINA_ERROR_NO_ERROR;
2682 }
2683
2684 EOLIAN void
_efl_ui_layout_base_efl_ui_i18n_language_set(Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char * locale)2685 _efl_ui_layout_base_efl_ui_i18n_language_set(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *locale)
2686 {
2687 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2688 efl_ui_language_set(wd->resize_obj, locale);
2689 }
2690
2691 EOLIAN const char *
_efl_ui_layout_base_efl_ui_i18n_language_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED)2692 _efl_ui_layout_base_efl_ui_i18n_language_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED)
2693 {
2694 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2695 return efl_ui_language_get(wd->resize_obj);
2696 }
2697
2698 EOLIAN static void
_efl_ui_layout_base_efl_ui_l10n_l10n_text_set(Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char * label,const char * domain)2699 _efl_ui_layout_base_efl_ui_l10n_l10n_text_set(Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *label, const char *domain)
2700 {
2701 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2702 efl_ui_l10n_text_set(efl_part(obj, efl_ui_widget_default_text_part_get(obj)), label, domain);
2703 }
2704
2705 EOLIAN static const char *
_efl_ui_layout_base_efl_ui_l10n_l10n_text_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char ** domain)2706 _efl_ui_layout_base_efl_ui_l10n_l10n_text_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char **domain)
2707 {
2708 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2709 return efl_ui_l10n_text_get(efl_part(obj, efl_ui_widget_default_text_part_get(obj)), domain);
2710 }
2711
2712 EOLIAN static Eo *
_efl_ui_layout_efl_object_constructor(Eo * obj,void * _pd EINA_UNUSED)2713 _efl_ui_layout_efl_object_constructor(Eo *obj, void *_pd EINA_UNUSED)
2714 {
2715 obj = efl_constructor(efl_super(obj, EFL_UI_LAYOUT_CLASS));
2716 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
2717
2718 /* basic layouts should not obey finger size */
2719 sd->finger_size_multiplier_x = sd->finger_size_multiplier_y = 0;
2720
2721 return obj;
2722 }
2723
2724 EOLIAN static Eo *
_efl_ui_layout_base_efl_object_constructor(Eo * obj,Efl_Ui_Layout_Data * sd)2725 _efl_ui_layout_base_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Data *sd)
2726 {
2727 sd->obj = obj;
2728 sd->needs_theme_apply = EINA_TRUE;
2729 sd->finger_size_multiplier_x = sd->finger_size_multiplier_y = 1;
2730 obj = efl_constructor(efl_super(obj, MY_CLASS));
2731 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
2732 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER);
2733
2734 return obj;
2735 }
2736
2737 EOLIAN static Efl_Object*
_efl_ui_layout_base_efl_object_finalize(Eo * obj,Efl_Ui_Layout_Data * pd)2738 _efl_ui_layout_base_efl_object_finalize(Eo *obj, Efl_Ui_Layout_Data *pd)
2739 {
2740 Eo *eo, *win;
2741 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
2742 eo = efl_finalize(efl_super(obj, MY_CLASS));
2743 if (pd->needs_theme_apply)
2744 {
2745 efl_ui_widget_theme_apply(eo);
2746 /* handle case where subclass does not call into layout */
2747 pd->needs_theme_apply = EINA_FALSE;
2748 }
2749 else if (pd->deferred_signals)
2750 _deferred_signals_emit(pd);
2751 efl_canvas_group_change(obj);
2752
2753 Elm_Layout_Data *ld = efl_data_scope_safe_get(obj, ELM_LAYOUT_MIXIN);
2754 /* need to explicitly set this here to permit group_calc since efl_canvas_group_change
2755 * blocks non-finalized objects and the object will not be finalized until after this
2756 * function returns
2757 */
2758 if (ld) ld->needs_size_calc = EINA_TRUE;
2759
2760 win = elm_widget_top_get(obj);
2761 if (efl_isa(win, EFL_UI_WIN_CLASS))
2762 efl_ui_layout_theme_rotation_apply(obj, efl_ui_win_rotation_get(win));
2763
2764 if (efl_file_get(wd->resize_obj) || efl_file_mmap_get(wd->resize_obj))
2765 efl_file_load(wd->resize_obj);
2766
2767 return eo;
2768 }
2769
2770 static void
_efl_ui_layout_base_efl_object_invalidate(Eo * obj,Efl_Ui_Layout_Data * pd)2771 _efl_ui_layout_base_efl_object_invalidate(Eo *obj, Efl_Ui_Layout_Data *pd)
2772 {
2773 if (pd->model_watch)
2774 {
2775 Efl_Model *model;
2776
2777 pd->model_watch = EINA_FALSE;
2778 efl_event_callback_del(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
2779 _efl_ui_layout_base_model_update, pd);
2780
2781 model = efl_ui_view_model_get(obj);
2782 if (!model)
2783 {
2784 _efl_ui_layout_base_model_unregister(obj, pd, model);
2785 }
2786 }
2787
2788 efl_invalidate(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS));
2789 }
2790
2791 EOLIAN static void
_efl_ui_layout_base_efl_layout_signal_message_send(Eo * obj,Efl_Ui_Layout_Data * pd EINA_UNUSED,int id,const Eina_Value msg)2792 _efl_ui_layout_base_efl_layout_signal_message_send(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, int id, const Eina_Value msg)
2793 {
2794 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2795 efl_layout_signal_message_send(wd->resize_obj, id, msg);
2796 }
2797
2798 EOLIAN static void
_efl_ui_layout_base_efl_layout_signal_signal_process(Eo * obj,Efl_Ui_Layout_Data * pd EINA_UNUSED,Eina_Bool recurse)2799 _efl_ui_layout_base_efl_layout_signal_signal_process(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, Eina_Bool recurse)
2800 {
2801 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
2802 efl_layout_signal_process(wd->resize_obj, recurse);
2803 }
2804
2805 /* Efl.Part implementation */
2806
2807 EOLIAN static Eo *
_efl_ui_layout_base_efl_part_part_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED,const char * part)2808 _efl_ui_layout_base_efl_part_part_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED, const char *part)
2809 {
2810 Efl_Canvas_Layout_Part_Type type = EFL_CANVAS_LAYOUT_PART_TYPE_NONE;
2811
2812 EINA_SAFETY_ON_NULL_RETURN_VAL(part, NULL);
2813 ELM_WIDGET_DATA_GET_OR_RETURN((Eo *) obj, wd, NULL);
2814
2815 // Check part type without using edje_object_part_object_get(), as this
2816 // can cause recalc, which has side effects... and could be slow.
2817
2818 if (!elm_widget_is_legacy(obj))
2819 {
2820 if (eina_streq(part, "background"))
2821 {
2822 if (efl_layout_group_part_exist_get(wd->resize_obj, "efl.background"))
2823 type = efl_canvas_layout_part_type_get(efl_part(wd->resize_obj, "efl.background"));
2824 if (type != EFL_CANVAS_LAYOUT_PART_TYPE_SWALLOW)
2825 {
2826 if (type < EFL_CANVAS_LAYOUT_PART_TYPE_LAST &&
2827 type > EFL_CANVAS_LAYOUT_PART_TYPE_NONE)
2828 {
2829 const char *file = NULL, *key = NULL;
2830 efl_file_simple_get(wd->resize_obj, &file, &key);
2831 WRN("Layout has a background but it's not a swallow: '%s'",
2832 elm_widget_theme_element_get(obj));
2833 }
2834 return efl_part_get(efl_super(obj, MY_CLASS), part);
2835 }
2836
2837 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_BG_CLASS, obj, part);
2838 }
2839 else if (eina_streq(part, "shadow"))
2840 return efl_part_get(efl_super(obj, MY_CLASS), part);
2841 }
2842
2843 if (!efl_layout_group_part_exist_get(wd->resize_obj, part))
2844 {
2845 // edje part will handle the error message
2846 return efl_part_get(wd->resize_obj, part);
2847 }
2848
2849 type = efl_canvas_layout_part_type_get(efl_part(wd->resize_obj, part));
2850 if (type >= EFL_CANVAS_LAYOUT_PART_TYPE_LAST)
2851 {
2852 ERR("Invalid type found for part '%s' in group '%s'",
2853 part, elm_widget_theme_element_get(obj));
2854 return NULL;
2855 }
2856
2857 switch (type)
2858 {
2859 case EFL_CANVAS_LAYOUT_PART_TYPE_BOX:
2860 case EFL_CANVAS_LAYOUT_PART_TYPE_TABLE:
2861 return _efl_ui_layout_pack_proxy_get((Eo *) obj, (Edje_Part_Type)type, part);
2862 case EFL_CANVAS_LAYOUT_PART_TYPE_TEXT:
2863 case EFL_CANVAS_LAYOUT_PART_TYPE_TEXTBLOCK:
2864 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_TEXT_CLASS, obj, part);
2865 case EFL_CANVAS_LAYOUT_PART_TYPE_SWALLOW:
2866 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CONTENT_CLASS, obj, part);
2867 default:
2868 return ELM_PART_IMPLEMENT(EFL_UI_LAYOUT_PART_CLASS, obj, part);
2869 }
2870 }
2871
2872 static const char *
_efl_ui_layout_base_default_content_part_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED)2873 _efl_ui_layout_base_default_content_part_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED)
2874 {
2875 const char *part = NULL;
2876 if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_FALSE))
2877 return NULL;
2878 return part;
2879 }
2880
2881 static const char *
_efl_ui_layout_base_default_text_part_get(const Eo * obj,Efl_Ui_Layout_Data * sd EINA_UNUSED)2882 _efl_ui_layout_base_default_text_part_get(const Eo *obj, Efl_Ui_Layout_Data *sd EINA_UNUSED)
2883 {
2884 const char *part = NULL;
2885 if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE))
2886 return NULL;
2887 return part;
2888 }
2889
2890 #define CONTENT_FULL(part_typename, typename, CLASS, TYPENAME) \
2891 ELM_PART_OVERRIDE_CONTENT_GET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2892 ELM_PART_OVERRIDE_CONTENT_SET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2893 ELM_PART_OVERRIDE_CONTENT_UNSET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME))
2894
2895
2896 #define TEXT_FULL(part_typename, typename, CLASS, TYPENAME) \
2897 ELM_PART_OVERRIDE_TEXT_TEXT_GET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2898 ELM_PART_OVERRIDE_TEXT_TEXT_SET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2899
2900
2901 #define MARKUP_FULL(part_typename, typename, CLASS, TYPENAME) \
2902 ELM_PART_OVERRIDE_TEXT_MARKUP_GET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2903 ELM_PART_OVERRIDE_TEXT_MARKUP_SET_FULL(part_typename, typename, ELM_PART_OVERRIDE_INTERNALS_FETCH(CLASS, TYPENAME)) \
2904
2905 /* Efl.Ui.Layout_Part_Content */
CONTENT_FULL(efl_ui_layout_part_content,efl_ui_layout,EFL_UI_LAYOUT_BASE,Efl_Ui_Layout_Data)2906 CONTENT_FULL(efl_ui_layout_part_content, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2907
2908 /* Efl.Ui.Layout_Part_Text */
2909 TEXT_FULL(efl_ui_layout_part_text, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2910 MARKUP_FULL(efl_ui_layout_part_text, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2911
2912 EOLIAN static const char *
2913 _efl_ui_layout_part_text_efl_ui_l10n_l10n_text_get(const Eo *obj, void *_pd EINA_UNUSED, const char **domain)
2914 {
2915 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
2916 return elm_widget_part_translatable_text_get(pd->obj, pd->part, domain);
2917 }
2918
2919 EOLIAN static void
_efl_ui_layout_part_text_efl_ui_l10n_l10n_text_set(Eo * obj,void * _pd EINA_UNUSED,const char * label,const char * domain)2920 _efl_ui_layout_part_text_efl_ui_l10n_l10n_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *label, const char *domain)
2921 {
2922 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
2923 elm_widget_part_translatable_text_set(pd->obj, pd->part, label, domain);
2924 }
2925
2926 /* Efl.Ui.Layout_Part_Legacy */
CONTENT_FULL(efl_ui_layout_part_legacy,efl_ui_layout,EFL_UI_LAYOUT_BASE,Efl_Ui_Layout_Data)2927 CONTENT_FULL(efl_ui_layout_part_legacy, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2928 TEXT_FULL(efl_ui_layout_part_legacy, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2929 MARKUP_FULL(efl_ui_layout_part_legacy, efl_ui_layout, EFL_UI_LAYOUT_BASE, Efl_Ui_Layout_Data)
2930
2931 EOLIAN static const char *
2932 _efl_ui_layout_part_legacy_efl_ui_l10n_l10n_text_get(const Eo *obj, void *_pd EINA_UNUSED, const char **domain)
2933 {
2934 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
2935 return elm_widget_part_translatable_text_get(pd->obj, pd->part, domain);
2936 }
2937
2938 EOLIAN static void
_efl_ui_layout_part_legacy_efl_ui_l10n_l10n_text_set(Eo * obj,void * _pd EINA_UNUSED,const char * label,const char * domain)2939 _efl_ui_layout_part_legacy_efl_ui_l10n_l10n_text_set(Eo *obj, void *_pd EINA_UNUSED, const char *label, const char *domain)
2940 {
2941 Elm_Part_Data *pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
2942 elm_widget_part_translatable_text_set(pd->obj, pd->part, label, domain);
2943 }
2944
2945 /* Efl.Ui.Layout_Part_Bg (common) */
2946
2947 EOLIAN static Efl_Object *
_efl_ui_layout_part_bg_efl_object_finalize(Eo * obj,void * _pd EINA_UNUSED)2948 _efl_ui_layout_part_bg_efl_object_finalize(Eo *obj, void *_pd EINA_UNUSED)
2949 {
2950 Efl_Ui_Layout_Data *sd;
2951 Elm_Part_Data *pd;
2952 Eo *bg;
2953
2954 obj = efl_finalize(efl_super(obj, EFL_UI_LAYOUT_PART_BG_CLASS));
2955 if (!obj) return NULL;
2956
2957 pd = efl_data_scope_get(obj, EFL_UI_WIDGET_PART_CLASS);
2958 sd = efl_data_scope_get(pd->obj, MY_CLASS);
2959 bg = _efl_ui_widget_bg_get(pd->obj);
2960 if (!_efl_ui_layout_content_set(pd->obj, sd, "efl.background", bg))
2961 {
2962 ERR("Failed to swallow new background object!");
2963 // Shouldn't happen. What now? del bg? call super? return null?
2964 }
2965
2966 return obj;
2967 }
2968
2969 EOLIAN static void
_efl_ui_layout_base_automatic_theme_rotation_set(Eo * obj,Efl_Ui_Layout_Data * pd,Eina_Bool automatic)2970 _efl_ui_layout_base_automatic_theme_rotation_set(Eo *obj, Efl_Ui_Layout_Data *pd, Eina_Bool automatic)
2971 {
2972 if (pd->automatic_orientation_apply == automatic) return;
2973 pd->automatic_orientation_apply = automatic;
2974
2975 efl_ui_layout_theme_rotation_apply(obj, efl_ui_win_rotation_get(elm_widget_top_get(obj)));
2976 }
2977
2978 EOLIAN static Eina_Bool
_efl_ui_layout_base_automatic_theme_rotation_get(const Eo * obj EINA_UNUSED,Efl_Ui_Layout_Data * pd)2979 _efl_ui_layout_base_automatic_theme_rotation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd)
2980 {
2981 return pd->automatic_orientation_apply;
2982 }
2983
2984 EOLIAN static void
_efl_ui_layout_base_theme_rotation_apply(Eo * obj,Efl_Ui_Layout_Data * pd EINA_UNUSED,int orientation)2985 _efl_ui_layout_base_theme_rotation_apply(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, int orientation)
2986 {
2987 char prefix[4], buf[128];
2988
2989 if (elm_widget_is_legacy(obj))
2990 snprintf(prefix, sizeof(prefix), "elm");
2991 else
2992 snprintf(prefix, sizeof(prefix), "efl");
2993 snprintf(buf, sizeof(buf), "%s,state,orient,%d", prefix, (int)orientation);
2994 efl_layout_signal_emit(obj, buf, prefix);
2995 }
2996
2997
2998 /* Efl.Ui.Layout_Part_Xxx includes */
2999 #include "efl_ui_layout_part.eo.c"
3000 #include "efl_ui_layout_part_content.eo.c"
3001 #include "efl_ui_layout_part_bg.eo.c"
3002 #include "efl_ui_layout_part_text.eo.c"
3003 #include "efl_ui_layout_part_legacy.eo.c"
3004
3005 /* Efl.Part end */
3006
3007
3008 /* Internal EO APIs and hidden overrides */
3009 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_object_event_callback_priority_add(Eo * obj,Efl_Ui_Layout_Data * pd,const Efl_Event_Description * desc,Efl_Callback_Priority priority,Efl_Event_Cb func,const void * user_data)3010 _efl_ui_layout_base_efl_object_event_callback_priority_add(Eo *obj, Efl_Ui_Layout_Data *pd, const Efl_Event_Description *desc, Efl_Callback_Priority priority, Efl_Event_Cb func, const void *user_data)
3011 {
3012 if (desc == EFL_UI_LAYOUT_EVENT_THEME_CHANGED)
3013 {
3014 pd->cb_theme_changed = EINA_TRUE;
3015 }
3016
3017 return efl_event_callback_priority_add(efl_super(obj, MY_CLASS), desc, priority, func, user_data);
3018 }
3019
3020 EOLIAN static Eina_Bool
_efl_ui_layout_base_efl_object_event_callback_array_priority_add(Eo * obj,Efl_Ui_Layout_Data * pd,const Efl_Callback_Array_Item * array,Efl_Callback_Priority priority,const void * user_data)3021 _efl_ui_layout_base_efl_object_event_callback_array_priority_add(Eo *obj, Efl_Ui_Layout_Data *pd, const Efl_Callback_Array_Item *array, Efl_Callback_Priority priority, const void *user_data)
3022 {
3023 for (int i = 0; array[i].desc; ++i)
3024 {
3025 if (array[i].desc == EFL_UI_LAYOUT_EVENT_THEME_CHANGED)
3026 {
3027 pd->cb_theme_changed = EINA_TRUE;
3028 }
3029 }
3030 return efl_event_callback_array_priority_add(efl_super(obj, MY_CLASS), array, priority, user_data);
3031 }
3032
EFL_FUNC_BODY_CONST(efl_ui_layout_text_aliases_get,const Elm_Layout_Part_Alias_Description *,NULL)3033 EFL_FUNC_BODY_CONST(efl_ui_layout_text_aliases_get, const Elm_Layout_Part_Alias_Description *, NULL)
3034 EFL_FUNC_BODY_CONST(efl_ui_layout_content_aliases_get, const Elm_Layout_Part_Alias_Description *, NULL)
3035
3036 EFL_UI_LAYOUT_CONTENT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
3037 EFL_UI_LAYOUT_TEXT_ALIASES_IMPLEMENT(MY_CLASS_PFX)
3038
3039 #define EFL_UI_LAYOUT_BASE_EXTRA_OPS \
3040 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_layout_base), \
3041 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_layout_base), \
3042 ELM_PART_TEXT_DEFAULT_OPS(efl_ui_layout_base), \
3043 EFL_UI_LAYOUT_CONTENT_ALIASES_OPS(MY_CLASS_PFX), \
3044 EFL_UI_LAYOUT_TEXT_ALIASES_OPS(MY_CLASS_PFX), \
3045 EFL_OBJECT_OP_FUNC(efl_event_callback_priority_add, _efl_ui_layout_base_efl_object_event_callback_priority_add), \
3046 EFL_OBJECT_OP_FUNC(efl_event_callback_array_priority_add, _efl_ui_layout_base_efl_object_event_callback_array_priority_add), \
3047 EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_layout_base_efl_object_dbg_info_get)
3048
3049
3050 #include "efl_ui_layout_base.eo.c"
3051 #include "efl_ui_layout.eo.c"
3052
3053 #include "efl_ui_layout_legacy_eo.h"
3054
3055
3056 EOLIAN static Eo *
3057 _efl_ui_layout_legacy_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
3058 {
3059 obj = efl_constructor(efl_super(obj, EFL_UI_LAYOUT_LEGACY_CLASS));
3060 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
3061 return obj;
3062 }
3063
3064 EAPI Evas_Object *
elm_layout_add(Evas_Object * parent)3065 elm_layout_add(Evas_Object *parent)
3066 {
3067 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
3068 return elm_legacy_add(EFL_UI_LAYOUT_LEGACY_CLASS, parent);
3069 }
3070
3071 EAPI Eina_Bool
elm_layout_file_set(Eo * obj,const char * file,const char * group)3072 elm_layout_file_set(Eo *obj, const char *file, const char *group)
3073 {
3074 return efl_file_simple_load((Eo *) obj, file, group);
3075 }
3076
3077 EAPI void
elm_layout_file_get(Eo * obj,const char ** file,const char ** group)3078 elm_layout_file_get(Eo *obj, const char **file, const char **group)
3079 {
3080 efl_file_simple_get((Eo *) obj, file, group);
3081 }
3082
3083 EAPI Eina_Bool
elm_layout_mmap_set(Eo * obj,const Eina_File * file,const char * group)3084 elm_layout_mmap_set(Eo *obj, const Eina_File *file, const char *group)
3085 {
3086 return efl_file_simple_mmap_load((Eo *) obj, file, group);
3087 }
3088
3089 EAPI void
elm_layout_mmap_get(Eo * obj,const Eina_File ** file,const char ** group)3090 elm_layout_mmap_get(Eo *obj, const Eina_File **file, const char **group)
3091 {
3092 efl_file_simple_mmap_get((Eo *) obj, file, group);
3093 }
3094
3095 EAPI Eina_Bool
elm_layout_box_append(Eo * obj,const char * part,Evas_Object * child)3096 elm_layout_box_append(Eo *obj, const char *part, Evas_Object *child)
3097 {
3098 return efl_pack(efl_part(obj, part), child);
3099 }
3100
3101 EAPI Eina_Bool
elm_layout_box_prepend(Eo * obj,const char * part,Evas_Object * child)3102 elm_layout_box_prepend(Eo *obj, const char *part, Evas_Object *child)
3103 {
3104 return efl_pack_begin(efl_part(obj, part), child);
3105 }
3106
3107 EAPI Eina_Bool
elm_layout_box_insert_before(Eo * obj,const char * part,Evas_Object * child,const Evas_Object * reference)3108 elm_layout_box_insert_before(Eo *obj, const char *part, Evas_Object *child, const Evas_Object *reference)
3109 {
3110 return efl_pack_before(efl_part(obj, part), child, reference);
3111 }
3112
3113 EAPI Eina_Bool
elm_layout_box_insert_at(Eo * obj,const char * part,Evas_Object * child,unsigned int pos)3114 elm_layout_box_insert_at(Eo *obj, const char *part, Evas_Object *child, unsigned int pos)
3115 {
3116 return efl_pack_at(efl_part(obj, part), child, pos);
3117 }
3118
3119 EAPI Evas_Object *
elm_layout_box_remove(Eo * obj,const char * part,Evas_Object * child)3120 elm_layout_box_remove(Eo *obj, const char *part, Evas_Object *child)
3121 {
3122 if (!efl_pack_unpack(efl_part(obj, part), child))
3123 return NULL;
3124 return child;
3125 }
3126
3127 EAPI Eina_Bool
elm_layout_box_remove_all(Eo * obj,const char * part,Eina_Bool clear)3128 elm_layout_box_remove_all(Eo *obj, const char *part, Eina_Bool clear)
3129 {
3130 if (clear)
3131 return efl_pack_clear(efl_part(obj, part));
3132 else
3133 return efl_pack_unpack_all(efl_part(obj, part));
3134 }
3135
3136 EAPI Eina_Bool
elm_layout_table_pack(Eo * obj,const char * part,Evas_Object * child,unsigned short col,unsigned short row,unsigned short colspan,unsigned short rowspan)3137 elm_layout_table_pack(Eo *obj, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
3138 {
3139 return efl_pack_table(efl_part(obj, part), child, col, row, colspan, rowspan);
3140 }
3141
3142 EAPI Evas_Object *
elm_layout_table_unpack(Eo * obj,const char * part,Evas_Object * child)3143 elm_layout_table_unpack(Eo *obj, const char *part, Evas_Object *child)
3144 {
3145 if (!efl_pack_unpack(efl_part(obj, part), child))
3146 return NULL;
3147 return child;
3148 }
3149
3150 EAPI Eina_Bool
elm_layout_table_clear(Eo * obj,const char * part,Eina_Bool clear)3151 elm_layout_table_clear(Eo *obj, const char *part, Eina_Bool clear)
3152 {
3153 if (clear)
3154 return efl_pack_clear(efl_part(obj, part));
3155 else
3156 return efl_pack_unpack_all(efl_part(obj, part));
3157 }
3158
3159 EAPI Eina_Bool
elm_layout_text_set(Eo * obj,const char * part,const char * text)3160 elm_layout_text_set(Eo *obj, const char *part, const char *text)
3161 {
3162 Eo *part_obj;
3163
3164 if (efl_invalidating_get(obj) || efl_invalidated_get(obj)) return EINA_FALSE;
3165
3166 if (!part)
3167 {
3168 part = efl_ui_widget_default_text_part_get(obj);
3169 if (!part) return EINA_FALSE;
3170 }
3171 else if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE))
3172 return EINA_FALSE;
3173
3174 part_obj = efl_ref(efl_part(obj, part));
3175
3176 if (!efl_isa(part_obj, EFL_TEXT_INTERFACE) ||
3177 !efl_isa(part_obj, EFL_UI_LAYOUT_PART_CLASS))
3178 {
3179 efl_unref(part_obj);
3180 return EINA_FALSE;
3181 }
3182
3183 efl_text_set(part_obj, text);
3184
3185 efl_unref(part_obj);
3186
3187 return EINA_TRUE;
3188 }
3189
3190 EAPI const char *
elm_layout_text_get(const Eo * obj,const char * part)3191 elm_layout_text_get(const Eo *obj, const char *part)
3192 {
3193 if (!part)
3194 {
3195 part = efl_ui_widget_default_text_part_get(obj);
3196 if (!part) return NULL;
3197 }
3198 else if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE))
3199 return NULL;
3200
3201 return efl_text_get(efl_part(obj, part));
3202 }
3203
3204 EAPI Eina_Bool
elm_layout_part_cursor_engine_only_set(Eo * obj,const char * part,Eina_Bool engine_only)3205 elm_layout_part_cursor_engine_only_set(Eo *obj, const char *part, Eina_Bool engine_only)
3206 {
3207 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3208 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
3209 return _efl_ui_layout_part_cursor_engine_only_set(sd, part, engine_only);
3210 }
3211
3212 EAPI Eina_Bool
elm_layout_part_cursor_engine_only_get(const Eo * obj,const char * part)3213 elm_layout_part_cursor_engine_only_get(const Eo *obj, const char *part)
3214 {
3215 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3216 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
3217 return _efl_ui_layout_part_cursor_engine_only_get(sd, part);
3218 }
3219
3220 EAPI Eina_Bool
elm_layout_part_cursor_set(Eo * obj,const char * part,const char * cursor)3221 elm_layout_part_cursor_set(Eo *obj, const char *part, const char *cursor)
3222 {
3223 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3224 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
3225 return _efl_ui_layout_part_cursor_set(sd, part, cursor);
3226 }
3227
3228 EAPI const char *
elm_layout_part_cursor_get(const Eo * obj,const char * part)3229 elm_layout_part_cursor_get(const Eo *obj, const char *part)
3230 {
3231 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3232 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL);
3233 return _efl_ui_layout_part_cursor_get(sd, part);
3234 }
3235
3236 EAPI Eina_Bool
elm_layout_part_cursor_style_set(Eo * obj,const char * part,const char * style)3237 elm_layout_part_cursor_style_set(Eo *obj, const char *part, const char *style)
3238 {
3239 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3240 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
3241 return _efl_ui_layout_part_cursor_style_set(sd, part, style);
3242 }
3243
3244 EAPI const char *
elm_layout_part_cursor_style_get(const Eo * obj,const char * part)3245 elm_layout_part_cursor_style_get(const Eo *obj, const char *part)
3246 {
3247 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3248 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL);
3249 return _efl_ui_layout_part_cursor_style_get(sd, part);
3250 }
3251
3252 EAPI Eina_Bool
elm_layout_part_cursor_unset(Eo * obj,const char * part)3253 elm_layout_part_cursor_unset(Eo *obj, const char *part)
3254 {
3255 Efl_Ui_Layout_Data *sd = efl_data_scope_get(obj, MY_CLASS);
3256 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
3257 return _efl_ui_layout_part_cursor_set(sd, part, NULL);
3258 }
3259
3260 EAPI int
elm_layout_freeze(Evas_Object * obj)3261 elm_layout_freeze(Evas_Object *obj)
3262 {
3263 return efl_layout_calc_freeze(obj);
3264 }
3265
3266 EAPI int
elm_layout_thaw(Evas_Object * obj)3267 elm_layout_thaw(Evas_Object *obj)
3268 {
3269 return efl_layout_calc_thaw(obj);
3270 }
3271
3272 void
_elm_layout_signal_callback_add_legacy(Eo * obj,Eo * edje,Eina_List ** p_edje_signals,const char * emission,const char * source,Edje_Signal_Cb func,void * data)3273 _elm_layout_signal_callback_add_legacy(Eo *obj, Eo *edje, Eina_List **p_edje_signals,
3274 const char *emission, const char *source,
3275 Edje_Signal_Cb func, void *data)
3276 {
3277 Edje_Signal_Data *esd;
3278
3279 esd = ELM_NEW(Edje_Signal_Data);
3280 if (!esd) return;
3281
3282 esd->obj = obj;
3283 esd->func = func;
3284 esd->emission = eina_stringshare_add(emission);
3285 esd->source = eina_stringshare_add(source);
3286 esd->data = data;
3287 *p_edje_signals = eina_list_append(*p_edje_signals, esd);
3288
3289 edje_object_signal_callback_add(edje, emission, source,
3290 _edje_signal_callback, esd);
3291 }
3292
3293 /* replicated from elm_layout just because legacy widget's icon spot
3294 * is elm.swallow.content, not elm.swallow.icon.
3295 */
3296 void
_elm_layout_legacy_icon_signal_emit(Evas_Object * obj)3297 _elm_layout_legacy_icon_signal_emit(Evas_Object *obj)
3298 {
3299 char buf[63];
3300 Eo *edje;
3301
3302 edje = elm_layout_edje_get(obj);
3303 if (!edje) return;
3304 if (!edje_object_part_exists(obj, "elm.swallow.content")) return;
3305 snprintf(buf, sizeof(buf), "elm,state,icon,%s",
3306 elm_layout_content_get(obj, "icon") ? "visible" : "hidden");
3307
3308 elm_layout_signal_emit(obj, buf, "elm");
3309 edje_object_message_signal_process(edje);
3310 efl_canvas_group_change(obj);
3311 }
3312
3313 EAPI void
elm_layout_signal_callback_add(Eo * obj,const char * emission,const char * source,Edje_Signal_Cb func,void * data)3314 elm_layout_signal_callback_add(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
3315 {
3316 Efl_Ui_Layout_Data *sd;
3317
3318 if (!emission || !source) return;
3319
3320 if (efl_isa(obj, ELM_ENTRY_CLASS))
3321 {
3322 _elm_entry_signal_callback_add_legacy(obj, emission, source, func, data);
3323 return;
3324 }
3325
3326 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3327 if (!sd) return;
3328 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
3329
3330 _elm_layout_signal_callback_add_legacy(obj, wd->resize_obj, &sd->edje_signals,
3331 emission, source, func, data);
3332 }
3333
3334 void *
_elm_layout_signal_callback_del_legacy(Eo * obj EINA_UNUSED,Eo * edje,Eina_List ** p_edje_signals,const char * emission,const char * source,Edje_Signal_Cb func)3335 _elm_layout_signal_callback_del_legacy(Eo *obj EINA_UNUSED, Eo *edje, Eina_List **p_edje_signals,
3336 const char *emission, const char *source,
3337 Edje_Signal_Cb func)
3338 {
3339 Edje_Signal_Data *esd = NULL;
3340 void *data = NULL;
3341 Eina_List *l;
3342
3343 if (!emission || !source) return NULL;
3344
3345 EINA_LIST_FOREACH(*p_edje_signals, l, esd)
3346 {
3347 if ((esd->func == func) && (!strcmp(esd->emission, emission)) &&
3348 (!strcmp(esd->source, source)))
3349 {
3350 *p_edje_signals = eina_list_remove_list(*p_edje_signals, l);
3351
3352 edje_object_signal_callback_del_full(edje, emission, source,
3353 _edje_signal_callback, esd);
3354
3355 eina_stringshare_del(esd->emission);
3356 eina_stringshare_del(esd->source);
3357 data = esd->data;
3358 free(esd);
3359
3360 return data; /* stop at 1st match */
3361 }
3362 }
3363
3364 return NULL;
3365 }
3366
3367 EAPI void *
elm_layout_signal_callback_del(Eo * obj,const char * emission,const char * source,Edje_Signal_Cb func)3368 elm_layout_signal_callback_del(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func)
3369 {
3370 Efl_Ui_Layout_Data *sd;
3371
3372 if (!emission || !source) return NULL;
3373
3374 if (efl_isa(obj, ELM_ENTRY_CLASS))
3375 return _elm_entry_signal_callback_del_legacy(obj, emission, source, func);
3376
3377 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3378 if (!sd) return NULL;
3379 ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
3380
3381 return _elm_layout_signal_callback_del_legacy(obj, wd->resize_obj, &sd->edje_signals,
3382 emission, source, func);
3383 }
3384
3385 EAPI void
elm_layout_signal_emit(Eo * obj,const char * emission,const char * source)3386 elm_layout_signal_emit(Eo *obj, const char *emission, const char *source)
3387 {
3388 efl_layout_signal_emit(obj, emission, source);
3389 }
3390
3391 EAPI const char *
elm_layout_data_get(const Evas_Object * obj,const char * key)3392 elm_layout_data_get(const Evas_Object *obj, const char *key)
3393 {
3394 return efl_layout_group_data_get(obj, key);
3395 }
3396
3397 EAPI Eina_Bool
elm_layout_theme_set(Evas_Object * obj,const char * klass,const char * group,const char * style)3398 elm_layout_theme_set(Evas_Object *obj, const char *klass, const char *group, const char *style)
3399 {
3400 Eina_Error theme_apply_ret;
3401
3402 theme_apply_ret = efl_ui_layout_theme_set(obj, klass, group, style);
3403 return (theme_apply_ret != EFL_UI_THEME_APPLY_ERROR_GENERIC);
3404 }
3405
3406 #include "efl_ui_layout_legacy_eo.c"
3407