jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=e7f0b64860b3028ba0d5cac7aa0077e864c4cc70
commit e7f0b64860b3028ba0d5cac7aa0077e864c4cc70 Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Mon Apr 25 21:36:56 2016 +0900 Elm.Layout: Replace box & table part API by fake object This moves the part_box and part_table APIs to a fake object like was done in Edje Object. This also adds support a few new APIs to those containers, so they behave exactly like Edje.Object. This is another implementation bit of "eo_part". --- src/Makefile_Elementary.am | 3 + src/lib/elementary/Makefile.am | 27 +- src/lib/elementary/efl_ui_layout_internal_box.eo | 40 ++ src/lib/elementary/efl_ui_layout_internal_table.eo | 37 ++ src/lib/elementary/elm_layout.c | 126 ++++++- src/lib/elementary/elm_layout.eo | 148 -------- src/lib/elementary/elm_layout_legacy.h | 140 +++++++ src/lib/elementary/elm_layout_pack.c | 418 +++++++++++++++++++++ 8 files changed, 770 insertions(+), 169 deletions(-) diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 231b0f7..49de9e3 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -118,6 +118,8 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_box.eo \ lib/elementary/efl_ui_box_flow.eo \ lib/elementary/efl_ui_grid.eo \ + lib/elementary/efl_ui_layout_internal_box.eo \ + lib/elementary/efl_ui_layout_internal_table.eo \ $(NULL) # Legacy classes - not part of public EO API @@ -583,6 +585,7 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/elm_inwin.c \ lib/elementary/elm_label.c \ lib/elementary/elm_layout.c \ + lib/elementary/elm_layout_pack.c \ lib/elementary/elm_list.c \ lib/elementary/elm_main.c \ lib/elementary/elm_map.c \ diff --git a/src/lib/elementary/Makefile.am b/src/lib/elementary/Makefile.am index 446bf17..e84ac65 100644 --- a/src/lib/elementary/Makefile.am +++ b/src/lib/elementary/Makefile.am @@ -23,7 +23,6 @@ elm_eolian_files = \ elm_colorselector.eo \ elm_combobox.eo \ elm_conformant.eo \ - elm_container.eo \ elm_ctxpopup.eo \ elm_datetime.eo \ elm_dayselector.eo \ @@ -121,7 +120,13 @@ elm_eolian_files = \ elm_list_item.eo \ elm_toolbar_item.eo \ elm_diskselector_item.eo \ - elm_popup_item.eo + elm_popup_item.eo \ + efl_ui_box.eo \ + efl_ui_box_flow.eo \ + efl_ui_grid.eo \ + efl_ui_layout_internal_box.eo \ + efl_ui_layout_internal_table.eo \ + $(NULL) elm_eolian_type_files = \ elm_general.eot @@ -276,7 +281,6 @@ includesub_HEADERS = \ elm_bg_eo.h \ elm_bg_legacy.h \ elm_box.h \ - elm_box_eo.h \ elm_box_legacy.h \ elm_box_common.h \ elm_bubble.h \ @@ -306,7 +310,6 @@ includesub_HEADERS = \ elm_conform.h \ elm_conform_eo.h \ elm_conform_legacy.h \ - elm_container.h \ elm_cursor.h \ elm_datetime.h \ elm_datetime_common.h \ @@ -358,7 +361,6 @@ includesub_HEADERS = \ elm_glview_eo.h \ elm_glview_legacy.h \ elm_grid.h \ - elm_grid_eo.h \ elm_grid_legacy.h \ elm_hover.h \ elm_hover_eo.h \ @@ -466,7 +468,6 @@ includesub_HEADERS = \ elm_systray_watcher.h \ elm_sys_notify.h \ elm_table.h \ - elm_table_eo.h \ elm_table_legacy.h \ elm_theme.h \ elm_thumb.h \ @@ -493,7 +494,10 @@ includesub_HEADERS = \ elm_win_eo.h \ elm_win_legacy.h \ elm_win_standard.h \ - elm_helper.h + elm_helper.h \ + efl_ui_box_private.h \ + $(NULL) + includesubdir = $(includedir)/elementary-@VMAJ@/ libelementary_la_SOURCES = \ @@ -534,7 +538,6 @@ libelementary_la_SOURCES = \ elc_combobox.c \ elm_config.c \ elm_conform.c \ - elm_container.c \ elm_datetime.c \ elm_dayselector.c \ elm_dbus_menu.c \ @@ -569,6 +572,7 @@ libelementary_la_SOURCES = \ elm_inwin.c \ elm_label.c \ elm_layout.c \ + elm_layout_pack.c \ elm_list.c \ elm_main.c \ elm_map.c \ @@ -618,7 +622,12 @@ libelementary_la_SOURCES = \ els_box.c \ els_cursor.c \ els_tooltip.c \ - elu_ews_wm.c + elu_ews_wm.c \ + efl_ui_box.c \ + efl_ui_box_flow.c \ + efl_ui_box_layout.c \ + efl_ui_grid.c \ + $(NULL) libelementary_la_CFLAGS = @ELEMENTARY_CFLAGS@ libelementary_la_LIBADD = @ELEMENTARY_SUBBUILD_LIBS@ @LTLIBINTL@ diff --git a/src/lib/elementary/efl_ui_layout_internal_box.eo b/src/lib/elementary/efl_ui_layout_internal_box.eo new file mode 100644 index 0000000..3efb952 --- /dev/null +++ b/src/lib/elementary/efl_ui_layout_internal_box.eo @@ -0,0 +1,40 @@ +class Efl.Ui.Layout_Internal.Box (Eo.Base, Efl.Pack_Linear) +{ + [[Represents a Box created as part of a layout. + + Can not be deleted, this is only a representation of an internal object + of an EFL layout. + ]] + legacy_prefix: null; + data: Efl_Ui_Layout_Table_Data; + methods { + @property real_part @protected { + set {} + values { + layout: Eo.Base*; + pack: Eo.Base*; + part: const(char)*; + } + } + } + implements { + Eo.Base.finalize; + Eo.Base.destructor; + Efl.Container.content_iterate; + Efl.Container.content_count; + Efl.Container.content_remove; + Efl.Pack.pack_clear; + Efl.Pack.unpack_all; + Efl.Pack.unpack; + Efl.Pack.pack; + Efl.Pack_Linear.pack_begin; + Efl.Pack_Linear.pack_end; + Efl.Pack_Linear.pack_before; + Efl.Pack_Linear.pack_after; + Efl.Pack_Linear.pack_insert; + Efl.Pack_Linear.content_at.get; + Efl.Pack_Linear.content_at_remove; + Efl.Pack_Linear.content_index.get; + Efl.Pack_Linear.direction.get; + } +} diff --git a/src/lib/elementary/efl_ui_layout_internal_table.eo b/src/lib/elementary/efl_ui_layout_internal_table.eo new file mode 100644 index 0000000..19c9bba --- /dev/null +++ b/src/lib/elementary/efl_ui_layout_internal_table.eo @@ -0,0 +1,37 @@ +class Efl.Ui.Layout_Internal.Table (Eo.Base, Efl.Pack_Grid) +{ + [[Represents a Table created as part of a layout. + + Can not be deleted, this is only a representation of an internal object + of an EFL layout. + ]] + legacy_prefix: null; + data: Efl_Ui_Layout_Table_Data; + methods { + @property real_part @protected { + set {} + values { + layout: Eo.Base*; + pack: Eo.Base*; + part: const(char)*; + } + } + } + implements { + Eo.Base.finalize; + Eo.Base.destructor; + Efl.Container.content_iterate; + Efl.Container.content_count; + Efl.Container.content_remove; + Efl.Pack.pack_clear; + Efl.Pack.unpack_all; + Efl.Pack.unpack; + Efl.Pack_Grid.pack_grid; + Efl.Pack_Grid.grid_content_at; + Efl.Pack_Grid.grid_content_iterate; + Efl.Pack_Grid.grid_content_position.get; + Efl.Pack_Grid.grid_size.get; + Efl.Pack_Grid.grid_columns.get; + Efl.Pack_Grid.grid_rows.get; + } +} diff --git a/src/lib/elementary/elm_layout.c b/src/lib/elementary/elm_layout.c index a886bc7..e3e515f 100644 --- a/src/lib/elementary/elm_layout.c +++ b/src/lib/elementary/elm_layout.c @@ -15,6 +15,8 @@ #define MY_CLASS_NAME "Elm_Layout" #define MY_CLASS_NAME_LEGACY "elm_layout" +Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Evas_Object *pack, const char *part); + static const char SIG_THEME_CHANGED[] = "theme,changed"; const char SIG_LAYOUT_FOCUSED[] = "focused"; const char SIG_LAYOUT_UNFOCUSED[] = "unfocused"; @@ -1052,6 +1054,7 @@ elm_layout_content_get(const Evas_Object *obj, { ELM_LAYOUT_CHECK(obj) NULL; Evas_Object *ret = NULL; + ret = efl_content_get((Eo *) obj, swallow); return ret; } @@ -1067,10 +1070,21 @@ _elm_layout_efl_container_content_get(Eo *obj, Elm_Layout_Smart_Data *sd, const EINA_LIST_FOREACH(sd->subs, l, sub_d) { - if ((sub_d->type == SWALLOW) && !strcmp(part, sub_d->part)) return sub_d->obj; + if ((sub_d->type != TEXT) && !strcmp(part, sub_d->part)) + { + if (sub_d->type == SWALLOW) + return sub_d->obj; + if ((sub_d->type == TABLE_PACK) || _sub_box_is(sub_d)) + return _elm_layout_pack_proxy_get(obj, sub_d->obj, sub_d->part); + } } - return NULL; + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); + + if (!_elm_layout_part_aliasing_eval(obj, sd, &part, EINA_FALSE)) + return NULL; + + return efl_content_get(wd->resize_obj, part); } EAPI Evas_Object * @@ -1135,7 +1149,7 @@ _elm_layout_efl_container_content_remove(Eo *obj, Elm_Layout_Smart_Data *sd EINA edje_object_part_unswallow(wd->resize_obj, content); _eo_unparent_helper(content, obj); - return content; + return EINA_TRUE; } /* legacy only - eo is iterator */ @@ -1310,7 +1324,7 @@ _layout_box_subobj_init(Elm_Layout_Smart_Data *sd, Elm_Layout_Sub_Object_Data *s eo_parent_set(child, sd->obj); } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_box_append(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child) { Elm_Layout_Sub_Object_Data *sub_d; @@ -1347,7 +1361,7 @@ _elm_layout_box_append(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eva return EINA_TRUE; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_box_prepend(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child) { Elm_Layout_Sub_Object_Data *sub_d; @@ -1384,7 +1398,7 @@ _elm_layout_box_prepend(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Ev return EINA_TRUE; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_box_insert_before(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, const Evas_Object *reference) { Elm_Layout_Sub_Object_Data *sub_d; @@ -1426,7 +1440,7 @@ _elm_layout_box_insert_before(Eo *obj, Elm_Layout_Smart_Data *sd, const char *pa return EINA_TRUE; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_box_insert_at(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, unsigned int pos) { Elm_Layout_Sub_Object_Data *sub_d; @@ -1464,7 +1478,7 @@ _elm_layout_box_insert_at(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, return EINA_TRUE; } -EOLIAN static Evas_Object* +Evas_Object * _elm_layout_box_remove(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child) { @@ -1485,7 +1499,7 @@ _elm_layout_box_remove(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eva return NULL; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_box_remove_all(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eina_Bool clear) { EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); @@ -1515,7 +1529,7 @@ _elm_layout_box_remove_all(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, return EINA_TRUE; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_table_pack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) { Elm_Layout_Sub_Object_Data *sub_d; @@ -1562,7 +1576,7 @@ _elm_layout_table_pack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eva return EINA_TRUE; } -EOLIAN static Evas_Object* +Evas_Object * _elm_layout_table_unpack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child) { @@ -1584,7 +1598,7 @@ _elm_layout_table_unpack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, E return NULL; } -EOLIAN static Eina_Bool +Eina_Bool _elm_layout_table_clear(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eina_Bool clear) { EINA_SAFETY_ON_NULL_RETURN_VAL(part, EINA_FALSE); @@ -1885,6 +1899,8 @@ EOLIAN static void _elm_layout_class_constructor(Eo_Class *klass) evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass); } +/* Legacy APIs */ + EAPI Eina_Bool elm_layout_file_set(Eo *obj, const char *file, const char *group) { @@ -1897,4 +1913,90 @@ elm_layout_file_get(Eo *obj, const char **file, const char **group) efl_file_get((Eo *) obj, file, group); } +EAPI Eina_Bool +elm_layout_box_append(Elm_Layout *obj, const char *part, Evas_Object *child) +{ + Eo *box = efl_content_get(obj, part); + if (!box) return EINA_FALSE; + efl_pack(box, child); + return EINA_TRUE; +} + +EAPI Eina_Bool +elm_layout_box_prepend(Elm_Layout *obj, const char *part, Evas_Object *child) +{ + Eo *box = efl_content_get(obj, part); + if (!box) return EINA_FALSE; + efl_pack_begin(box, child); + return EINA_TRUE; +} + +EAPI Eina_Bool +elm_layout_box_insert_before(Elm_Layout *obj, const char *part, Evas_Object *child, const Evas_Object *reference) +{ + return efl_pack_before(efl_content_get(obj, part), child, reference); +} + +EAPI Eina_Bool +elm_layout_box_insert_at(Elm_Layout *obj, const char *part, Evas_Object *child, unsigned int pos) +{ + Eo *box = efl_content_get(obj, part); + if (!box) return EINA_FALSE; + efl_pack_insert(box, child, pos); + return EINA_TRUE; +} + +EAPI Evas_Object * +elm_layout_box_remove(Elm_Layout *obj, const char *part, Evas_Object *child) +{ + Eo *box = efl_content_get(obj, part); + if (!box) return NULL; + if (!efl_pack_unpack(box, child)) + return NULL; + return child; +} + +EAPI Eina_Bool +elm_layout_box_remove_all(Elm_Layout *obj, const char *part, Eina_Bool clear) +{ + Eo *box = efl_content_get(obj, part); + if (!box) return EINA_FALSE; + if (clear) + efl_pack_clear(box); + else + efl_pack_unpack_all(box); + return EINA_TRUE; +} + +EAPI Eina_Bool +elm_layout_table_pack(Elm_Layout *obj, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan) +{ + Eo *table = efl_content_get(obj, part); + if (!table) return EINA_FALSE; + efl_pack_grid(table, child, col, row, colspan, rowspan); + return EINA_TRUE; +} + +EAPI Evas_Object * +elm_layout_table_unpack(Elm_Layout *obj, const char *part, Evas_Object *child) +{ + Eo *table = efl_content_get(obj, part); + if (!table) return NULL; + if (efl_pack_unpack(table, child)) + return child; + return NULL; +} + +EAPI Eina_Bool +elm_layout_table_clear(Elm_Layout *obj, const char *part, Eina_Bool clear) +{ + Eo *table = efl_content_get(obj, part); + if (!table) return EINA_FALSE; + if (clear) + efl_pack_clear(table); + else + efl_pack_unpack_all(table); + return EINA_TRUE; +} + #include "elm_layout.eo.c" diff --git a/src/lib/elementary/elm_layout.eo b/src/lib/elementary/elm_layout.eo index 6ec3f8a..aca8c46 100644 --- a/src/lib/elementary/elm_layout.eo +++ b/src/lib/elementary/elm_layout.eo @@ -96,21 +96,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) settings loaded \@ref elm_layout_file_set.]] } } - box_remove_all { - [[Remove all children of the given part box. - - The objects will be removed from the box part and their lifetime - will not be handled by the layout anymore. This is equivalent to - @.box_remove for all box children. - ]] - return: bool; - params { - @in part: const(char)*; [[The box part name to remove child.]] - @in clear: bool; [[If true, then all objects will be deleted as - well, otherwise they will just be removed and - will be dangling on the canvas.]] - } - } part_cursor_engine_only_set { [[Sets if the cursor set should be searched on the theme or should use the provided by the engine, only. @@ -136,19 +121,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) @in part_name: const(char)*; [[A part from loaded edje group.]] } } - table_unpack { - [[Unpack (remove) a child of the given part table. - - The object will be unpacked from the table part and its lifetime - will not be handled by the layout anymore. This is equivalent to - \@ref elm_layout_content_unset for table. - ]] - return: Evas.Object *; [[The object that was being used, or $null if not found.]] - params { - @in part: const(char)*; [[The table part name to remove child.]] - @in child: Evas.Object *; [[The object to remove from table.]] - } - } freeze { [[Freezes the Elementary layout object. @@ -182,19 +154,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) from the edje object will cause this to happen too. ]] } - box_remove { - [[Remove a child of the given part box. - - The object will be removed from the box part and its lifetime - will not be handled by the layout anymore. This is equivalent to - \@ref elm_layout_content_unset for box. - ]] - return: Evas.Object *; [[The object that was being used, or $null if not found.]] - params { - @in part: const(char)*; [[The box part name to remove child.]] - @in child: Evas.Object *; [[The object to remove from box.]] - } - } sizing_restricted_eval { [[Request sizing reevaluation, restricted to current width and/or height. @@ -278,36 +237,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) @in part_name: const(char)*; [[A part from loaded edje group.]] } } - box_insert_before { - [[Insert child to layout box part before a reference object. - - Once the object is inserted, it will become child of the layout. - Its lifetime will be bound to the layout, whenever the layout - dies the child will be deleted automatically. One should use - @.box_remove to make this layout forget about the object. - ]] - return: bool; - params { - @in part: const(char)*; [[The box part to insert.]] - @in child: own(Evas.Object *); [[The child object to insert into box.]] - @in reference: const(Evas.Object)*; [[Another reference object to insert before in box.]] - } - } - box_insert_at { - [[Insert child to layout box part at a given position. - - Once the object is inserted, it will become child of the layout. - Its lifetime will be bound to the layout, whenever the layout - dies the child will be deleted automatically. One should use - @.box_remove to make this layout forget about the object. - ]] - return: bool; - params { - @in part: const(char)*; [[The box part to insert.]] - @in child: own(Evas.Object *); [[The child object to insert into box.]] - @in pos: uint; [[The numeric position >=0 to insert the child.]] - } - } sub_object_add_enable { legacy: null; return: bool; @@ -339,20 +268,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) @in key: const(char)*; [[The data key.]] } } - box_append { - [[Append child to layout box part. - - Once the object is appended, it will become child of the layout. - Its lifetime will be bound to the layout, whenever the layout - dies the child will be deleted automatically. One should use - @.box_remove to make this layout forget about the object. - ]] - return: bool; - params { - @in part: const(char)*; [[The box part to which the object will be appended.]] - @in child: own(Evas.Object *); [[The child object to append to box.]] - } - } signal_callback_del { [[Remove a signal-triggered callback from a given layout widget. @@ -384,20 +299,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) ]] return: int; [[The frozen state or 0 if the object is not frozen or on error.]] } - box_prepend { - [[Prepend child to layout box part. - - Once the object is prepended, it will become child of the layout. - Its lifetime will be bound to the layout, whenever the layout - dies the child will be deleted automatically. One should use - @.box_remove to make this layout forget about the object. - ]] - return: bool; - params { - @in part: const(char)*; [[The box part to which the object will be prepended.]] - @in child: own(Evas.Object *); [[The child object to prepend to box.]] - } - } signal_emit { [[Send a (Edje) signal to a given layout widget's underlying Edje object. @@ -412,40 +313,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) @in source: const(char)*; [[The signal's source string.]] } } - table_pack { - [[Insert child to layout table part. - - Once the object is inserted, it will become child of the table. - Its lifetime will be bound to the layout, and whenever the layout - dies the child will be deleted automatically. One should use - @.table_unpack to make this layout forget about the object. - - If $colspan or $rowspan are bigger than 1, that object will occupy - more space than a single cell. - - See also @.table_unpack, @.table_clear. - ]] - /* FIXME-doc - For instance, the following code: - @code - elm_layout_table_pack(layout, "table_part", child, 0, 1, 3, 1); - @endcode - - Would result in an object being added like the following picture: - - @image html layout_colspan.png - @image latex layout_colspan.eps width=\textwidth - */ - return: bool; - params { - @in part: const(char)*; [[The box part to pack child.]] - @in child: own(Evas.Object *); [[The child object to pack into table.]] - @in col: ushort; [[The column to which the child should be added. (>= 0)]] - @in row: ushort; [[The row to which the child should be added. (>= 0)]] - @in colspan: ushort; [[How many columns should be used to store this object. (>= 1)]] - @in rowspan: ushort; [[How many rows should be used to store this object. (>= 1)]] - } - } part_cursor_unset { [[Unsets a cursor previously set with @.part_cursor_set.]] return: bool; @@ -455,21 +322,6 @@ class Elm.Layout (Elm.Widget, Efl.Container, Efl.File) @.part_cursor_set.]] } } - table_clear { - [[Remove all the child objects of the given part table. - - The objects will be removed from the table part and their - lifetime will not be handled by the layout anymore. This - is equivalent to @.table_unpack for all table children. - ]] - return: bool; - params { - @in part: const(char)*; [[The table part name to remove child.]] - @in clear: bool; [[If true, then all objects will be deleted as - well, otherwise they will just be removed and - will be dangling on the canvas.]] - } - } } implements { class.constructor; diff --git a/src/lib/elementary/elm_layout_legacy.h b/src/lib/elementary/elm_layout_legacy.h index 539152c..77bf7cc 100644 --- a/src/lib/elementary/elm_layout_legacy.h +++ b/src/lib/elementary/elm_layout_legacy.h @@ -101,4 +101,144 @@ EAPI Eina_Bool elm_layout_file_set(Eo *obj, const char *file, const char *group) */ EAPI void elm_layout_file_get(Eo *obj, const char **file, const char **group); +/** + * @brief Append child to layout box part. + * + * Once the object is appended, it will become child of the layout. Its + * lifetime will be bound to the layout, whenever the layout dies the child + * will be deleted automatically. One should use @ref elm_layout_box_remove to + * make this layout forget about the object. + * + * @param[in] child The child object to append to box. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_box_append(Evas_Object *obj, const char *part, Evas_Object *child); + +/** + * @brief Prepend child to layout box part. + * + * Once the object is prepended, it will become child of the layout. Its + * lifetime will be bound to the layout, whenever the layout dies the child + * will be deleted automatically. One should use @ref elm_layout_box_remove to + * make this layout forget about the object. + * + * @param[in] child The child object to prepend to box. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_box_prepend(Evas_Object *obj, const char *part, Evas_Object *child); + +/** + * @brief Insert child to layout box part before a reference object. + * + * Once the object is inserted, it will become child of the layout. Its + * lifetime will be bound to the layout, whenever the layout dies the child + * will be deleted automatically. One should use @ref elm_layout_box_remove to + * make this layout forget about the object. + * + * @param[in] child The child object to insert into box. + * @param[in] reference Another reference object to insert before in box. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_box_insert_before(Evas_Object *obj, const char *part, Evas_Object *child, const Evas_Object *reference); + +/** + * @brief Insert child to layout box part at a given position. + * + * Once the object is inserted, it will become child of the layout. Its + * lifetime will be bound to the layout, whenever the layout dies the child + * will be deleted automatically. One should use @ref elm_layout_box_remove to + * make this layout forget about the object. + * + * @param[in] child The child object to insert into box. + * @param[in] pos The numeric position >=0 to insert the child. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_box_insert_at(Evas_Object *obj, const char *part, Evas_Object *child, unsigned int pos); + +/** + * @brief Remove a child of the given part box. + * + * The object will be removed from the box part and its lifetime will not be + * handled by the layout anymore. This is equivalent to @ref + * elm_layout_content_unset for box. + * + * @param[in] child The object to remove from box. + * + * @return The object that was being used, or @c null if not found. + * + * @ingroup Elm_Layout + */ +EAPI Evas_Object *elm_layout_box_remove(Evas_Object *obj, const char *part, Evas_Object *child); + +/** + * @brief Remove all children of the given part box. + * + * The objects will be removed from the box part and their lifetime will not be + * handled by the layout anymore. This is equivalent to + * @ref elm_layout_box_remove for all box children. + * + * @param[in] clear If true, then all objects will be deleted as well, + * otherwise they will just be removed and will be dangling on the canvas. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_box_remove_all(Evas_Object *obj, const char *part, Eina_Bool clear); + +/** + * @brief Insert child to layout table part. + * + * Once the object is inserted, it will become child of the table. Its lifetime + * will be bound to the layout, and whenever the layout dies the child will be + * deleted automatically. One should use @ref elm_layout_table_unpack to make + * this layout forget about the object. + * + * If @c colspan or @c rowspan are bigger than 1, that object will occupy more + * space than a single cell. + * + * See also @ref elm_layout_table_unpack, @ref elm_layout_table_clear. + * + * @param[in] child The child object to pack into table. + * @param[in] col The column to which the child should be added. (>= 0) + * @param[in] row The row to which the child should be added. (>= 0) + * @param[in] colspan How many columns should be used to store this object. (>= + * 1) + * @param[in] rowspan How many rows should be used to store this object. (>= 1) + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_table_pack(Evas_Object *obj, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan); + +/** + * @brief Unpack (remove) a child of the given part table. + * + * The object will be unpacked from the table part and its lifetime will not be + * handled by the layout anymore. This is equivalent to @ref + * elm_layout_content_unset for table. + * + * @param[in] child The object to remove from table. + * + * @return The object that was being used, or @c null if not found. + * + * @ingroup Elm_Layout + */ +EAPI Evas_Object *elm_layout_table_unpack(Evas_Object *obj, const char *part, Evas_Object *child); + +/** + * @brief Remove all the child objects of the given part table. + * + * The objects will be removed from the table part and their lifetime will not + * be handled by the layout anymore. This is equivalent to + * @ref elm_layout_table_unpack for all table children. + * + * @param[in] clear If true, then all objects will be deleted as well, + * otherwise they will just be removed and will be dangling on the canvas. + * + * @ingroup Elm_Layout + */ +EAPI Eina_Bool elm_layout_table_clear(Evas_Object *obj, const char *part, Eina_Bool clear); + #include "elm_layout.eo.legacy.h" diff --git a/src/lib/elementary/elm_layout_pack.c b/src/lib/elementary/elm_layout_pack.c new file mode 100644 index 0000000..2b6a234 --- /dev/null +++ b/src/lib/elementary/elm_layout_pack.c @@ -0,0 +1,418 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#define ELM_LAYOUT_PROTECTED +#define EFL_UI_LAYOUT_INTERNAL_BOX_PROTECTED +#define EFL_UI_LAYOUT_INTERNAL_TABLE_PROTECTED + +#include <Elementary.h> + +#include "elm_priv.h" +#include "elm_widget_layout.h" + +#include "efl_ui_layout_internal_box.eo.h" +#include "efl_ui_layout_internal_table.eo.h" +#include "../evas/canvas/evas_box.eo.h" +#include "../evas/canvas/evas_table.eo.h" + +/* layout internals for box & table */ +Eina_Bool _elm_layout_box_append(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child); +Eina_Bool _elm_layout_box_prepend(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child); +Eina_Bool _elm_layout_box_insert_before(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, const Evas_Object *reference); +Eina_Bool _elm_layout_box_insert_at(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, unsigned int pos); +Evas_Object *_elm_layout_box_remove(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child); +Eina_Bool _elm_layout_box_remove_all(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eina_Bool clear); +Eina_Bool _elm_layout_table_pack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan); +Evas_Object *_elm_layout_table_unpack(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Evas_Object *child); +Eina_Bool _elm_layout_table_clear(Eo *obj, Elm_Layout_Smart_Data *sd, const char *part, Eina_Bool clear); + +#define BOX_CLASS EFL_UI_LAYOUT_INTERNAL_BOX_CLASS +#define TABLE_CLASS EFL_UI_LAYOUT_INTERNAL_TABLE_CLASS +#define DATA_KEY "__elm_layout_internal" + +typedef struct _Layout_Part_Data Efl_Ui_Layout_Box_Data; +typedef struct _Layout_Part_Data Efl_Ui_Layout_Table_Data; +typedef struct _Part_Item_Iterator Part_Item_Iterator; + +struct _Layout_Part_Data +{ + Elm_Layout *obj; + Elm_Layout_Smart_Data *sd; + Eina_Stringshare *part; + Evas_Object *pack; +}; + +struct _Part_Item_Iterator +{ + Eina_Iterator iterator; + Eina_List *list; + Eina_Iterator *real_iterator; + Eo *object; +}; + +Eo * +_elm_layout_pack_proxy_get(Elm_Layout *obj, Evas_Object *pack, const char *part) +{ + Efl_Ui_Layout_Internal_Box *eo; + + eo = eo_key_obj_get(pack, DATA_KEY); + if (eo) return eo; + + if (eo_isa(pack, EVAS_BOX_CLASS)) + eo = eo_add(BOX_CLASS, obj, + efl_ui_layout_internal_box_real_part_set(eo_self, obj, pack, part)); + else if (eo_isa(pack, EVAS_TABLE_CLASS)) + eo = eo_add(TABLE_CLASS, obj, + efl_ui_layout_internal_table_real_part_set(eo_self, obj, pack, part)); + else + return NULL; + + eo_key_obj_set(pack, DATA_KEY, eo); + return eo; +} + +EOLIAN static void +_efl_ui_layout_internal_box_real_part_set(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Eo *layout, Eo *pack, const char *part) +{ + pd->obj = layout; + pd->sd = eo_data_scope_get(layout, ELM_LAYOUT_CLASS); + pd->part = part; + pd->pack = pack; +} + +EOLIAN static Eo_Base * +_efl_ui_layout_internal_box_eo_base_finalize(Eo *obj, Efl_Ui_Layout_Box_Data *pd) +{ + EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->obj && pd->part && pd->sd, NULL); + return eo_finalize(eo_super(obj, BOX_CLASS)); +} + +EOLIAN static void +_efl_ui_layout_internal_box_eo_base_destructor(Eo *obj, Efl_Ui_Layout_Box_Data *pd) +{ + eo_key_del(pd->pack, DATA_KEY); + eo_destructor(eo_super(obj, BOX_CLASS)); +} + +/* this iterator is the same as efl_ui_box */ +static Eina_Bool +_part_item_iterator_next(Part_Item_Iterator *it, void **data) +{ + Efl_Gfx_Base *sub; + + if (!it->object) return EINA_FALSE; + if (!eina_iterator_next(it->real_iterator, (void **) &sub)) + return EINA_FALSE; + + if (data) *data = sub; + return EINA_TRUE; +} + +static Eo * +_part_item_iterator_get_container(Part_Item_Iterator *it) +{ + return it->object; +} + +static void +_part_item_iterator_free(Part_Item_Iterator *it) +{ + eina_iterator_free(it->real_iterator); + eo_wref_del(it->object, &it->object); + eina_list_free(it->list); + free(it); +} + +static Eina_Iterator * +_part_item_iterator_create(Eo *obj, Eina_Iterator *real_iterator, Eina_List *list) +{ + Part_Item_Iterator *it; + + it = calloc(1, sizeof(*it)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->list = list; + it->real_iterator = real_iterator; + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_part_item_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_part_item_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_part_item_iterator_free); + eo_wref_add(obj, &it->object); + + return &it->iterator; +} + +EOLIAN static Eina_Iterator * +_efl_ui_layout_internal_box_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Box_Data *pd) +{ + Eina_Iterator *it; + + it = evas_object_box_iterator_new(pd->pack); + return _part_item_iterator_create(obj, it, NULL); +} + +EOLIAN static int +_efl_ui_layout_internal_box_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd) +{ + return evas_obj_box_count(pd->pack); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_box_efl_container_content_remove(Eo *obj, Efl_Ui_Layout_Box_Data *pd EINA_UNUSED, Efl_Gfx_Base *content) +{ + // alias + return efl_pack_unpack(obj, content); +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd) +{ + _elm_layout_box_remove_all(pd->obj, pd->sd, pd->part, EINA_TRUE); +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_unpack_all(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd) +{ + _elm_layout_box_remove_all(pd->obj, pd->sd, pd->part, EINA_FALSE); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_box_efl_pack_unpack(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj) +{ + return _elm_layout_box_remove(pd->obj, pd->sd, pd->part, subobj) != NULL; +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_pack(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj) +{ + _elm_layout_box_append(pd->obj, pd->sd, pd->part, subobj); +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_linear_pack_begin(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj) +{ + _elm_layout_box_prepend(pd->obj, pd->sd, pd->part, subobj); +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_linear_pack_end(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj) +{ + _elm_layout_box_append(pd->obj, pd->sd, pd->part, subobj); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_box_efl_pack_linear_pack_before(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj, const Efl_Gfx_Base *existing) +{ + return _elm_layout_box_insert_before(pd->obj, pd->sd, pd->part, subobj, existing); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_box_efl_pack_linear_pack_after(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj, const Efl_Gfx_Base *existing) +{ + const Efl_Gfx_Base *other; + int index; + + index = efl_pack_content_index_get(pd->pack, (Efl_Gfx_Base *) existing); + if (index < 0) return EINA_FALSE; + + other = efl_pack_content_at_get(pd->pack, index + 1); + if (other) + return _elm_layout_box_insert_before(pd->obj, pd->sd, pd->part, subobj, other); + + efl_pack_end(obj, subobj); + return EINA_TRUE; +} + +EOLIAN static void +_efl_ui_layout_internal_box_efl_pack_linear_pack_insert(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj, int index) +{ + _elm_layout_box_insert_at(pd->obj, pd->sd, pd->part, subobj, index); +} + +EOLIAN static Efl_Gfx_Base * +_efl_ui_layout_internal_box_efl_pack_linear_content_at_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, int index) +{ + Evas_Object_Box_Option *opt; + Evas_Object_Box_Data *priv; + + priv = eo_data_scope_get(pd->pack, EVAS_BOX_CLASS); + opt = eina_list_nth(priv->children, index); + if (!opt) return NULL; + return opt->obj; +} + +EOLIAN static Efl_Gfx_Base * +_efl_ui_layout_internal_box_efl_pack_linear_content_at_remove(Eo *obj, Efl_Ui_Layout_Box_Data *pd, int index) +{ + Efl_Gfx_Base *subobj; + + subobj = efl_pack_content_at_get(pd->pack, index); + if (!subobj) return NULL; + if (efl_pack_unpack(obj, subobj)) + return subobj; + + ERR("failed to remove %p from %p (item %d)", subobj, pd->obj, index); + return NULL; +} + +EOLIAN static int +_efl_ui_layout_internal_box_efl_pack_linear_content_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd, Efl_Gfx_Base *subobj) +{ + return efl_pack_content_index_get(pd->pack, subobj); +} + +EOLIAN static Efl_Orient +_efl_ui_layout_internal_box_efl_pack_linear_direction_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Box_Data *pd) +{ + ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EFL_ORIENT_NONE); + + return efl_pack_direction_get(efl_content_get(wd->resize_obj, pd->part)); +} + +EOLIAN static void +_efl_ui_layout_internal_table_real_part_set(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, Eo *layout, Eo *pack, const char *part) +{ + pd->obj = layout; + pd->sd = eo_data_scope_get(layout, ELM_LAYOUT_CLASS); + pd->part = eina_stringshare_add(part); + pd->pack = pack; +} + +EOLIAN static Eo_Base * +_efl_ui_layout_internal_table_eo_base_finalize(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->obj && pd->part && pd->sd, NULL); + return eo_finalize(eo_super(obj, TABLE_CLASS)); +} + +EOLIAN static void +_efl_ui_layout_internal_table_eo_base_destructor(Eo *obj, Efl_Ui_Layout_Box_Data *pd) +{ + eo_key_del(pd->pack, DATA_KEY); + eina_stringshare_del(pd->part); + eo_destructor(eo_super(obj, TABLE_CLASS)); +} + +EOLIAN static Eina_Iterator * +_efl_ui_layout_internal_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Layout_Table_Data *pd) +{ + Eina_Iterator *it; + + it = evas_object_table_iterator_new(pd->pack); + + return _part_item_iterator_create(obj, it, NULL); +} + +EOLIAN static int +_efl_ui_layout_internal_table_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + return evas_obj_table_count(pd->pack); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_table_efl_container_content_remove(Eo *obj, Efl_Ui_Layout_Table_Data *pd EINA_UNUSED, Efl_Gfx_Base *content) +{ + return efl_pack_unpack(obj, content); +} + +EOLIAN static void +_efl_ui_layout_internal_table_efl_pack_pack_clear(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + _elm_layout_table_clear(pd->obj, pd->sd, pd->part, EINA_TRUE); +} + +EOLIAN static void +_efl_ui_layout_internal_table_efl_pack_unpack_all(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + _elm_layout_table_clear(pd->obj, pd->sd, pd->part, EINA_FALSE); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_table_efl_pack_unpack(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, Efl_Gfx_Base *subobj) +{ + if (!subobj) return EINA_FALSE; + return _elm_layout_table_unpack(pd->obj, pd->sd, pd->part, subobj) == subobj; +} + +EOLIAN static void +_efl_ui_layout_internal_table_efl_pack_grid_pack_grid(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, Efl_Gfx_Base *subobj, int col, int row, int colspan, int rowspan) +{ + _elm_layout_table_pack(pd->obj, pd->sd, pd->part, subobj, col, row, colspan, rowspan); +} + +EOLIAN static Efl_Gfx_Base * +_efl_ui_layout_internal_table_efl_pack_grid_grid_content_at(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int col, int row) +{ + return evas_object_table_child_get(pd->pack, col, row); +} + +EOLIAN static Eina_Iterator * +_efl_ui_layout_internal_table_efl_pack_grid_grid_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int col, int row, Eina_Bool below) +{ + // contents at col,row - see also Efl.Ui.Grid or edje_containers.c + // not reusing edje's iterator because the container would be wrong + + Eina_List *list, *l = NULL; + Evas_Object *sobj; + unsigned short c, r, cs, rs; + + list = evas_object_table_children_get(pd->pack); + EINA_LIST_FREE(list, sobj) + { + evas_object_table_pack_get(pd->pack, sobj, &c, &r, &cs, &rs); + + if (((int) c == col) && ((int) r == row)) + list = eina_list_append(list, sobj); + else if (below) + { + if (((int) c <= col) && ((int) (c + cs) >= col) && + ((int) r <= row) && ((int) (r + rs) >= row)) + list = eina_list_append(list, sobj); + } + } + + return _part_item_iterator_create(pd->obj, eina_list_iterator_new(l), l); +} + +EOLIAN static Eina_Bool +_efl_ui_layout_internal_table_efl_pack_grid_grid_content_position_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, Efl_Gfx_Base * subobj, int *col, int *row, int *colspan, int *rowspan) +{ + unsigned short c, r, cs, rs; + Eina_Bool ret; + + ret = evas_object_table_pack_get(pd->pack, subobj, &c, &r, &cs, &rs); + if (col) *col = c; + if (row) *row = r; + if (colspan) *colspan = cs; + if (rowspan) *rowspan = rs; + + return ret; +} + +EOLIAN static void +_efl_ui_layout_internal_table_efl_pack_grid_grid_size_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd, int *cols, int *rows) +{ + evas_object_table_col_row_size_get(pd->pack, cols, rows); +} + +EOLIAN static int +_efl_ui_layout_internal_table_efl_pack_grid_grid_columns_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + int cols, rows; + evas_object_table_col_row_size_get(pd->pack, &cols, &rows); + return cols; +} + +EOLIAN static int +_efl_ui_layout_internal_table_efl_pack_grid_grid_rows_get(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Table_Data *pd) +{ + int cols, rows; + evas_object_table_col_row_size_get(pd->pack, &cols, &rows); + return rows; +} + +#include "efl_ui_layout_internal_box.eo.c" +#include "efl_ui_layout_internal_table.eo.c" --