Tizen 2.1 release
[platform/core/uifw/e17.git] / src / bin / e_widget_deskpreview.c
1 #include "e.h"
2
3 typedef struct _E_Widget_Data E_Widget_Data;
4 struct _E_Widget_Data
5 {
6    Evas_Object         *obj, *table;
7    Eina_List           *desks;
8    int                  w, h, dx, dy, cx, cy;
9 };
10 typedef struct _E_Widget_Desk_Data E_Widget_Desk_Data;
11 struct _E_Widget_Desk_Data
12 {
13    Evas_Object *icon, *thumb;
14    int          zone, con, x, y;
15    Ecore_Event_Handler *bg_upd_hdl;
16    Eina_Bool configurable : 1;
17 };
18
19 /* local function prototypes */
20 static void      _e_wid_data_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__);
21 static void      _e_wid_del_hook(Evas_Object *obj);
22 static void      _e_wid_reconfigure(E_Widget_Data *wd);
23 static void      _e_wid_desk_cb_config(void *data, Evas *evas, Evas_Object *obj, void *event);
24 static void      _e_wid_cb_resize(void *data, Evas *evas, Evas_Object *obj, void *event);
25 static Eina_Bool _e_wid_cb_bg_update(void *data, int type, void *event);
26
27 EAPI Evas_Object *
28 e_widget_deskpreview_add(Evas *evas, int nx, int ny)
29 {
30    Evas_Object *obj;
31    E_Widget_Data *wd;
32
33    obj = e_widget_add(evas);
34    wd = E_NEW(E_Widget_Data, 1);
35    wd->obj = obj;
36    wd->dx = nx;
37    wd->dy = ny;
38    e_widget_data_set(obj, wd);
39    e_widget_del_hook_set(obj, _e_wid_del_hook);
40
41    wd->table = evas_object_table_add(evas);
42    evas_object_table_padding_set(wd->table, 0, 0);
43    evas_object_table_align_set(wd->table, 0.5, 0.5);
44    e_widget_resize_object_set(wd->obj, wd->table);
45    evas_object_show(wd->table);
46    e_widget_sub_object_add(wd->obj, wd->table);
47
48    e_widget_deskpreview_num_desks_set(obj, wd->dx, wd->dy);
49
50    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
51                                   _e_wid_cb_resize, NULL);
52    return obj;
53 }
54
55 EAPI void
56 e_widget_deskpreview_num_desks_set(Evas_Object *obj, int nx, int ny)
57 {
58    E_Widget_Data *wd;
59
60    if (!(wd = e_widget_data_get(obj))) return;
61    wd->dx = nx;
62    wd->dy = ny;
63    _e_wid_reconfigure(wd);
64 }
65
66 EAPI Evas_Object *
67 e_widget_deskpreview_desk_add(Evas_Object *obj, E_Zone *zone, int x, int y, int w, int h)
68 {
69    E_Widget_Desk_Data *dd;
70    const char *bgfile;
71
72    bgfile = e_bg_file_get(zone->container->num, zone->num, x, y);
73
74    dd = E_NEW(E_Widget_Desk_Data, 1);
75    dd->con = zone->container->num;
76    dd->zone = zone->num;
77    dd->x = x;
78    dd->y = y;
79
80    dd->icon = edje_object_add(evas_object_evas_get(obj));
81    e_theme_edje_object_set(dd->icon, "base/theme/widgets",
82                            "e/widgets/deskpreview/desk");
83
84    dd->thumb = e_icon_add(evas_object_evas_get(obj));
85    e_icon_fill_inside_set(dd->thumb, EINA_FALSE);
86    e_icon_file_edje_set(dd->thumb, bgfile, "e/desktop/background");
87    evas_object_show(dd->thumb);
88    edje_object_part_swallow(dd->icon, "e.swallow.content", dd->thumb);
89
90    evas_object_size_hint_min_set(dd->icon, w, h);
91    evas_object_size_hint_max_set(dd->icon, w, h);
92    evas_object_show(dd->icon);
93    evas_object_data_set(dd->icon, "desk_data", dd);
94    dd->configurable = EINA_TRUE;
95    evas_object_event_callback_add(dd->icon, EVAS_CALLBACK_FREE, _e_wid_data_del, dd);
96    evas_object_event_callback_add(dd->icon, EVAS_CALLBACK_MOUSE_DOWN,
97                                   _e_wid_desk_cb_config, dd);
98    dd->bg_upd_hdl = ecore_event_handler_add(E_EVENT_BG_UPDATE,
99                                             _e_wid_cb_bg_update, dd);
100
101    return dd->icon;
102 }
103
104 EAPI void
105 e_widget_deskpreview_desk_configurable_set(Evas_Object *obj, Eina_Bool enable)
106 {
107    E_Widget_Desk_Data *dd;
108
109    EINA_SAFETY_ON_NULL_RETURN(obj);
110    dd = evas_object_data_get(obj, "desk_data");
111    EINA_SAFETY_ON_NULL_RETURN(dd);
112    enable = !!enable;
113    if (dd->configurable == enable) return;
114    if (enable)
115      evas_object_event_callback_add(dd->icon, EVAS_CALLBACK_MOUSE_DOWN,
116                                     _e_wid_desk_cb_config, dd);
117    else
118      evas_object_event_callback_del_full(dd->icon, EVAS_CALLBACK_MOUSE_DOWN,
119                                          _e_wid_desk_cb_config, dd);
120    dd->configurable = enable;
121 }
122
123 /* local function prototypes */
124 static void
125 _e_wid_data_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
126 {
127    E_Widget_Desk_Data *dd;
128    dd = data;
129    if (!dd) return;
130    if (dd->bg_upd_hdl) ecore_event_handler_del(dd->bg_upd_hdl);
131    if (dd->thumb) evas_object_del(dd->thumb);
132    E_FREE(dd);
133 }
134
135 static void
136 _e_wid_del_hook(Evas_Object *obj)
137 {
138    E_Widget_Data *wd;
139    Evas_Object *o;
140
141    if (!(wd = e_widget_data_get(obj))) return;
142
143    EINA_LIST_FREE(wd->desks, o)
144      evas_object_del(o);
145
146    E_FREE(wd);
147 }
148
149 static void
150 _e_wid_reconfigure(E_Widget_Data *wd)
151 {
152    Eina_List *l, *ll;
153    Evas_Object *dw;
154    E_Zone *zone;
155    int tw, th, mw, mh, y;
156    E_Widget_Desk_Data *dd;
157    double zone_ratio, desk_ratio;
158
159    zone = e_util_zone_current_get(e_manager_current_get());
160
161    evas_object_geometry_get(wd->table, NULL, NULL, &tw, &th);
162    if ((tw == 0) || (th == 0))
163      {
164         mw = mh = 0;
165      }
166    else
167      {
168         zone_ratio = (double) zone->w / zone->h;
169         desk_ratio = (tw / wd->dx) / (th / wd->dy);
170
171         if (zone_ratio > desk_ratio)
172           {
173              mw = tw / wd->dx;
174              mh = mw / zone_ratio;
175           }
176         else
177           {
178              mh = th / wd->dy;
179              mw = mh * zone_ratio;
180           }
181      }
182
183    EINA_LIST_FOREACH_SAFE (wd->desks, l, ll, dw)
184      {
185         if (!(dd = evas_object_data_get(dw, "desk_data"))) continue;
186         if ((dd->x < wd->dx) && (dd->y < wd->dy))
187           {
188              evas_object_size_hint_min_set(dw, mw, mh);
189              evas_object_size_hint_max_set(dw, mw, mh);
190           }
191         else
192           {
193              evas_object_del(dd->thumb);
194              evas_object_del(dw);
195              wd->desks = eina_list_remove(wd->desks, dw);
196           }
197      }
198
199    for (y = 0; y < wd->dy; y++)
200      {
201         int x, sx;
202
203         if (y >= wd->cy) sx = 0;
204         else sx = wd->cx;
205         for (x = sx; x < wd->dx; x++)
206           {
207              Evas_Object *dp;
208
209              dp = e_widget_deskpreview_desk_add(wd->obj, zone, x, y, mw, mh);
210              evas_object_size_hint_aspect_set(dp, EVAS_ASPECT_CONTROL_BOTH, zone->w, zone->h);
211              evas_object_table_pack(wd->table, dp, x, y, 1, 1);
212              wd->desks = eina_list_append(wd->desks, dp);
213           }
214      }
215
216    wd->cx = wd->dx;
217    wd->cy = wd->dy;
218 }
219
220 static void
221 _e_wid_desk_cb_config(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event)
222 {
223    E_Widget_Desk_Data *dd;
224    Evas_Event_Mouse_Down *ev;
225
226    ev = event;
227    if (!(dd = data)) return;
228    if (ev->button == 1)
229      {
230         E_Container *con;
231         char buff[256];
232
233         con = e_container_current_get(e_manager_current_get());
234         snprintf(buff, sizeof(buff), "%i %i %i %i",
235                  dd->con, dd->zone, dd->x, dd->y);
236         e_configure_registry_call("internal/desk", con, buff);
237      }
238 }
239
240 static void
241 _e_wid_cb_resize(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event __UNUSED__)
242 {
243    E_Widget_Data *wd;
244
245    if (!(wd = e_widget_data_get(obj))) return;
246    _e_wid_reconfigure(wd);
247 }
248
249 static Eina_Bool
250 _e_wid_cb_bg_update(void *data, int type, void *event)
251 {
252    E_Event_Bg_Update *ev;
253    E_Widget_Desk_Data *dd;
254
255    if (type != E_EVENT_BG_UPDATE) return ECORE_CALLBACK_PASS_ON;
256    if (!(dd = data)) return ECORE_CALLBACK_PASS_ON;
257    ev = event;
258
259    if (((ev->container < 0) || (dd->con == ev->container)) &&
260        ((ev->zone < 0) || (dd->zone == ev->zone)) &&
261        ((ev->desk_x < 0) || (dd->x == ev->desk_x)) &&
262        ((ev->desk_y < 0) || (dd->y == ev->desk_y)))
263      {
264         const char *bgfile;
265
266         bgfile = e_bg_file_get(dd->con, dd->zone, dd->x, dd->y);
267         e_icon_file_edje_set(dd->thumb, bgfile, "e/desktop/background");
268      }
269
270    return ECORE_CALLBACK_PASS_ON;
271 }
272