2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include "quickpanel-ui.h"
21 #include "list_util.h"
22 #include "quickpanel_theme_def.h"
23 #include "noti_gridbox.h"
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"
32 typedef struct _gridbox_info_layout {
42 } gridbox_info_layout;
44 typedef struct _gridbox_info_animation {
48 void (*update_cb)(Evas_Object *list, void *data, int is_prepend);
49 Evas_Object *container;
52 } gridbox_info_animation;
54 static void _gridbox_layout_get_pos(int order, int *x, int *y, void *data) {
55 gridbox_info_layout *info_layout = data;
57 retif(data == NULL, , "invalid parameter");
58 retif(x == NULL, , "invalid parameter");
59 retif(y == NULL, , "invalid parameter");
61 int n_per_row = info_layout->n_per_rows;
63 int row = (order - 1) / n_per_row;
64 int column = (order - 1) - (row * n_per_row);
66 //DBG("order:%d r:%d c:%d", order, row, column);
68 int row_x = info_layout->padding_left
69 + ((info_layout->child_w + info_layout->padding_between) * column);
71 int row_y = info_layout->padding_top
72 + ((info_layout->child_h + info_layout->padding_between) * row);
78 static void _gridbox_layout(Evas_Object *o, Evas_Object_Box_Data *priv,
82 int off_x = 0, off_y = 0;
85 Evas_Object_Box_Option *opt;
88 retif(o == NULL, , "invalid parameter");
89 retif(priv == NULL, , "invalid parameter");
90 retif(data == NULL, , "invalid parameter");
92 gridbox_info_layout *info_layout = (gridbox_info_layout *) data;
94 n_children = eina_list_count(priv->children);
95 DBG("layout function:%d", n_children);
96 DBG("ref count:%p(%d)",o, evas_object_ref_get(o));
102 evas_object_geometry_get(o, &x, &y, &w, &h);
104 //set info about children
105 opt = eina_list_data_get(priv->children);
106 evas_object_size_hint_min_get(opt->obj, &child_w, &child_h);
108 info_layout->child_w = child_w;
109 info_layout->child_h = child_h;
111 DBG("grid layout children:%d %d", child_w, child_h);
113 int order_children = 1;
114 EINA_LIST_FOREACH_SAFE(priv->children, l, l_next, opt)
116 _gridbox_layout_get_pos(order_children, &off_x, &off_y, info_layout);
117 evas_object_move(opt->obj, x + off_x, y + off_y);
118 evas_object_resize(opt->obj, info_layout->child_w,
119 info_layout->child_h);
123 evas_object_size_hint_min_set(o, -1,
124 off_y + info_layout->child_h + info_layout->padding_bottom);
127 Evas_Object *gridbox_create(Evas_Object *parent, void *data) {
129 retif(parent == NULL, NULL, "invalid parameter");
130 retif(data == NULL, NULL, "invalid parameter");
131 struct appdata *ad = data;
132 Evas_Object *gridbox = NULL;
134 gridbox_info_layout *info_layout_portrait = NULL;
135 gridbox_info_layout *info_layout_landscape = NULL;
137 info_layout_portrait = (gridbox_info_layout *) malloc(
138 sizeof(gridbox_info_layout));
139 retif(info_layout_portrait == NULL, NULL, "memory allocation failed");
140 info_layout_portrait->padding_between = 12 * ad->scale;
141 info_layout_portrait->padding_top = 0;
142 info_layout_portrait->padding_left = 14 * ad->scale;
143 info_layout_portrait->padding_bottom = 12 * ad->scale;
144 info_layout_portrait->n_per_rows = 2;
145 info_layout_portrait->child_w = 0; //340;
146 info_layout_portrait->child_h = 0; //400;
147 info_layout_portrait->scale = ad->scale;
149 info_layout_landscape = (gridbox_info_layout *) malloc(
150 sizeof(gridbox_info_layout));
151 retif(info_layout_landscape == NULL, NULL, "memory allocation failed");
152 info_layout_landscape->padding_between = 12 * ad->scale;
153 info_layout_landscape->padding_top = 0;
154 info_layout_landscape->padding_left = 14 * ad->scale;
155 info_layout_landscape->padding_bottom = 12 * ad->scale;
156 info_layout_landscape->n_per_rows = 3;
157 info_layout_landscape->child_w = 0; //409;
158 info_layout_landscape->child_h = 0; //400;
159 info_layout_landscape->scale = ad->scale;
161 gridbox = elm_box_add(parent);
162 evas_object_size_hint_weight_set(gridbox, EVAS_HINT_EXPAND,
164 evas_object_size_hint_align_set(gridbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
166 if (ad->angle == 270 || ad->angle == 90)
167 elm_box_layout_set(gridbox, _gridbox_layout, info_layout_landscape,
170 elm_box_layout_set(gridbox, _gridbox_layout, info_layout_portrait,
173 evas_object_ref(gridbox);
174 evas_object_show(gridbox);
176 evas_object_data_set(gridbox, E_DATA_LAYOUT_PORTRAIT, info_layout_portrait);
177 evas_object_data_set(gridbox, E_DATA_LAYOUT_LANDSCAPE,
178 info_layout_landscape);
179 evas_object_data_set(gridbox, E_DATA_CB_DELETE_ITEM, NULL);
180 evas_object_data_set(gridbox, E_DATA_APP_DATA, ad);
185 void gridbox_remove(Evas_Object *gridbox) {
187 retif(gridbox == NULL, , "invalid parameter");
189 gridbox_info_layout *info_layout_portrait = evas_object_data_get(gridbox,
190 E_DATA_LAYOUT_PORTRAIT);
191 gridbox_info_layout *info_layout_landscape = evas_object_data_get(gridbox,
192 E_DATA_LAYOUT_LANDSCAPE);
194 gridbox_remove_all_item(gridbox, 0);
195 evas_object_data_del(gridbox, E_DATA_LAYOUT_PORTRAIT);
196 evas_object_data_del(gridbox, E_DATA_LAYOUT_LANDSCAPE);
197 evas_object_data_del(gridbox, E_DATA_CB_DELETE_ITEM);
198 evas_object_data_del(gridbox, E_DATA_APP_DATA);
199 evas_object_unref(gridbox);
200 evas_object_del(gridbox);
202 if (info_layout_portrait != NULL)
203 free(info_layout_portrait);
204 if (info_layout_landscape != NULL)
205 free(info_layout_landscape);
208 void gridbox_set_item_deleted_cb(Evas_Object *gridbox,
209 void(*deleted_cb)(void *data, Evas_Object *obj)) {
210 retif(gridbox == NULL, , "invalid parameter");
211 retif(deleted_cb == NULL, , "invalid parameter");
213 evas_object_data_set(gridbox, E_DATA_CB_DELETE_ITEM, deleted_cb);
216 static void _gridbox_call_item_deleted_cb(Evas_Object *gridbox, void *data,
218 retif(gridbox == NULL, , "invalid parameter");
220 void (*deleted_cb)(void *data, Evas_Object *obj) = NULL;
222 deleted_cb = evas_object_data_get(gridbox, E_DATA_CB_DELETE_ITEM);
224 if (deleted_cb != NULL) {
225 deleted_cb(data, obj);
229 void gridbox_add_item(Evas_Object *gridbox, Evas_Object *item, int is_prepend) {
230 const char *signal = NULL;
232 retif(gridbox == NULL, , "invalid parameter");
233 retif(item == NULL, , "invalid parameter");
235 struct appdata *ad = evas_object_data_get(gridbox, E_DATA_APP_DATA);
238 if (ad->angle == 270 || ad->angle == 90) {
239 signal = "box.landscape";
241 signal = "box.portrait";
245 DBG("set to %s, %x", signal, item);
247 elm_object_signal_emit(item, signal, "box.prog");
248 edje_object_message_signal_process(_EDJ(item));
249 elm_layout_sizing_eval(item);
251 if (is_prepend == GRIDBOX_PREPEND)
252 elm_box_pack_start(gridbox, item);
254 elm_box_pack_end(gridbox, item);
257 static void _gridbox_remove_item_anim_cb(void *data, Elm_Transit *transit) {
259 retif(data == NULL, , "invalid parameter");
260 retif(transit == NULL, , "invalid parameter");
262 gridbox_info_animation *info_animation = data;
264 retif(info_animation->gridbox == NULL, , "invalid parameter");
265 retif(info_animation->item == NULL, , "invalid parameter");
267 DBG("remove:%p", info_animation->item);
269 elm_box_unpack(info_animation->gridbox, info_animation->item);
271 _gridbox_call_item_deleted_cb(info_animation->gridbox,
272 noti_box_node_get(info_animation->item), info_animation->item);
273 noti_box_remove(info_animation->item);
275 if (info_animation->update_cb != NULL) {
276 retif(info_animation->container == NULL, , "invalid parameter");
277 retif(info_animation->noti == NULL, , "invalid parameter");
279 info_animation->update_cb(info_animation->container,
280 info_animation->noti, info_animation->pos);
283 free(info_animation);
284 info_animation = NULL;
287 void gridbox_remove_item(Evas_Object *gridbox, Evas_Object *item, int with_animation) {
288 DBG("remove:%p", item);
289 retif(gridbox == NULL, , "invalid parameter");
290 retif(item == NULL, , "invalid parameter");
292 if (noti_box_get_status(item) == STATE_DELETING) {
295 noti_box_set_status(item, STATE_DELETING);
297 if (with_animation == 1) {
298 gridbox_info_animation *info_animation = (gridbox_info_animation *) malloc(
299 sizeof(gridbox_info_animation));
300 if (info_animation == NULL)
302 info_animation->gridbox = gridbox;
303 info_animation->item = item;
304 info_animation->update_cb = NULL;
305 info_animation->container = NULL;
306 info_animation->noti = NULL;
307 info_animation->pos = 0;
309 Elm_Transit *transit = elm_transit_add();
310 //Fade in and out with layout object.
311 elm_transit_object_add(transit, item);
312 elm_transit_effect_fade_add(transit);
313 elm_transit_duration_set(transit, 0.7);
314 elm_transit_del_cb_set(transit, _gridbox_remove_item_anim_cb,
316 elm_transit_go(transit);
318 _gridbox_call_item_deleted_cb(gridbox,
319 noti_box_node_get(item), item);
320 elm_box_unpack(gridbox, item);
321 noti_box_remove(item);
325 void gridbox_remove_all_item(Evas_Object *gridbox, int with_animation) {
327 retif(gridbox == NULL, , "invalid parameter");
332 Eina_List *item_list = elm_box_children_get(gridbox);
334 EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
337 // call deleted callback
338 gridbox_remove_item(gridbox, obj, with_animation);
343 void gridbox_update_item(Evas_Object *gridbox, Evas_Object *item) {
345 retif(gridbox == NULL, , "invalid parameter");
346 retif(item == NULL, , "invalid parameter");
349 void gridbox_remove_and_add_item(Evas_Object *gridbox, Evas_Object *item
350 ,void (*update_cb)(Evas_Object *list, void *data, int is_prepend)
351 ,void *container, void *data, int pos) {
353 retif(gridbox == NULL, , "invalid parameter");
354 retif(item == NULL, , "invalid parameter");
355 retif(update_cb == NULL, , "invalid parameter");
356 retif(container == NULL, , "invalid parameter");
357 retif(data == NULL, , "invalid parameter");
359 if (noti_box_get_status(item) == STATE_DELETING) {
362 noti_box_set_status(item, STATE_DELETING);
364 gridbox_info_animation *info_animation = (gridbox_info_animation *) malloc(
365 sizeof(gridbox_info_animation));
366 if (info_animation == NULL)
368 info_animation->gridbox = gridbox;
369 info_animation->item = item;
370 info_animation->update_cb = update_cb;
371 info_animation->container = container;
372 info_animation->noti = data;
373 info_animation->pos = pos;
375 Elm_Transit *transit = elm_transit_add();
376 //Fade in and out with layout object.
377 elm_transit_object_add(transit, item);
378 elm_transit_effect_fade_add(transit);
379 elm_transit_duration_set(transit, 0.4);
380 elm_transit_del_cb_set(transit, _gridbox_remove_item_anim_cb,
382 elm_transit_go(transit);
385 void gridbox_finalize_rotation_cb(void *data) {
386 retif(data == NULL, , "invalid parameter");
387 Evas_Object *gridbox = data;
389 elm_box_recalculate(gridbox);
392 void gridbox_rotation(Evas_Object *gridbox, int angle) {
393 const char *signal = NULL;
395 retif(gridbox == NULL, , "invalid parameter");
397 gridbox_info_layout *info_layout_portrait = evas_object_data_get(gridbox,
398 E_DATA_LAYOUT_PORTRAIT);
399 gridbox_info_layout *info_layout_landscape = evas_object_data_get(gridbox,
400 E_DATA_LAYOUT_LANDSCAPE);
402 retif(info_layout_portrait == NULL || info_layout_landscape == NULL, ,
403 "gridbox is crashed");
408 Eina_List *item_list = elm_box_children_get(gridbox);
410 if (angle == 270 || angle == 90) {
411 signal = "box.landscape";
413 signal = "box.portrait";
416 DBG("all count:%d", eina_list_count (item_list));
418 EINA_LIST_FOREACH_SAFE(item_list, l, l_next, obj)
421 elm_object_signal_emit(obj, signal, "box.prog");
422 edje_object_message_signal_process(_EDJ(obj));
423 elm_layout_sizing_eval(obj);
424 DBG("set to %s, %x", signal, obj);
428 if (angle == 270 || angle == 90) {
429 elm_box_layout_set(gridbox, _gridbox_layout, info_layout_landscape,
433 layout_data = elm_box_transition_new(0.0, _gridbox_layout,
434 info_layout_portrait, NULL, _gridbox_layout,
435 info_layout_landscape, NULL, gridbox_finalize_rotation_cb,
439 elm_box_layout_set(gridbox, _gridbox_layout, info_layout_portrait,
442 layout_data = elm_box_transition_new(0.0, _gridbox_layout,
443 info_layout_landscape, NULL, _gridbox_layout,
444 info_layout_portrait, NULL, gridbox_finalize_rotation_cb,
450 elm_box_layout_set(gridbox, elm_box_layout_transition, layout_data,
451 elm_box_transition_free);
453 DBG("Angle Rotation is %d", angle);