62be2365fb01dd534cfadb3d34beb3fcd96dfe16
[apps/core/preloaded/quickpanel.git] / daemon / notifications / noti_listbox.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <Ecore_X.h>
18
19 #include "quickpanel-ui.h"
20 #include "common.h"
21 #include "list_util.h"
22 #include "quickpanel_def.h"
23 #include "noti_listbox.h"
24 #include "noti_list_item.h"
25
26 #define E_DATA_LAYOUT_PORTRAIT "layout_portrait"
27 #define E_DATA_LAYOUT_LANDSCAPE "layout_landscape"
28 #define E_DATA_CB_DELETE_ITEM "cb_delete_item"
29 #define E_DATA_CB_REMOVED "cb_removed"
30 #define E_DATA_APP_DATA "app_data"
31
32 typedef struct _listbox_info_layout {
33         int n_per_rows;
34         int padding_top;
35         int padding_left;
36         int padding_right;
37         int padding_bottom;
38         int padding_between;
39         int child_w;
40         int child_h;
41         double scale;
42 } listbox_info_layout;
43
44 typedef struct _listbox_info_animation {
45         Evas_Object *listbox;
46         Evas_Object *item;
47
48         void (*update_cb)(Evas_Object *list, void *data, int is_prepend);
49         Evas_Object *container;
50         void *noti;
51         int pos;
52 } listbox_info_animation;
53
54 Evas_Object *listbox_create(Evas_Object *parent, void *data) {
55         struct appdata *ad = data;
56         Evas_Object *listbox = NULL;
57
58         retif(parent == NULL, NULL, "invalid parameter");
59         retif(data == NULL, NULL, "invalid parameter");
60
61         listbox = elm_box_add(parent);
62         evas_object_size_hint_weight_set(listbox, EVAS_HINT_EXPAND,
63                         EVAS_HINT_EXPAND);
64         evas_object_size_hint_align_set(listbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
65         elm_box_horizontal_set(listbox, EINA_FALSE);
66         evas_object_show(listbox);
67
68         evas_object_data_set(listbox, E_DATA_CB_DELETE_ITEM, NULL);
69         evas_object_data_set(listbox, E_DATA_APP_DATA, ad);
70
71         qp_item_data *qid
72                 = quickpanel_list_util_item_new(QP_ITEM_TYPE_ONGOING_NOTI, NULL);
73         quickpanel_list_util_item_set_tag(listbox, qid);
74
75         return listbox;
76 }
77
78 void listbox_remove(Evas_Object *listbox) {
79
80         retif(listbox == NULL, , "invalid parameter");
81
82         listbox_remove_all_item(listbox, 0);
83         evas_object_data_del(listbox, E_DATA_CB_DELETE_ITEM);
84         evas_object_data_del(listbox, E_DATA_APP_DATA);
85         quickpanel_list_util_item_del_tag(listbox);
86         evas_object_del(listbox);
87 }
88
89 void listbox_set_item_deleted_cb(Evas_Object *listbox,
90                 void(*deleted_cb)(void *data, Evas_Object *obj)) {
91         retif(listbox == NULL, , "invalid parameter");
92         retif(deleted_cb == NULL, , "invalid parameter");
93
94         evas_object_data_set(listbox, E_DATA_CB_DELETE_ITEM, deleted_cb);
95 }
96
97 static void _listbox_call_item_deleted_cb(Evas_Object *listbox, void *data,
98                 Evas_Object *obj) {
99         retif(listbox == NULL, , "invalid parameter");
100
101         void (*deleted_cb)(void *data, Evas_Object *obj) = NULL;
102
103         deleted_cb = evas_object_data_get(listbox, E_DATA_CB_DELETE_ITEM);
104
105         if (deleted_cb != NULL) {
106                 deleted_cb(data, obj);
107         }
108 }
109
110 void listbox_add_item(Evas_Object *listbox, Evas_Object *item, int is_prepend) {
111         const char *signal = NULL;
112
113         retif(listbox == NULL, , "invalid parameter");
114         retif(item == NULL, , "invalid parameter");
115
116         struct appdata *ad = evas_object_data_get(listbox, E_DATA_APP_DATA);
117
118         if (ad != NULL) {
119                 if (ad->angle == 270 || ad->angle == 90) {
120                         signal = "box.landscape";
121                 } else {
122                         signal = "box.portrait";
123                 }
124         }
125
126         DBG("set to %s, %x", signal, item);
127
128         elm_object_signal_emit(item, signal, "box.prog");
129         edje_object_message_signal_process(_EDJ(item));
130         elm_layout_sizing_eval(item);
131
132         if (is_prepend == LISTBOX_PREPEND)
133                 elm_box_pack_start(listbox, item);
134         else
135                 elm_box_pack_end(listbox, item);
136 }
137
138 static void _listbox_remove_item_anim_cb(void *data, Elm_Transit *transit) {
139         DBG("");
140         retif(data == NULL, , "invalid parameter");
141         retif(transit == NULL, , "invalid parameter");
142
143         listbox_info_animation *info_animation = data;
144
145         retif(info_animation->listbox == NULL, , "invalid parameter");
146         retif(info_animation->item == NULL, , "invalid parameter");
147
148         DBG("remove:%p", info_animation->item);
149         void *node = noti_list_item_node_get(info_animation->item);
150         elm_box_unpack(info_animation->listbox, info_animation->item);
151         noti_list_item_remove(info_animation->item);
152         _listbox_call_item_deleted_cb(info_animation->listbox,
153                         node, NULL);
154
155         if (info_animation->update_cb != NULL) {
156                 retif(info_animation->container == NULL, , "invalid parameter");
157                 retif(info_animation->noti == NULL, , "invalid parameter");
158
159                 info_animation->update_cb(info_animation->container,
160                                 info_animation->noti, info_animation->pos);
161         }
162
163         free(info_animation);
164         info_animation = NULL;
165 }
166
167 void listbox_remove_item(Evas_Object *listbox, Evas_Object *item, int with_animation) {
168         retif(listbox == NULL, , "invalid parameter");
169         retif(item == NULL, , "invalid parameter");
170
171         if (noti_list_item_get_status(item) == STATE_DELETING) {
172                 return ;
173         }
174         noti_list_item_set_status(item, STATE_DELETING);
175
176         DBG("remove:%p", item);
177
178         if (with_animation == 1) {
179                 listbox_info_animation *info_animation = (listbox_info_animation *) malloc(
180                                 sizeof(listbox_info_animation));
181                 if (info_animation == NULL)
182                         return;
183                 info_animation->listbox = listbox;
184                 info_animation->item = item;
185                 info_animation->update_cb = NULL;
186                 info_animation->container = NULL;
187                 info_animation->noti = NULL;
188                 info_animation->pos = 0;
189
190                 Elm_Transit *transit = elm_transit_add();
191                 //Fade in and out with layout object.
192                 elm_transit_object_add(transit, item);
193                 elm_transit_effect_fade_add(transit);
194                 elm_transit_duration_set(transit, 0.7);
195                 elm_transit_del_cb_set(transit, _listbox_remove_item_anim_cb,
196                                 info_animation);
197                 elm_transit_go(transit);
198         } else {
199                 DBG("%p", item);
200                 void *node = noti_list_item_node_get(item);
201                 elm_box_unpack(listbox, item);
202                 noti_list_item_remove(item);
203                 _listbox_call_item_deleted_cb(listbox,
204                                 node, NULL);
205         }
206 }
207
208 void listbox_remove_all_item(Evas_Object *listbox, int with_animation) {
209         DBG("");
210         retif(listbox == NULL, , "invalid parameter");
211
212         Eina_List *l;
213         Eina_List *l_next;
214         Evas_Object *obj;
215         Eina_List *item_list = elm_box_children_get(listbox);
216
217         EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
218         {
219                 if (obj != NULL) {
220                         // call deleted callback
221                         listbox_remove_item(listbox, obj, with_animation);
222                 }
223         }
224 }
225
226 void listbox_update(Evas_Object *listbox) {
227         retif(listbox == NULL, , "invalid parameter");
228
229         Eina_List *l;
230         Eina_List *l_next;
231         Evas_Object *obj;
232         Eina_List *item_list = elm_box_children_get(listbox);
233
234         DBG("all count:%d", eina_list_count(item_list));
235
236         EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
237         {
238                 if (obj != NULL) {
239                         noti_list_item_update(obj);
240                 }
241         }
242 }
243
244 void listbox_update_item(Evas_Object *listbox, Evas_Object *item) {
245         retif(listbox == NULL, , "invalid parameter");
246         retif(item == NULL, , "invalid parameter");
247
248         noti_list_item_update(item);
249 }
250
251 void listbox_remove_and_add_item(Evas_Object *listbox, Evas_Object *item
252                 ,void (*update_cb)(Evas_Object *list, void *data, int is_prepend)
253                 ,void *container, void *data, int pos) {
254
255         retif(listbox == NULL, , "invalid parameter");
256         retif(item == NULL, , "invalid parameter");
257         retif(update_cb == NULL, , "invalid parameter");
258         retif(container == NULL, , "invalid parameter");
259         retif(data == NULL, , "invalid parameter");
260
261         if (noti_list_item_get_status(item) == STATE_DELETING) {
262                 return ;
263         }
264         noti_list_item_set_status(item, STATE_DELETING);
265
266         listbox_info_animation *info_animation = (listbox_info_animation *) malloc(
267                         sizeof(listbox_info_animation));
268         if (info_animation == NULL)
269                 return;
270         info_animation->listbox = listbox;
271         info_animation->item = item;
272         info_animation->update_cb = update_cb;
273         info_animation->container = container;
274         info_animation->noti = data;
275         info_animation->pos = pos;
276
277         Elm_Transit *transit = elm_transit_add();
278         //Fade in and out with layout object.
279         elm_transit_object_add(transit, item);
280         elm_transit_effect_fade_add(transit);
281         elm_transit_duration_set(transit, 0.4);
282         elm_transit_del_cb_set(transit, _listbox_remove_item_anim_cb,
283                         info_animation);
284         elm_transit_go(transit);
285 }
286
287 static void listbox_finalize_rotation_cb(void *data) {
288         retif(data == NULL, , "invalid parameter");
289         Evas_Object *listbox = data;
290
291         elm_box_recalculate(listbox);
292 }
293
294 void listbox_rotation(Evas_Object *listbox, int angle) {
295         const char *signal = NULL;
296
297         retif(listbox == NULL, , "invalid parameter");
298
299         Eina_List *l;
300         Eina_List *l_next;
301         Evas_Object *obj;
302         Eina_List *item_list = elm_box_children_get(listbox);
303
304         if (angle == 270 || angle == 90) {
305                 signal = "box.landscape";
306         } else {
307                 signal = "box.portrait";
308         }
309
310         DBG("all count:%d", eina_list_count(item_list));
311
312         EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
313         {
314                 if (obj != NULL) {
315                         elm_object_signal_emit(obj, signal, "box.prog");
316                         edje_object_message_signal_process(_EDJ(obj));
317                         elm_layout_sizing_eval(obj);
318                         DBG("set to %s, %x", signal, obj);
319                 }
320         }
321
322         DBG("Angle  Rotation  is %d", angle);
323 }