elementary/map - map supports language,changed
[framework/uifw/elementary.git] / src / lib / elm_table.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_table.h"
4
5 EAPI const char ELM_TABLE_SMART_NAME[] = "elm_table";
6
7 EVAS_SMART_SUBCLASS_NEW
8   (ELM_TABLE_SMART_NAME, _elm_table, Elm_Table_Smart_Class,
9   Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
10
11 static Eina_Bool
12 _elm_table_smart_focus_next(const Evas_Object *obj,
13                             Elm_Focus_Direction dir,
14                             Evas_Object **next)
15 {
16    Eina_Bool ret;
17    const Eina_List *items;
18    Eina_List *(*list_free)(Eina_List *list);
19    void *(*list_data_get)(const Eina_List *list);
20
21    ELM_TABLE_DATA_GET(obj, sd);
22
23    /* Focus chain */
24    /* TODO: Change this to use other chain */
25    if ((items = elm_widget_focus_custom_chain_get(obj)))
26      {
27         list_data_get = eina_list_data_get;
28         list_free = NULL;
29      }
30    else
31      {
32         items = evas_object_table_children_get
33             (ELM_WIDGET_DATA(sd)->resize_obj);
34         list_data_get = eina_list_data_get;
35         list_free = eina_list_free;
36
37         if (!items) return EINA_FALSE;
38      }
39
40    ret = elm_widget_focus_list_next_get(obj, items, list_data_get, dir, next);
41
42    if (list_free) list_free((Eina_List *)items);
43
44    return ret;
45 }
46
47 static Eina_Bool
48 _elm_table_smart_focus_direction(const Evas_Object *obj,
49                                  const Evas_Object *base,
50                                  double degree,
51                                  Evas_Object **direction,
52                                  double *weight)
53 {
54    Eina_Bool ret;
55    const Eina_List *items;
56    Eina_List *(*list_free)(Eina_List *list);
57    void *(*list_data_get)(const Eina_List *list);
58
59    ELM_TABLE_DATA_GET(obj, sd);
60
61    /* Focus chain */
62    /* TODO: Change this to use other chain */
63    if ((items = elm_widget_focus_custom_chain_get(obj)))
64      {
65         list_data_get = eina_list_data_get;
66         list_free = NULL;
67      }
68    else
69      {
70         items = evas_object_table_children_get
71             (ELM_WIDGET_DATA(sd)->resize_obj);
72         list_data_get = eina_list_data_get;
73         list_free = eina_list_free;
74
75         if (!items) return EINA_FALSE;
76      }
77
78    ret = elm_widget_focus_list_direction_get
79        (obj, base, items, list_data_get, degree, direction, weight);
80
81    if (list_free)
82      list_free((Eina_List *)items);
83
84    return ret;
85 }
86
87 static void
88 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
89 {
90    ELM_TABLE_DATA_GET(obj, sd);
91
92    evas_object_table_mirrored_set(ELM_WIDGET_DATA(sd)->resize_obj, rtl);
93 }
94
95 static Eina_Bool
96 _elm_table_smart_theme(Evas_Object *obj)
97 {
98    if (!_elm_table_parent_sc->theme(obj)) return EINA_FALSE;
99
100    _mirrored_set(obj, elm_widget_mirrored_get(obj));
101
102    return EINA_TRUE;
103 }
104
105 static void
106 _sizing_eval(Evas_Object *obj)
107 {
108    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
109    Evas_Coord w, h;
110
111    ELM_TABLE_DATA_GET(obj, sd);
112
113    evas_object_size_hint_min_get
114      (ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
115    evas_object_size_hint_max_get
116      (ELM_WIDGET_DATA(sd)->resize_obj, &maxw, &maxh);
117    evas_object_size_hint_min_set(obj, minw, minh);
118    evas_object_size_hint_max_set(obj, maxw, maxh);
119    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
120    if (w < minw) w = minw;
121    if (h < minh) h = minh;
122    if ((maxw >= 0) && (w > maxw)) w = maxw;
123    if ((maxh >= 0) && (h > maxh)) h = maxh;
124    evas_object_resize(obj, w, h);
125 }
126
127 static void
128 _on_size_hints_changed(void *data,
129                        Evas *e __UNUSED__,
130                        Evas_Object *obj __UNUSED__,
131                        void *event_info __UNUSED__)
132 {
133    _sizing_eval(data);
134 }
135
136 static Eina_Bool
137 _elm_table_smart_sub_object_del(Evas_Object *obj,
138                                 Evas_Object *child)
139 {
140    if (!_elm_table_parent_sc->sub_object_del(obj, child)) return EINA_FALSE;
141
142    _sizing_eval(obj);
143
144    return EINA_TRUE;
145 }
146
147 static void
148 _elm_table_smart_add(Evas_Object *obj)
149 {
150    EVAS_SMART_DATA_ALLOC(obj, Elm_Widget_Smart_Data);
151
152    priv->resize_obj = evas_object_table_add(evas_object_evas_get(obj));
153
154    evas_object_event_callback_add
155      (priv->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
156      _on_size_hints_changed, obj);
157
158    _elm_table_parent_sc->base.add(obj);
159
160    elm_widget_can_focus_set(obj, EINA_FALSE);
161    elm_widget_highlight_ignore_set(obj, EINA_FALSE);
162
163    _elm_table_smart_theme(obj);
164 }
165
166 static void
167 _elm_table_smart_del(Evas_Object *obj)
168 {
169    Eina_List *l;
170    Evas_Object *child;
171
172    ELM_TABLE_DATA_GET(obj, sd);
173
174    evas_object_event_callback_del_full
175      (ELM_WIDGET_DATA(sd)->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
176      _on_size_hints_changed, obj);
177
178    /* let's make our table object the *last* to be processed, since it
179     * may (smart) parent other sub objects here */
180    EINA_LIST_FOREACH(ELM_WIDGET_DATA(sd)->subobjs, l, child)
181      {
182         if (child == ELM_WIDGET_DATA(sd)->resize_obj)
183           {
184              ELM_WIDGET_DATA(sd)->subobjs =
185                eina_list_demote_list(ELM_WIDGET_DATA(sd)->subobjs, l);
186              break;
187           }
188      }
189
190    _elm_table_parent_sc->base.del(obj);
191 }
192
193 static void
194 _elm_table_smart_set_user(Elm_Table_Smart_Class *sc)
195 {
196    ELM_WIDGET_CLASS(sc)->base.add = _elm_table_smart_add;
197    ELM_WIDGET_CLASS(sc)->base.del = _elm_table_smart_del;
198    ELM_WIDGET_CLASS(sc)->sub_object_del = _elm_table_smart_sub_object_del;
199    ELM_WIDGET_CLASS(sc)->theme = _elm_table_smart_theme;
200    ELM_WIDGET_CLASS(sc)->focus_next = _elm_table_smart_focus_next;
201    ELM_WIDGET_CLASS(sc)->focus_direction = _elm_table_smart_focus_direction;
202 }
203
204 EAPI const Elm_Table_Smart_Class *
205 elm_table_smart_class_get(void)
206 {
207    static Elm_Table_Smart_Class _sc =
208      ELM_TABLE_SMART_CLASS_INIT_NAME_VERSION(ELM_TABLE_SMART_NAME);
209    static const Elm_Table_Smart_Class *class = NULL;
210
211    if (class) return class;
212
213    _elm_table_smart_set(&_sc);
214    class = &_sc;
215
216    return class;
217 }
218
219 EAPI Evas_Object *
220 elm_table_add(Evas_Object *parent)
221 {
222    Evas_Object *obj;
223
224    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
225
226    obj = elm_widget_add(_elm_table_smart_class_new(), parent);
227    if (!obj) return NULL;
228
229    if (!elm_widget_sub_object_add(parent, obj))
230      ERR("could not add %p as sub object of %p", obj, parent);
231
232    return obj;
233 }
234
235 EAPI void
236 elm_table_homogeneous_set(Evas_Object *obj,
237                           Eina_Bool homogeneous)
238 {
239    ELM_TABLE_CHECK(obj);
240    ELM_TABLE_DATA_GET(obj, sd);
241
242    evas_object_table_homogeneous_set
243      (ELM_WIDGET_DATA(sd)->resize_obj, homogeneous);
244 }
245
246 EAPI Eina_Bool
247 elm_table_homogeneous_get(const Evas_Object *obj)
248 {
249    ELM_TABLE_CHECK(obj) EINA_FALSE;
250    ELM_TABLE_DATA_GET(obj, sd);
251
252    return evas_object_table_homogeneous_get(ELM_WIDGET_DATA(sd)->resize_obj);
253 }
254
255 EAPI void
256 elm_table_padding_set(Evas_Object *obj,
257                       Evas_Coord horizontal,
258                       Evas_Coord vertical)
259 {
260    ELM_TABLE_CHECK(obj);
261    ELM_TABLE_DATA_GET(obj, sd);
262
263    evas_object_table_padding_set
264      (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
265 }
266
267 EAPI void
268 elm_table_padding_get(const Evas_Object *obj,
269                       Evas_Coord *horizontal,
270                       Evas_Coord *vertical)
271 {
272    ELM_TABLE_CHECK(obj);
273    ELM_TABLE_DATA_GET(obj, sd);
274
275    evas_object_table_padding_get
276      (ELM_WIDGET_DATA(sd)->resize_obj, horizontal, vertical);
277 }
278
279 EAPI void
280 elm_table_pack(Evas_Object *obj,
281                Evas_Object *subobj,
282                int x,
283                int y,
284                int w,
285                int h)
286 {
287    ELM_TABLE_CHECK(obj);
288    ELM_TABLE_DATA_GET(obj, sd);
289
290    elm_widget_sub_object_add(obj, subobj);
291    evas_object_table_pack(ELM_WIDGET_DATA(sd)->resize_obj, subobj, x, y, w, h);
292 }
293
294 EAPI void
295 elm_table_unpack(Evas_Object *obj,
296                  Evas_Object *subobj)
297 {
298    ELM_TABLE_CHECK(obj);
299    ELM_TABLE_DATA_GET(obj, sd);
300
301    elm_widget_sub_object_del(obj, subobj);
302    evas_object_table_unpack(ELM_WIDGET_DATA(sd)->resize_obj, subobj);
303 }
304
305 EAPI void
306 elm_table_pack_set(Evas_Object *subobj,
307                    int x,
308                    int y,
309                    int w,
310                    int h)
311 {
312    Evas_Object *obj = elm_widget_parent_widget_get(subobj);
313
314    ELM_TABLE_CHECK(obj);
315    ELM_TABLE_DATA_GET(obj, sd);
316
317    evas_object_table_pack(ELM_WIDGET_DATA(sd)->resize_obj, subobj, x, y, w, h);
318 }
319
320 EAPI void
321 elm_table_pack_get(Evas_Object *subobj,
322                    int *x,
323                    int *y,
324                    int *w,
325                    int *h)
326 {
327    Evas_Object *obj = elm_widget_parent_widget_get(subobj);
328    unsigned short ix, iy, iw, ih;
329
330    ELM_TABLE_CHECK(obj);
331    ELM_TABLE_DATA_GET(obj, sd);
332
333    evas_object_table_pack_get
334      (ELM_WIDGET_DATA(sd)->resize_obj, subobj, &ix, &iy, &iw, &ih);
335    if (x) *x = ix;
336    if (y) *y = iy;
337    if (w) *w = iw;
338    if (h) *h = ih;
339 }
340
341 EAPI void
342 elm_table_clear(Evas_Object *obj,
343                 Eina_Bool clear)
344 {
345    ELM_TABLE_CHECK(obj);
346    ELM_TABLE_DATA_GET(obj, sd);
347
348    evas_object_table_clear(ELM_WIDGET_DATA(sd)->resize_obj, clear);
349 }