diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h
index 1c5593a943..2af0d7e3b3 100644
--- a/legacy/evas/src/lib/Evas.h
+++ b/legacy/evas/src/lib/Evas.h
@@ -87,6 +87,13 @@ typedef enum _Evas_Colorspace
EVAS_COLORSPACE_RGB565_A5P /**< 16bit rgb565 + Alpha plane at end - 5 bits of the 8 being used per alpha byte */
} Evas_Colorspace; /**< Colorspaces for pixel data supported by Evas */
+typedef enum _Evas_Object_Table_Homogeneous_Mode
+{
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE = 0,
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE = 1,
+ EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM = 2
+} Evas_Object_Table_Homogeneous_Mode;
+
typedef struct _Evas_Transform Evas_Transform; /**< An Evas projective or affine transform */
typedef struct _Evas_Rectangle Evas_Rectangle; /**< A generic rectangle handle */
typedef struct _Evas_Coord_Rectangle Evas_Coord_Rectangle; /**< A generic rectangle handle */
@@ -791,7 +798,7 @@ extern "C" {
EAPI void evas_object_smart_callback_call (Evas_Object *obj, const char *event, void *event_info);
EAPI void evas_object_smart_changed (Evas_Object *obj);
EAPI void evas_object_smart_need_recalculate_set(Evas_Object *obj, Evas_Bool value);
- EAPI Evas_Bool evas_object_smart_need_recalculate_get(Evas_Object *obj);
+ EAPI Evas_Bool evas_object_smart_need_recalculate_get(const Evas_Object *obj);
EAPI void evas_object_smart_calculate (Evas_Object *obj);
@@ -993,10 +1000,12 @@ extern "C" {
{
Evas_Object_Smart_Clipped_Data base;
const Evas_Object_Box_Api *api;
- double align_h;
- double align_v;
- int padding_h;
- int padding_v;
+ struct {
+ double h, v;
+ } align;
+ struct {
+ Evas_Coord h, v;
+ } pad;
Eina_List *children;
Evas_Object_Box_Layout layout;
};
@@ -1022,14 +1031,10 @@ extern "C" {
EAPI void evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv);
EAPI void evas_object_box_layout_stack(Evas_Object *o, Evas_Object_Box_Data *priv);
- EAPI double evas_object_box_align_h_get(Evas_Object *o);
- EAPI double evas_object_box_align_v_get(Evas_Object *o);
- EAPI void evas_object_box_align_h_set(Evas_Object *o, double align_h);
- EAPI void evas_object_box_align_v_set(Evas_Object *o, double align_v);
- EAPI int evas_object_box_padding_h_get(Evas_Object *o);
- EAPI int evas_object_box_padding_v_get(Evas_Object *o);
- EAPI void evas_object_box_padding_h_set(Evas_Object *o, int padding_h);
- EAPI void evas_object_box_padding_v_set(Evas_Object *o, int padding_v);
+ EAPI void evas_object_box_align_set(Evas_Object *o, double horizontal, double vertical);
+ EAPI void evas_object_box_align_get(const Evas_Object *o, double *horizontal, double *vertical);
+ EAPI void evas_object_box_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical);
+ EAPI void evas_object_box_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical);
EAPI Evas_Object_Box_Option *evas_object_box_append(Evas_Object *o, Evas_Object *child);
EAPI Evas_Object_Box_Option *evas_object_box_prepend(Evas_Object *o, Evas_Object *child);
@@ -1046,6 +1051,21 @@ extern "C" {
EAPI Evas_Bool evas_object_box_option_property_vget(Evas_Object *o, Evas_Object_Box_Option *opt, int property, va_list args);
+ EAPI void evas_object_table_smart_set(Evas_Smart_Class *sc);
+ EAPI Evas_Object *evas_object_table_add(Evas *evas);
+ EAPI Evas_Object *evas_object_table_add_to(Evas_Object *parent);
+ EAPI void evas_object_table_homogeneous_set(Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous);
+ EAPI Evas_Object_Table_Homogeneous_Mode evas_object_table_homogeneous_get(const Evas_Object *o);
+ EAPI void evas_object_table_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical);
+ EAPI void evas_object_table_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical);
+ EAPI void evas_object_table_align_set(Evas_Object *o, double horizontal, double vertical);
+ EAPI void evas_object_table_align_get(const Evas_Object *o, double *horizontal, double *vertical);
+
+ EAPI Evas_Bool evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan);
+ EAPI Evas_Bool evas_object_table_unpack(Evas_Object *o, Evas_Object *child);
+ EAPI void evas_object_table_clear(Evas_Object *o, Evas_Bool delete);
+
+ EAPI void evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows);
#ifdef __cplusplus
}
diff --git a/legacy/evas/src/lib/canvas/Makefile.am b/legacy/evas/src/lib/canvas/Makefile.am
index ad9abcded7..a1834b7303 100644
--- a/legacy/evas/src/lib/canvas/Makefile.am
+++ b/legacy/evas/src/lib/canvas/Makefile.am
@@ -34,6 +34,7 @@ evas_object_rectangle.c \
evas_object_smart.c \
evas_object_smart_clipped.c \
evas_object_box.c \
+evas_object_table.c \
evas_object_text.c \
evas_object_textblock.c \
evas_font_dir.c \
diff --git a/legacy/evas/src/lib/canvas/evas_object_box.c b/legacy/evas/src/lib/canvas/evas_object_box.c
index 12f1289c84..d116b277ef 100644
--- a/legacy/evas/src/lib/canvas/evas_object_box.c
+++ b/legacy/evas/src/lib/canvas/evas_object_box.c
@@ -329,10 +329,10 @@ _evas_object_box_smart_add(Evas_Object *o)
_parent_sc.add(o);
priv->children = NULL;
- priv->align_h = 0.5;
- priv->align_v = 0.5;
- priv->padding_h = 0;
- priv->padding_v = 0;
+ priv->align.h = 0.5;
+ priv->align.v = 0.5;
+ priv->pad.h = 0;
+ priv->pad.v = 0;
priv->layout = evas_object_box_layout_horizontal;
}
@@ -672,7 +672,7 @@ evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv)
Evas_Object_Box_Option *objects[n_children];
evas_object_geometry_get(o, &x, &y, &w, &h);
- global_pad = priv->padding_h;
+ global_pad = priv->pad.h;
req_w = global_pad * (n_children - 1);
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -706,15 +706,15 @@ evas_object_box_layout_horizontal(Evas_Object *o, Evas_Object_Box_Data *priv)
remaining = _evas_object_box_layout_horizontal_weight_apply
(priv, objects, weight_use, remaining, weight_total);
- if (priv->align_h >= 0.0)
- x += remaining * priv->align_h;
+ if (priv->align.h >= 0.0)
+ x += remaining * priv->align.h;
else if (n_children == 1)
x += remaining / 2;
else
{ /* justified */
_fixed_point_divide_and_decompose_integer
(remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->padding_h;
+ global_pad += priv->pad.h;
}
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -830,7 +830,7 @@ evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv)
Evas_Object_Box_Option *objects[n_children];
evas_object_geometry_get(o, &x, &y, &w, &h);
- global_pad = priv->padding_v;
+ global_pad = priv->pad.v;
req_h = global_pad * (n_children - 1);
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -864,15 +864,15 @@ evas_object_box_layout_vertical(Evas_Object *o, Evas_Object_Box_Data *priv)
remaining = _evas_object_box_layout_vertical_weight_apply
(priv, objects, weight_use, remaining, weight_total);
- if (priv->align_v >= 0.0)
- y += remaining * priv->align_v;
+ if (priv->align.v >= 0.0)
+ y += remaining * priv->align.v;
else if (n_children == 1)
y += remaining / 2;
else
{ /* justified */
_fixed_point_divide_and_decompose_integer
(remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->padding_v;
+ global_pad += priv->pad.v;
}
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -956,7 +956,7 @@ evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Da
evas_object_geometry_get(o, &x, &y, &w, &h);
- share = w - priv->padding_h * (n_children - 1);
+ share = w - priv->pad.h * (n_children - 1);
_fixed_point_divide_and_decompose_integer
(share, n_children, &cell_sz, &inc);
@@ -987,7 +987,7 @@ evas_object_box_layout_homogeneous_horizontal(Evas_Object *o, Evas_Object_Box_Da
evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
- x += cell_sz + priv->padding_h;
+ x += cell_sz + priv->pad.h;
sub_pixel += inc;
if (sub_pixel >= 1 << 16)
{
@@ -1021,7 +1021,7 @@ evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data
evas_object_geometry_get(o, &x, &y, &w, &h);
- share = h - priv->padding_v * (n_children - 1);
+ share = h - priv->pad.v * (n_children - 1);
_fixed_point_divide_and_decompose_integer
(share, n_children, &cell_sz, &inc);
@@ -1051,7 +1051,7 @@ evas_object_box_layout_homogeneous_vertical(Evas_Object *o, Evas_Object_Box_Data
evas_object_resize(opt->obj, new_w, new_h);
evas_object_move(opt->obj, x + off_x, y + off_y);
- y += cell_sz + priv->padding_v;
+ y += cell_sz + priv->pad.v;
sub_pixel += inc;
if (sub_pixel >= 1 << 16)
{
@@ -1129,18 +1129,18 @@ evas_object_box_layout_homogeneous_max_size_horizontal(Evas_Object *o, Evas_Obje
cell_sz = child_w + padding_l + padding_r;
}
- global_pad = priv->padding_h;
+ global_pad = priv->pad.h;
remaining = w - n_children * cell_sz - global_pad * (n_children - 1);
- if (priv->align_h >= 0.0)
- x += remaining * priv->align_h;
+ if (priv->align.h >= 0.0)
+ x += remaining * priv->align.h;
else if (n_children == 1)
x += remaining / 2;
else
{ /* justified */
_fixed_point_divide_and_decompose_integer
(remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->padding_h;
+ global_pad += priv->pad.h;
}
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -1216,18 +1216,18 @@ evas_object_box_layout_homogeneous_max_size_vertical(Evas_Object *o, Evas_Object
cell_sz = child_h + padding_t + padding_b;
}
- global_pad = priv->padding_v;
+ global_pad = priv->pad.v;
remaining = h - n_children * cell_sz - global_pad * (n_children - 1);
- if (priv->align_v >= 0.0)
- y += remaining * priv->align_v;
+ if (priv->align.v >= 0.0)
+ y += remaining * priv->align.v;
else if (n_children == 1)
y += remaining / 2;
else
{ /* justified */
_fixed_point_divide_and_decompose_integer
(remaining, n_children - 1, &global_pad, &pad_inc);
- global_pad += priv->padding_v;
+ global_pad += priv->pad.v;
}
EINA_LIST_FOREACH(priv->children, l, opt)
@@ -1286,7 +1286,7 @@ _evas_object_box_layout_flow_horizontal_row_info_collect(Evas_Object_Box_Data *p
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
- child_w += padding_l + padding_r + priv->padding_h;
+ child_w += padding_l + padding_r + priv->pad.h;
child_h += padding_t + padding_b;
remain_w -= child_w;
@@ -1398,8 +1398,8 @@ evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *pri
v_justify = 0;
remain_y = h - (off_y + max_h);
- if (priv->align_v >= 0.0)
- inc_y = priv->align_v * remain_y;
+ if (priv->align.v >= 0.0)
+ inc_y = priv->align.v * remain_y;
else if (row_count == 0)
y += remain_y / 2;
else /* y-justified */
@@ -1413,7 +1413,7 @@ evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *pri
row_size = row_break[r] - i;
remain_x = (w - row_width[r]);
- if (priv->align_h < 0.0)
+ if (priv->align.h < 0.0)
{
if (row_size == 0)
x += remain_x / 2;
@@ -1440,8 +1440,8 @@ evas_object_box_layout_flow_horizontal(Evas_Object *o, Evas_Object_Box_Data *pri
y_remain = row_max_h[r] - child_h;
off_x = padding_l;
- if (priv->align_h >= 0.0)
- off_x += remain_x * priv->align_h;
+ if (priv->align.h >= 0.0)
+ off_x += remain_x * priv->align.h;
off_y = y_remain * align_y;
evas_object_move(opt->obj, x + off_x, y + off_y);
@@ -1480,7 +1480,7 @@ _evas_object_box_layout_flow_vertical_col_info_collect(Evas_Object_Box_Data *pri
evas_object_geometry_get(opt->obj, NULL, NULL, &child_w, &child_h);
child_w += padding_l + padding_r;
- child_h += padding_t + padding_b + priv->padding_v;
+ child_h += padding_t + padding_b + priv->pad.v;
remain_h -= child_h;
if (remain_h >= 0)
@@ -1565,8 +1565,8 @@ evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv)
h_justify = 0;
remain_x = w - (off_x + max_w);
- if (priv->align_h >= 0)
- inc_x = priv->align_h * remain_x;
+ if (priv->align.h >= 0)
+ inc_x = priv->align.h * remain_x;
else if (col_count == 0)
x += remain_x / 2;
else /* x-justified */
@@ -1580,7 +1580,7 @@ evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv)
col_size = col_break[c] - i;
remain_y = (h - col_height[c]);
- if (priv->align_v < 0.0)
+ if (priv->align.v < 0.0)
{
if (col_size == 0)
y += remain_y / 2;
@@ -1608,8 +1608,8 @@ evas_object_box_layout_flow_vertical(Evas_Object *o, Evas_Object_Box_Data *priv)
off_x = x_remain * align_x;
off_y = padding_t;
- if (priv->align_v >= 0.0)
- off_y += remain_y * priv->align_v;
+ if (priv->align.v >= 0.0)
+ off_y += remain_y * priv->align.v;
evas_object_move(opt->obj, x + off_x, y + off_y);
@@ -1691,87 +1691,69 @@ evas_object_box_layout_stack(Evas_Object *o, Evas_Object_Box_Data *priv)
}
/**
- * Get horizontal alignment of the box @a o.
- */
-double
-evas_object_box_align_h_get(Evas_Object *o)
-{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0.0);
- return priv->align_h;
-}
-
-/**
- * Get horizontal padding of the box @a o.
- */
-int
-evas_object_box_padding_h_get(Evas_Object *o)
-{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
- return priv->padding_h;
-}
-
-/**
- * Get vertical alignment of the box @a o.
- */
-double
-evas_object_box_align_v_get(Evas_Object *o)
-{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0.0);
- return priv->align_v;
-}
-
-/**
- * Get vertical padding of the box @a o.
- */
-int
-evas_object_box_padding_v_get(Evas_Object *o)
-{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN_VAL(o, priv, 0);
- return priv->padding_v;
-}
-
-/**
- * Set horizontal alignment of the box @a o.
+ * Set the alignment of the whole bounding box of contents.
*/
void
-evas_object_box_align_h_set(Evas_Object *o, double align_h)
+evas_object_box_align_set(Evas_Object *o, double horizontal, double vertical)
{
EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
- priv->align_h = align_h;
+ if (priv->align.h == horizontal && priv->align.v == vertical)
+ return;
+ priv->align.h = horizontal;
+ priv->align.v = vertical;
evas_object_smart_changed(o);
}
/**
- * Set horizontal padding of the box @a o.
+ * Get alignment of the whole bounding box of contents.
*/
void
-evas_object_box_padding_h_set(Evas_Object *o, int padding_h)
+evas_object_box_align_get(const Evas_Object *o, double *horizontal, double *vertical)
+{
+ EVAS_OBJECT_BOX_DATA_GET(o, priv);
+ if (priv)
+ {
+ if (horizontal) *horizontal = priv->align.h;
+ if (vertical) *vertical = priv->align.v;
+ }
+ else
+ {
+ if (horizontal) *horizontal = 0.5;
+ if (vertical) *vertical = 0.5;
+ }
+}
+
+/**
+ * Set the space (padding) between cells.
+ */
+void
+evas_object_box_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical)
{
EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
- priv->padding_h = padding_h;
+ if (priv->pad.h == horizontal && priv->pad.v == vertical)
+ return;
+ priv->pad.h = horizontal;
+ priv->pad.v = vertical;
evas_object_smart_changed(o);
}
/**
- * Set vertical alignment of the box @a o.
+ * Get the (space) padding between cells.
*/
void
-evas_object_box_align_v_set(Evas_Object *o, double align_v)
+evas_object_box_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical)
{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
- priv->align_v = align_v;
- evas_object_smart_changed(o);
-}
-
-/**
- * Set vertical padding of the box @a o.
- */
-void
-evas_object_box_padding_v_set(Evas_Object *o, int padding_v)
-{
- EVAS_OBJECT_BOX_DATA_GET_OR_RETURN(o, priv);
- priv->padding_v = padding_v;
- evas_object_smart_changed(o);
+ EVAS_OBJECT_BOX_DATA_GET(o, priv);
+ if (priv)
+ {
+ if (horizontal) *horizontal = priv->pad.h;
+ if (vertical) *vertical = priv->pad.v;
+ }
+ else
+ {
+ if (horizontal) *horizontal = 0;
+ if (vertical) *vertical = 0;
+ }
}
/**
diff --git a/legacy/evas/src/lib/canvas/evas_object_smart.c b/legacy/evas/src/lib/canvas/evas_object_smart.c
index 291f854167..86f44192a3 100644
--- a/legacy/evas/src/lib/canvas/evas_object_smart.c
+++ b/legacy/evas/src/lib/canvas/evas_object_smart.c
@@ -506,7 +506,7 @@ evas_object_smart_need_recalculate_set(Evas_Object *obj, Evas_Bool value)
* @ingroup Evas_Smart_Object_Group
*/
EAPI Evas_Bool
-evas_object_smart_need_recalculate_get(Evas_Object *obj)
+evas_object_smart_need_recalculate_get(const Evas_Object *obj)
{
Evas_Object_Smart *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
diff --git a/legacy/evas/src/lib/canvas/evas_object_table.c b/legacy/evas/src/lib/canvas/evas_object_table.c
new file mode 100644
index 0000000000..0e3aa1495c
--- /dev/null
+++ b/legacy/evas/src/lib/canvas/evas_object_table.c
@@ -0,0 +1,886 @@
+#include "evas_common.h"
+
+typedef struct _Evas_Object_Table_Data Evas_Object_Table_Data;
+typedef struct _Evas_Object_Table_Option Evas_Object_Table_Option;
+
+struct _Evas_Object_Table_Option
+{
+ Evas_Object *obj;
+ unsigned short col, row, colspan, rowspan, end_col, end_row;
+ struct {
+ Evas_Coord w, h;
+ } min, max;
+ struct {
+ double h, v;
+ } align;
+ struct {
+ Evas_Coord l, r, t, b;
+ } pad;
+ Evas_Bool expand_h : 1; /* XXX required? */
+ Evas_Bool expand_v : 1; /* XXX required? */
+};
+
+struct _Evas_Object_Table_Data
+{
+ Evas_Object_Smart_Clipped_Data base;
+ Eina_List *children;
+ struct {
+ Evas_Coord h, v;
+ } pad;
+ struct {
+ double h, v;
+ } align;
+ struct {
+ int cols, rows;
+ } size;
+ Evas_Object_Table_Homogeneous_Mode homogeneous;
+ Evas_Bool hints_changed : 1;
+ Evas_Bool expand_h : 1;
+ Evas_Bool expand_v : 1;
+};
+
+/**
+ * @addtogroup Evas_Object_Table
+ * @{
+ * @ingroup Evas_Smart_Object_Group
+ */
+
+#define EVAS_OBJECT_TABLE_DATA_GET(o, ptr) \
+ Evas_Object_Table_Data *ptr = evas_object_smart_data_get(o)
+
+#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, ptr) \
+ EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
+ if (!ptr) \
+ { \
+ fprintf(stderr, "CRITICAL: no widget data for object %p (%s)\n", \
+ o, evas_object_type_get(o)); \
+ fflush(stderr); \
+ abort(); \
+ return; \
+}
+
+#define EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \
+ EVAS_OBJECT_TABLE_DATA_GET(o, ptr); \
+ if (!ptr) \
+ { \
+ fprintf(stderr, "CRITICAL: no widget data for object %p (%s)\n", \
+ o, evas_object_type_get(o)); \
+ fflush(stderr); \
+ abort(); \
+ return val; \
+ }
+
+static const char EVAS_OBJECT_TABLE_OPTION_KEY[] = "Evas_Object_Table_Option";
+
+static Evas_Object_Table_Option *
+_evas_object_table_option_get(Evas_Object *o)
+{
+ return evas_object_data_get(o, EVAS_OBJECT_TABLE_OPTION_KEY);
+}
+
+static void
+_evas_object_table_option_set(Evas_Object *o, const Evas_Object_Table_Option *opt)
+{
+ evas_object_data_set(o, EVAS_OBJECT_TABLE_OPTION_KEY, opt);
+}
+
+static Evas_Object_Table_Option *
+_evas_object_table_option_del(Evas_Object *o)
+{
+ return evas_object_data_del(o, EVAS_OBJECT_TABLE_OPTION_KEY);
+}
+
+static void
+_on_child_del(void *data, Evas *evas, Evas_Object *child, void *einfo)
+{
+ Evas_Object *table = data;
+ evas_object_table_unpack(table, child);
+}
+
+static void
+_on_child_hints_changed(void *data, Evas *evas, Evas_Object *child, void *einfo)
+{
+ Evas_Object *table = data;
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(table, priv);
+ priv->hints_changed = 1;
+ evas_object_smart_changed(table);
+}
+
+static void
+_evas_object_table_child_connect(Evas_Object *o, Evas_Object *child)
+{
+ evas_object_event_callback_add
+ (child, EVAS_CALLBACK_DEL, _on_child_del, o);
+ evas_object_event_callback_add
+ (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed, o);
+}
+
+static void
+_evas_object_table_child_disconnect(Evas_Object *o, Evas_Object *child)
+{
+ evas_object_event_callback_del_full
+ (child, EVAS_CALLBACK_DEL, _on_child_del, o);
+ evas_object_event_callback_del_full
+ (child, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_child_hints_changed, o);
+}
+
+static void
+_evas_object_table_calculate_cell(const Evas_Object_Table_Option *opt, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+ Evas_Coord cw, ch;
+
+ *w -= opt->pad.l + opt->pad.r;
+ if (*w < opt->min.w)
+ cw = opt->min.w;
+ else if ((opt->max.w > -1) && (*w > opt->max.w))
+ cw = opt->max.w;
+ else
+ cw = *w;
+
+ *h -= opt->pad.t + opt->pad.b;
+ if (*h < opt->min.h)
+ ch = opt->min.h;
+ else if ((opt->max.h > -1) && (*h > opt->max.h))
+ ch = opt->max.h;
+ else
+ ch = *h;
+
+ *x += opt->pad.l;
+ if (cw != *w)
+ {
+ *x += (*w - cw) * opt->align.h;
+ *w = cw;
+ }
+
+ *y += opt->pad.t;
+ if (ch != *h)
+ {
+ *y += (*h - ch) * opt->align.v;
+ *h = ch;
+ }
+}
+
+/* static Evas_Bool */
+/* _evas_object_table_check_hints_homogeneous_table(Evas_Object *child, double *align, Evas_Coord min, const char *axis_name) */
+/* { */
+/* if (*align < 0.0) */
+/* { */
+/* /\* assume expand and align to the center. */
+/* * this is compatible with evas_object_box behavior and is the */
+/* * same as weight > 0.0. */
+/* *\/ */
+/* *align = 0.5; */
+/* return 0; */
+/* } */
+/* else if (min < 1) */
+/* { */
+/* fprintf(stderr, */
+/* "WARNING: child %p [%s, %s] has no minimum width " */
+/* "and no %s expand (weight is not > 0.0). " */
+/* "Assuming weight > 0.0\n", */
+/* child, evas_object_type_get(child), evas_object_name_get(child), */
+/* axis_name); */
+/* return 0; */
+/* } */
+
+/* return 1; */
+/* } */
+
+static void
+_evas_object_table_calculate_hints_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ Eina_List *l;
+ Evas_Object_Table_Option *opt;
+ Evas_Coord minw, minh, o_minw, o_minh;
+ Evas_Bool expand_h, expand_v;
+
+ o_minw = 0;
+ o_minh = 0;
+ minw = 0;
+ minh = 0;
+ expand_h = 0;
+ expand_v = 0;
+
+ EINA_LIST_FOREACH(priv->children, l, opt)
+ {
+ Evas_Object *child = opt->obj;
+ Evas_Coord child_minw, child_minh, cell_minw, cell_minh;
+ double weightw, weighth;
+
+ evas_object_size_hint_min_get(child, &opt->min.w, &opt->min.h);
+ evas_object_size_hint_max_get(child, &opt->max.w, &opt->max.h);
+ evas_object_size_hint_padding_get
+ (child, &opt->pad.l, &opt->pad.r, &opt->pad.t, &opt->pad.b);
+ evas_object_size_hint_align_get(child, &opt->align.h, &opt->align.v);
+ evas_object_size_hint_weight_get(child, &weightw, &weighth);
+
+ child_minw = opt->min.w + opt->pad.l + opt->pad.r;
+ child_minh = opt->min.h + opt->pad.t + opt->pad.b;
+
+ cell_minw = (child_minw + opt->colspan - 1) / opt->colspan;
+ cell_minh = (child_minh + opt->rowspan - 1) / opt->rowspan;
+
+ if ((weightw > 0.0) &&
+ ((opt->max.w < 0) ||
+ ((opt->max.w > -1) && (opt->min.w < opt->max.w))))
+ {
+ opt->expand_h = 1;
+ expand_h = 1;
+ }
+/* else if ((priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE) && */
+/* (!_evas_object_table_check_hints_homogeneous_table */
+/* (child, &opt->align.h, opt->min.w, "horizontal"))) */
+/* { */
+/* opt->expand_h = 1; */
+/* expand_h = 1; */
+/* } */
+
+ if ((weighth > 0.0) &&
+ ((opt->max.h < 0) ||
+ ((opt->max.h > -1) && (opt->min.h < opt->max.h))))
+ {
+ opt->expand_v = 1;
+ expand_v = 1;
+ }
+/* else if ((priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE) && */
+/* (!_evas_object_table_check_hints_homogeneous_table */
+/* (child, &opt->align.v, opt->min.h, "vertical"))) */
+/* { */
+/* opt->expand_v = 1; */
+/* expand_v = 1; */
+/* } */
+
+ if (opt->align.h < 0.0)
+ opt->align.h = 0.5;
+ if (opt->align.v < 0.0)
+ opt->align.v = 0.5;
+
+ /* greatest mininum values, with paddings */
+ if (minw < cell_minw)
+ minw = cell_minw;
+ if (minh < cell_minh)
+ minh = cell_minh;
+ /* greatest mininum values, without paddings */
+ if (o_minw < opt->min.w)
+ o_minw = opt->min.w;
+ if (o_minh < opt->min.h)
+ o_minh = opt->min.h;
+ }
+
+ if (priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM)
+ {
+ if (o_minw < 1)
+ {
+ fputs("ERROR: homogeneous table based on item size but no "
+ "horizontal mininum size specified! Using expand.\n",
+ stderr);
+ expand_h = 1;
+ }
+ if (o_minh < 1)
+ {
+ fputs("ERROR: homogeneous table based on item size but no "
+ "vertical mininum size specified! Using expand.\n",
+ stderr);
+ expand_v = 1;
+ }
+ }
+
+ minw = priv->size.cols * (minw + priv->pad.h) - priv->pad.h;
+ minh = priv->size.rows * (minh + priv->pad.v) - priv->pad.v;
+
+ priv->hints_changed = 0;
+ priv->expand_h = expand_h;
+ priv->expand_v = expand_v;
+
+ if ((minw > 0 ) || (minh > 0))
+ evas_object_size_hint_min_set(o, minw, minh);
+
+ // XXX hint max?
+}
+
+static void
+_evas_object_table_calculate_layout_homogeneous_sizes_item(const Evas_Object *o, const Evas_Object_Table_Data *priv, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+ Evas_Coord minw, minh;
+ Evas_Bool expand_h, expand_v;
+
+ evas_object_size_hint_min_get(o, &minw, &minh);
+ expand_h = priv->expand_h;
+ expand_v = priv->expand_v;
+
+ if (*w < minw)
+ expand_h = 0;
+ if (!expand_h)
+ {
+ *x += (*w - minw) * priv->align.h;
+ *w = minw;
+ }
+
+ if (*h < minh)
+ expand_v = 0;
+ if (!expand_v)
+ {
+ *y += (*h - minh) * priv->align.v;
+ *h = minh;
+ }
+}
+
+static void
+_evas_object_table_calculate_layout_homogeneous_sizes(const Evas_Object *o, const Evas_Object_Table_Data *priv, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h, Evas_Coord *cellw, Evas_Coord *cellh)
+{
+ evas_object_geometry_get(o, x, y, w, h);
+ if (priv->homogeneous == EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM)
+ _evas_object_table_calculate_layout_homogeneous_sizes_item
+ (o, priv, x, y, w, h);
+
+ *cellw = (*w + priv->size.cols - 1) / priv->size.cols;
+ *cellh = (*h + priv->size.rows - 1) / priv->size.rows;
+}
+
+static void
+_evas_object_table_calculate_layout_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ Evas_Coord x, y, w, h, cellw, cellh;
+ Eina_List *l;
+ Evas_Object_Table_Option *opt;
+
+ _evas_object_table_calculate_layout_homogeneous_sizes
+ (o, priv, &x, &y, &w, &h, &cellw, &cellh);
+
+ EINA_LIST_FOREACH(priv->children, l, opt)
+ {
+ Evas_Object *child = opt->obj;
+ Evas_Coord cx, cy, cw, ch;
+
+ cx = x + opt->col * (cellw + priv->pad.h);
+ cy = y + opt->row * (cellh + priv->pad.v);
+
+ cw = opt->colspan * cellw - priv->pad.h;
+ ch = opt->rowspan * cellh - priv->pad.v;
+
+ _evas_object_table_calculate_cell(opt, &cx, &cy, &cw, &ch);
+
+ evas_object_move(child, cx, cy);
+ evas_object_resize(child, cw, ch);
+ }
+}
+
+static void
+_evas_object_table_smart_calculate_homogeneous(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ if (priv->hints_changed)
+ _evas_object_table_calculate_hints_homogeneous(o, priv);
+ _evas_object_table_calculate_layout_homogeneous(o, priv);
+}
+
+static void
+_evas_object_table_calculate_hints_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ puts("XXX TODO: calculate hints for non-homogeneous tables");
+}
+
+static void
+_evas_object_table_calculate_layout_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ puts("XXX TODO: calculate layout for non-homogeneous tables");
+}
+
+static void
+_evas_object_table_smart_calculate_regular(Evas_Object *o, Evas_Object_Table_Data *priv)
+{
+ if (priv->hints_changed)
+ _evas_object_table_calculate_hints_regular(o, priv);
+ _evas_object_table_calculate_layout_regular(o, priv);
+}
+
+static Evas_Smart_Class _parent_sc = {NULL};
+
+static void
+_evas_object_table_smart_add(Evas_Object *o)
+{
+ Evas_Object_Table_Data *priv;
+
+ priv = evas_object_smart_data_get(o);
+ if (!priv)
+ {
+ priv = calloc(1, sizeof(*priv));
+ if (!priv)
+ {
+ fputs("ERROR: could not allocate object private data.\n", stderr);
+ return;
+ }
+ evas_object_smart_data_set(o, priv);
+ }
+ priv->pad.h = 0;
+ priv->pad.v = 0;
+ priv->align.h = 0.5;
+ priv->align.v = 0.5;
+ priv->size.cols = 0;
+ priv->size.rows = 0;
+ priv->homogeneous = EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE;
+ priv->hints_changed = 1;
+ priv->expand_h = 0;
+ priv->expand_v = 0;
+
+ _parent_sc.add(o);
+}
+
+static void
+_evas_object_table_smart_del(Evas_Object *o)
+{
+ EVAS_OBJECT_TABLE_DATA_GET(o, priv);
+ Eina_List *l;
+
+ l = priv->children;
+ while (l)
+ {
+ Evas_Object_Table_Option *opt = l->data;
+ _evas_object_table_child_disconnect(o, opt->obj);
+ _evas_object_table_option_del(opt->obj);
+ free(opt);
+ l = eina_list_remove_list(l, l);
+ }
+
+ _parent_sc.del(o);
+}
+
+static void
+_evas_object_table_smart_resize(Evas_Object *o, int w, int h)
+{
+ evas_object_smart_changed(o);
+}
+
+static void
+_evas_object_table_smart_calculate(Evas_Object *o)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, priv);
+
+ if ((priv->size.cols < 1) || (priv->size.rows < 1))
+ {
+ fprintf(stderr, "DBG: nothing to do: cols=%d, rows=%d\n",
+ priv->size.cols, priv->size.rows);
+ return;
+ }
+
+ if (priv->homogeneous)
+ _evas_object_table_smart_calculate_homogeneous(o, priv);
+ else
+ _evas_object_table_smart_calculate_regular(o, priv);
+}
+
+static Evas_Smart *
+_evas_object_table_smart_class_new(void)
+{
+ static Evas_Smart_Class sc = {
+ "Evas_Object_Table", EVAS_SMART_CLASS_VERSION,
+ };
+
+ if (!_parent_sc.name)
+ evas_object_table_smart_set(&sc);
+
+ return evas_smart_class_new(&sc);
+}
+
+/**
+ * Create a new table.
+ *
+ * It's set to non-homogeneous by default, add children with
+ * evas_object_table_pack().
+ */
+Evas_Object *
+evas_object_table_add(Evas *evas)
+{
+ Evas_Object *o;
+ Evas_Smart *smart;
+
+ if (!smart)
+ smart = _evas_object_table_smart_class_new();
+
+ o = evas_object_smart_add(evas, smart);
+ return o;
+}
+
+/**
+ * Create a table that is child of a given element @a parent.
+ *
+ * @see evas_object_table_add()
+ */
+Evas_Object *
+evas_object_table_add_to(Evas_Object *parent)
+{
+ Evas *evas;
+ Evas_Object *o;
+
+ evas = evas_object_evas_get(parent);
+ o = evas_object_table_add(evas);
+ evas_object_smart_member_add(o, parent);
+ return o;
+}
+
+/**
+ * Set the default table @a api struct (Evas_Smart_Class)
+ * with the default values. May be used to extend that API.
+ */
+void
+evas_object_table_smart_set(Evas_Smart_Class *sc)
+{
+ if (!sc)
+ return;
+
+ if (!_parent_sc.name)
+ evas_object_smart_clipped_smart_set(&_parent_sc);
+
+ sc->add = _evas_object_table_smart_add;
+ sc->del = _evas_object_table_smart_del;
+ sc->move = _parent_sc.move;
+ sc->resize = _evas_object_table_smart_resize;
+ sc->show = _parent_sc.show;
+ sc->hide = _parent_sc.hide;
+ sc->color_set = _parent_sc.color_set;
+ sc->clip_set = _parent_sc.clip_set;
+ sc->clip_unset = _parent_sc.clip_unset;
+ sc->calculate = _evas_object_table_smart_calculate;
+ sc->member_add = _parent_sc.member_add;
+ sc->member_del = _parent_sc.member_del;
+}
+
+/**
+ * Set how this table should layout children.
+ *
+ * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_NONE
+ * If table does not use homogeneous mode then columns and rows will
+ * be calculated based on hints of individual cells. This operation
+ * mode is more flexible, but more complex and heavy to calculate as
+ * well.
+ *
+ * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE
+ * When homogeneous is relative to table the own table size is divided
+ * equally among children, filling the whole table area. That is, if
+ * table has @c WIDTH and @c COLUMNS, each cell will get WIDTH /
+ * COLUMNS pixels. If children have minimum size that is larger
+ * than this amount (including padding), then it will overflow and be
+ * aligned respecting the alignment hint, possible overlapping sibling
+ * cells. @b Weight hint is used as a boolean, if greater than zero it
+ * will make the child expand in that axis, taking as much space as
+ * possible (bounded to maximum size hint). Negative alignment will be
+ * considered as 0.5.
+ *
+ * @par EVAS_OBJECT_TABLE_HOMOGENEOUS_ITEM
+ * When homogeneous is relative to item it means the greatest minimum
+ * cell size will be used. That is, if no element is set to expand,
+ * the table will have its contents to a minimum size, the bounding
+ * box of all these children will be aligned relatively to the table
+ * object using evas_object_table_align_get(). If the table area is
+ * too small to hold this minimum bounding box, then the objects will
+ * keep their size and the bounding box will overflow the box area,
+ * still respecting the alignment. @b Weight hint is used as a
+ * boolean, if greater than zero it will make that cell expand in that
+ * axis, toggling the expand mode, which makes the table behave
+ * much like @b EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE, except that the
+ * bounding box will overflow and items will not overlap siblings. If
+ * no minimum size is provided at all then the table will fallback to
+ * expand mode as well.
+ */
+void
+evas_object_table_homogeneous_set(Evas_Object *o, Evas_Object_Table_Homogeneous_Mode homogeneous)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, priv);
+ if (priv->homogeneous == homogeneous)
+ return;
+ priv->homogeneous = homogeneous;
+ priv->hints_changed = 1;
+ evas_object_smart_changed(o);
+}
+
+/**
+ * Get the current layout homogeneous mode.
+ *
+ * @see evas_object_table_homogeneous_set()
+ */
+Evas_Object_Table_Homogeneous_Mode
+evas_object_table_homogeneous_get(const Evas_Object *o)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, priv, 0);
+ return priv->homogeneous;
+}
+
+/**
+ * Set the alignment of the whole bounding box of contents.
+ */
+void
+evas_object_table_align_set(Evas_Object *o, double horizontal, double vertical)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, priv);
+ if (priv->align.h == horizontal && priv->align.v == vertical)
+ return;
+ priv->align.h = horizontal;
+ priv->align.v = vertical;
+ evas_object_smart_changed(o);
+}
+
+/**
+ * Get alignment of the whole bounding box of contents.
+ */
+void
+evas_object_table_align_get(const Evas_Object *o, double *horizontal, double *vertical)
+{
+ EVAS_OBJECT_TABLE_DATA_GET(o, priv);
+ if (priv)
+ {
+ if (horizontal) *horizontal = priv->align.h;
+ if (vertical) *vertical = priv->align.v;
+ }
+ else
+ {
+ if (horizontal) *horizontal = 0.5;
+ if (vertical) *vertical = 0.5;
+ }
+}
+
+/**
+ * Set padding between cells.
+ */
+void
+evas_object_table_padding_set(Evas_Object *o, Evas_Coord horizontal, Evas_Coord vertical)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, priv);
+ if (priv->pad.h == horizontal && priv->pad.v == vertical)
+ return;
+ priv->pad.h = horizontal;
+ priv->pad.v = vertical;
+ evas_object_smart_changed(o);
+}
+
+/**
+ * Get padding between cells.
+ */
+void
+evas_object_table_padding_get(const Evas_Object *o, Evas_Coord *horizontal, Evas_Coord *vertical)
+{
+ EVAS_OBJECT_TABLE_DATA_GET(o, priv);
+ if (priv)
+ {
+ if (horizontal) *horizontal = priv->pad.h;
+ if (vertical) *vertical = priv->pad.v;
+ }
+ else
+ {
+ if (horizontal) *horizontal = 0;
+ if (vertical) *vertical = 0;
+ }
+}
+
+/**
+ * Add a new child to table.
+ *
+ * @param col relative-horizontal position to place child.
+ * @param row relative-vertical position to place child.
+ * @param colspan how many relative-horizontal position to use for this child.
+ * @param rowspan how many relative-vertical position to use for this child.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+Evas_Bool
+evas_object_table_pack(Evas_Object *o, Evas_Object *child, unsigned short col, unsigned short row, unsigned short colspan, unsigned short rowspan)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, priv, 0);
+ Evas_Object_Table_Option *opt;
+
+ if (rowspan < 1)
+ {
+ fputs("ERROR: rowspan < 1\n", stderr);
+ return 0;
+ }
+ if (colspan < 1)
+ {
+ fputs("ERROR: colspan < 1\n", stderr);
+ return 0;
+ }
+
+ opt = _evas_object_table_option_get(child);
+ if (opt)
+ {
+ fputs("ERROR: cannot add object that is already part of a table!\n",
+ stderr);
+ return 0;
+ }
+
+ opt = malloc(sizeof(*opt));
+ if (!opt)
+ {
+ fputs("ERROR: could not allocate table option data.\n", stderr);
+ return 0;
+ }
+
+ opt->obj = child;
+ opt->col = col;
+ opt->row = row;
+ opt->colspan = colspan;
+ opt->rowspan = rowspan;
+ opt->end_col = col + colspan;
+ opt->end_row = row + rowspan;
+ opt->min.w = 0;
+ opt->min.h = 0;
+ opt->max.w = 0;
+ opt->max.h = 0;
+ opt->align.h = 0.5;
+ opt->align.v = 0.5;
+ opt->pad.l = 0;
+ opt->pad.r = 0;
+ opt->pad.t = 0;
+ opt->pad.b = 0;
+ opt->expand_h = 0;
+ opt->expand_v = 0;
+
+ priv->children = eina_list_append(priv->children, opt);
+
+ if (priv->size.cols < opt->end_col)
+ priv->size.cols = opt->end_col;
+ if (priv->size.rows < opt->end_row)
+ priv->size.rows = opt->end_row;
+
+ _evas_object_table_option_set(child, opt);
+ evas_object_smart_member_add(child, o);
+ _evas_object_table_child_connect(o, child);
+ priv->hints_changed = 1;
+ evas_object_smart_changed(o);
+
+ return 1;
+}
+
+static void
+_evas_object_table_remove_opt(Evas_Object_Table_Data *priv, Evas_Object_Table_Option *opt)
+{
+ Eina_List *l;
+ int max_row, max_col, was_greatest;
+
+ max_row = 0;
+ max_col = 0;
+ was_greatest = 0;
+ l = priv->children;
+ while (l)
+ {
+ Evas_Object_Table_Option *cur_opt = l->data;
+
+ if (cur_opt != opt)
+ {
+ if (max_col < cur_opt->end_col)
+ max_col = cur_opt->end_col;
+ if (max_row < cur_opt->end_row)
+ max_row = cur_opt->end_row;
+
+ l = l->next;
+ }
+ else
+ {
+ Eina_List *tmp = l->next;
+ priv->children = eina_list_remove_list(priv->children, l);
+
+ if ((priv->size.cols > opt->end_col) &&
+ (priv->size.rows > opt->end_row))
+ break;
+ else
+ {
+ was_greatest = 1;
+ l = tmp;
+ }
+ }
+ }
+
+ if (was_greatest)
+ {
+ priv->size.cols = max_col;
+ priv->size.rows = max_row;
+ }
+}
+
+/**
+ * Remove child from table.
+ *
+ * @note removing a child will immediately call a walk over children in order
+ * to recalculate numbers of columns and rows. If you plan to remove
+ * all children, use evas_object_table_clear() instead.
+ *
+ * @return 1 on success, 0 on failure.
+ */
+Evas_Bool
+evas_object_table_unpack(Evas_Object *o, Evas_Object *child)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN_VAL(o, priv, 0);
+ Evas_Object_Table_Option *opt;
+
+ if (o != evas_object_smart_parent_get(child))
+ {
+ fputs("ERROR: cannot unpack child from incorrect table!\n", stderr);
+ return;
+ }
+
+ opt = _evas_object_table_option_del(child);
+ if (!opt)
+ {
+ fputs("ERROR: cannot unpack child with no packing option!\n", stderr);
+ return;
+ }
+
+ _evas_object_table_child_disconnect(o, child);
+ _evas_object_table_remove_opt(priv, opt);
+ evas_object_smart_member_del(child);
+ free(opt);
+ priv->hints_changed = 1;
+ evas_object_smart_changed(o);
+
+ return 1;
+}
+
+/**
+ * Faster way to remove all child objects.
+ *
+ * @param delete if true, it will delete just removed children.
+ */
+void
+evas_object_table_clear(Evas_Object *o, Evas_Bool delete)
+{
+ EVAS_OBJECT_TABLE_DATA_GET_OR_RETURN(o, priv);
+ Eina_List *l;
+
+ l = priv->children;
+ while (l)
+ {
+ Evas_Object_Table_Option *opt = l->data;
+ _evas_object_table_child_disconnect(o, opt->obj);
+ _evas_object_table_option_del(opt->obj);
+ evas_object_smart_member_del(opt->obj);
+ if (delete)
+ evas_object_del(opt->obj);
+ free(opt);
+ l = eina_list_remove_list(l, l);
+ }
+ priv->children = NULL;
+ priv->size.cols = 0;
+ priv->size.rows = 0;
+ evas_object_smart_changed(o);
+}
+
+/**
+ * Get the number of columns and rows this table takes.
+ *
+ * @note columns and rows are virtual entities, one can specify a table
+ * with a single object that takes 4 columns and 5 rows. The only
+ * difference for a single cell table is that paddings will be
+ * accounted proportionally.
+ */
+void
+evas_object_table_col_row_size_get(const Evas_Object *o, int *cols, int *rows)
+{
+ EVAS_OBJECT_TABLE_DATA_GET(o, priv);
+ if (priv)
+ {
+ if (cols) *cols = priv->size.cols;
+ if (rows) *rows = priv->size.rows;
+ }
+ else
+ {
+ if (cols) *cols = -1;
+ if (rows) *rows = -1;
+ }
+}