elementary/theme, widget, win, toolbar, thumb, toggle, util, box - removed white...
[framework/uifw/elementary.git] / src / lib / elm_table.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Table Table
6  *
7  * Arranges widgets in a table where items can also span multiple
8  * columns or rows - even overlap (and then be raised or lowered
9  * accordingly to adjust stacking if they do overlap).
10  */
11
12 typedef struct _Widget_Data Widget_Data;
13
14 struct _Widget_Data
15 {
16    Evas_Object *tbl;
17 };
18
19 static const char *widtype = NULL;
20 static void _del_hook(Evas_Object *obj);
21 static void _sizing_eval(Evas_Object *obj);
22 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
23 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
24 static void _theme_hook(Evas_Object *obj);
25
26 static void
27 _del_pre_hook(Evas_Object *obj)
28 {
29    Widget_Data *wd = elm_widget_data_get(obj);
30    if (!wd) return;
31    evas_object_event_callback_del_full
32      (wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
33    evas_object_del(wd->tbl);
34 }
35
36 static void
37 _del_hook(Evas_Object *obj)
38 {
39    Widget_Data *wd = elm_widget_data_get(obj);
40    if (!wd) return;
41    free(wd);
42 }
43
44 static Eina_Bool
45 _elm_table_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
46 {
47    Widget_Data *wd = elm_widget_data_get(obj);
48    const Eina_List *items;
49    void *(*list_data_get) (const Eina_List *list);
50    Eina_List *(*list_free) (Eina_List *list);
51
52    if ((!wd) || (!wd->tbl))
53      return EINA_FALSE;
54
55    /* Focus chain */
56    /* TODO: Change this to use other chain */
57    if ((items = elm_widget_focus_custom_chain_get(obj)))
58      {
59         list_data_get = eina_list_data_get;
60         list_free = NULL;
61      }
62    else
63      {
64         items = evas_object_table_children_get(wd->tbl);
65         list_data_get = eina_list_data_get;
66         list_free = eina_list_free;
67
68         if (!items) return EINA_FALSE;
69      }
70
71    Eina_Bool ret = elm_widget_focus_list_next_get(obj, items, list_data_get,
72                                                    dir, next);
73
74    if (list_free)
75      list_free((Eina_List *)items);
76
77    return ret;
78 }
79
80 static void
81 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
82 {
83    Widget_Data *wd = elm_widget_data_get(obj);
84    if ((!wd) || (!wd->tbl))
85      return;
86
87    evas_object_table_mirrored_set(wd->tbl, rtl);
88 }
89
90 static void
91 _theme_hook(Evas_Object *obj)
92 {
93    _elm_widget_mirrored_reload(obj);
94    _mirrored_set(obj, elm_widget_mirrored_get(obj));
95 }
96
97 static void
98 _sizing_eval(Evas_Object *obj)
99 {
100    Widget_Data *wd = elm_widget_data_get(obj);
101    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
102    Evas_Coord w, h;
103    if (!wd) return;
104    evas_object_size_hint_min_get(wd->tbl, &minw, &minh);
105    evas_object_size_hint_max_get(wd->tbl, &maxw, &maxh);
106    evas_object_size_hint_min_set(obj, minw, minh);
107    evas_object_size_hint_max_set(obj, maxw, maxh);
108    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
109    if (w < minw) w = minw;
110    if (h < minh) h = minh;
111    if ((maxw >= 0) && (w > maxw)) w = maxw;
112    if ((maxh >= 0) && (h > maxh)) h = maxh;
113    evas_object_resize(obj, w, h);
114 }
115
116 static void
117 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
118 {
119    _sizing_eval(data);
120 }
121
122 static void
123 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
124 {
125    _sizing_eval(obj);
126 }
127
128 /**
129  * Add a new table to the parent
130  *
131  * @param parent The parent object
132  * @return The new object or NULL if it cannot be created
133  *
134  * @ingroup Table
135  */
136 EAPI Evas_Object *
137 elm_table_add(Evas_Object *parent)
138 {
139    Evas_Object *obj;
140    Evas *e;
141    Widget_Data *wd;
142
143    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
144
145    ELM_SET_WIDTYPE(widtype, "table");
146    elm_widget_type_set(obj, "table");
147    elm_widget_sub_object_add(parent, obj);
148    elm_widget_data_set(obj, wd);
149    elm_widget_del_hook_set(obj, _del_hook);
150    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
151    elm_widget_focus_next_hook_set(obj, _elm_table_focus_next_hook);
152    elm_widget_can_focus_set(obj, EINA_FALSE);
153    elm_widget_highlight_ignore_set(obj, EINA_FALSE);
154    elm_widget_theme_hook_set(obj, _theme_hook);
155
156    wd->tbl = evas_object_table_add(e);
157    evas_object_event_callback_add(wd->tbl, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
158                                   _changed_size_hints, obj);
159    elm_widget_resize_object_set(obj, wd->tbl);
160
161    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
162
163    _mirrored_set(obj, elm_widget_mirrored_get(obj));
164    return obj;
165 }
166
167 /**
168  * Set the homogenous layout in the table
169  *
170  * @param obj The layout object
171  * @param homogenous A boolean to set (or no) layout homogenous
172  * in the table
173  * (1 = homogenous,  0 = no homogenous)
174  *
175  * @ingroup Table
176  */
177 EAPI void
178 elm_table_homogenous_set(Evas_Object *obj, Eina_Bool homogenous)
179 {
180    ELM_CHECK_WIDTYPE(obj, widtype);
181    Widget_Data *wd = elm_widget_data_get(obj);
182    if (!wd) return;
183    evas_object_table_homogeneous_set(wd->tbl, homogenous);
184 }
185
186 /**
187  * Get the current table homogenous mode.
188  *
189  * @param obj The table object
190  * @return a boolean to set (or no) layout homogenous in the table
191  * (1 = homogenous,  0 = no homogenous)
192  *
193  * @ingroup Table
194  */
195 EAPI Eina_Bool
196 elm_table_homogenous_get(const Evas_Object *obj)
197 {
198    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
199    Widget_Data *wd = elm_widget_data_get(obj);
200    if (!wd) return EINA_FALSE;
201    return evas_object_table_homogeneous_get(wd->tbl);
202 }
203
204 /**
205  * Set padding between cells.
206  *
207  * @param obj The layout object.
208  * @param horizontal set the horizontal padding.
209  * @param vertical set the vertical padding.
210  *
211  * @ingroup Table
212  */
213 EAPI void
214 elm_table_padding_set(Evas_Object *obj, Evas_Coord horizontal, Evas_Coord vertical)
215 {
216    ELM_CHECK_WIDTYPE(obj, widtype);
217    Widget_Data *wd = elm_widget_data_get(obj);
218    if (!wd) return;
219    evas_object_table_padding_set(wd->tbl, horizontal, vertical);
220 }
221
222 /**
223  * Get padding between cells.
224  *
225  * @param obj The layout object.
226  * @param horizontal set the horizontal padding.
227  * @param vertical set the vertical padding.
228  *
229  * @ingroup Table
230  */
231 EAPI void
232 elm_table_padding_get(const Evas_Object *obj, Evas_Coord *horizontal, Evas_Coord *vertical)
233 {
234    ELM_CHECK_WIDTYPE(obj, widtype);
235    Widget_Data *wd = elm_widget_data_get(obj);
236    if (!wd) return;
237    evas_object_table_padding_get(wd->tbl, horizontal, vertical);
238 }
239
240 /**
241  * Add a subobject on the table with the coordinates passed
242  *
243  * @param obj The table object
244  * @param subobj The subobject to be added to the table
245  * @param x Coordinate to X axis
246  * @param y Coordinate to Y axis
247  * @param w Horizontal length
248  * @param h Vertical length
249  *
250  * @ingroup Table
251  */
252 EAPI void
253 elm_table_pack(Evas_Object *obj, Evas_Object *subobj, int x, int y, int w, int h)
254 {
255    ELM_CHECK_WIDTYPE(obj, widtype);
256    Widget_Data *wd = elm_widget_data_get(obj);
257    if (!wd) return;
258    elm_widget_sub_object_add(obj, subobj);
259    evas_object_table_pack(wd->tbl, subobj, x, y, w, h);
260 }
261
262 /**
263  * Remove child from table.
264  *
265  * @param obj The table object
266  * @param subobj The subobject
267  *
268  * @ingroup Table
269  */
270 EAPI void
271 elm_table_unpack(Evas_Object *obj, Evas_Object *subobj)
272 {
273    ELM_CHECK_WIDTYPE(obj, widtype);
274    Widget_Data *wd = elm_widget_data_get(obj);
275    if (!wd) return;
276    elm_widget_sub_object_del(obj, subobj);
277    evas_object_table_unpack(wd->tbl, subobj);
278 }
279
280 /**
281  * Faster way to remove all child objects from a table object.
282  *
283  * @param obj The table object
284  * @param clear If true, it will delete just removed children
285  *
286  * @ingroup Table
287  */
288 EAPI void
289 elm_table_clear(Evas_Object *obj, Eina_Bool clear)
290 {
291    ELM_CHECK_WIDTYPE(obj, widtype);
292    Widget_Data *wd = elm_widget_data_get(obj);
293    if (!wd) return;
294    evas_object_table_clear(wd->tbl, clear);
295 }