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".
This commit is contained in:
Jean-Philippe Andre 2016-04-25 21:36:56 +09:00
parent 59ead67aa1
commit e7f0b64860
8 changed files with 770 additions and 169 deletions

View File

@ -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 \

View File

@ -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@

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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"

View File

@ -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;

View File

@ -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"

View File

@ -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"