The source code moved from the SPIN with license changed to Flora 1.1
[apps/native/home/homescreen-efl.git] / src / page_scroller.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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 <stdbool.h>
18 #include <Elementary.h>
19
20 #include "util.h"
21 #include "homescreen-efl.h"
22 #include "page_scroller.h"
23
24 #define PAGE_SCROLLER_WIDTH 272
25 #define PAGE_SCROLLER_HEIGHT 272
26
27 #define EDJE_PAGE_SCROLLER_FILENAME "/usr/apps/com.samsung.home-lite/res/edje/page_scroller.edj"
28 #define EDJE_PAGE_SCROLLER_LIVEBOX_GROUP_NAME "page_scroller_livebox"
29 #define EDJE_PAGE_SCROLLER_ALL_APPS_GROUP_NAME "page_scroller_all_apps"
30 #define EDJE_PAGE_SCROLLER_CONTENT_GROUP_NAME "page_scroller_content"
31
32
33 static Evas_Object *__page_scroller_create_scroller(void);
34 static void __page_scroller_change_cb(void *data, Evas_Object *obj, const char *emission, const char *source);
35 static Eina_Bool __page_scroller_blocker_cb(void *data);
36
37 static struct {
38         Ecore_Timer *blocker;
39 } s_info = {
40         .blocker = NULL,
41 };
42
43
44 HAPI Evas_Object *page_scroller_create(int page_width, int page_height)
45 {
46         Evas_Object *scroller = NULL;
47
48         scroller = __page_scroller_create_scroller();
49         if (!scroller) {
50                 LOGE("Failed to create scroller");
51                 return NULL;
52         }
53
54         elm_scroller_page_size_set(scroller, page_width, page_height);
55         elm_scroller_loop_set(scroller, EINA_TRUE, EINA_FALSE);
56         elm_object_signal_callback_add(scroller, "*", SIGNAL_SOURCE, __page_scroller_change_cb, NULL);
57
58         return scroller;
59 }
60
61
62 HAPI void page_scroller_destroy(Evas_Object *scroller)
63 {
64         LOGD("Destroy page scroller");
65
66         if (!scroller) {
67                 LOGE("Invalid param : scroller is NULL");
68                 return;
69         }
70
71         evas_object_del(scroller);
72 }
73
74 HAPI bool page_scroller_add_page(Evas_Object *scroller, Evas_Object *page)
75 {
76         LOGD("Add page");
77
78         Evas_Object *box = NULL;
79
80         if (!page || !scroller) {
81                 LOGE("Invalid parameters : page or scroller is NULL");
82                 return false;
83         }
84
85         box = elm_object_content_get(scroller);
86         if (!box) {
87                 LOGE("Failed to obtain box from scroller");
88                 return false;
89         }
90
91         elm_box_pack_end(box, page);
92
93         return true;
94 }
95
96 HAPI void page_scroller_remove_page(Evas_Object *scroller, Evas_Object *page)
97 {
98         LOGD("Remove page");
99         Evas_Object *box = NULL;
100
101         if (!page || !scroller) {
102                 LOGE("Page or scroller is NULL");
103                 return;
104         }
105
106         box = elm_object_content_get(scroller);
107         if (!box) {
108                 LOGE("Failed to get scroller");
109                 return;
110         }
111
112         elm_box_unpack(box, page);
113         evas_object_del(page);
114         return;
115 }
116
117 HAPI Eina_List* page_scroller_get_all_pages(Evas_Object *scroller)
118 {
119         Evas_Object *box = NULL;
120         Eina_List *pages = NULL;
121
122         if (!scroller) {
123                 LOGE("Invalid parameter : scroller is NULL");
124                 return NULL;
125         }
126
127         box = elm_object_content_get(scroller);
128         if (!box) {
129                 LOGE("Failed to get box");
130                 return NULL;
131         }
132
133         pages = elm_box_children_get(box);
134         if (!pages) {
135                 LOGE("Failed to get pages list");
136                 return NULL;
137         }
138
139         return pages;
140 }
141
142
143 HAPI Evas_Object* page_scroller_get_page(Evas_Object *scroller, int n)
144 {
145         Eina_List *pages = NULL;
146         Evas_Object *page = NULL;
147
148         pages = page_scroller_get_all_pages(scroller);
149         if (!pages) {
150                 LOGE("Failed to get page");
151                 return NULL;
152         }
153
154         page = (Evas_Object*) eina_list_nth(pages, n);
155
156         eina_list_free(pages);
157
158         return page;
159 }
160
161
162 HAPI bool page_scroller_freeze(Evas_Object *scroller)
163 {
164         LOGD("Freeze page scroller");
165
166         if (!scroller) {
167                 LOGE("Page Scroller is NULL");
168                 return false;
169         }
170
171         elm_scroller_movement_block_set(scroller, ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
172
173         return true;
174 }
175
176 HAPI bool page_scroller_unfreeze(Evas_Object *scroller)
177 {
178         LOGD("Unfreeze page scroller");
179
180         if (!scroller) {
181                 LOGE("Page Scroller is NULL");
182                 return false;
183         }
184
185         elm_scroller_movement_block_set(scroller, ELM_SCROLLER_MOVEMENT_NO_BLOCK);
186
187         return true;
188 }
189
190 HAPI int page_scroller_get_page_count(Evas_Object *scroller)
191 {
192         Eina_List *page_list = NULL;
193         int page_count = 0;
194
195         if (!scroller) {
196                 LOGE("invalid param : scroller is NULL");
197                 return -1;
198         }
199
200         page_list = page_scroller_get_all_pages(scroller);
201         page_count = eina_list_count(page_list);
202
203         eina_list_free(page_list);
204
205         return page_count;
206 }
207
208
209 HAPI Eina_List* page_scroller_unpack_pages(Evas_Object *scroller)
210 {
211         Evas_Object *box = NULL;
212         Eina_List *page_list = NULL;
213
214         if (!scroller) {
215                 LOGE("Page scroller is NULL");
216                 return NULL;
217         }
218
219         page_list = page_scroller_get_all_pages(scroller);
220
221         if (!page_list) {
222                 LOGE("Failed to get m_page list");
223                 return NULL;
224         }
225
226         box = elm_object_content_get(scroller);
227         elm_box_unpack_all(box); ///@todo better content unset?
228
229         return page_list;
230 }
231
232
233 HAPI void page_scroller_pack_pages(Evas_Object *scroller, Eina_List *page_list)
234 {
235         LOGD("");
236         Eina_List *item = NULL;
237         Evas_Object *page = NULL;
238         Evas_Object *box = NULL;
239
240         if (!scroller || !page_list) {
241                 LOGE("Invalid parameters : scroller [%p] page_list [%p]", scroller, page_list);
242                 return;
243         }
244
245         box = elm_object_content_get(scroller);
246         if (!box) {
247                 LOGE("Cannot obtain box, pages will remain unpacked");
248                 return;
249         }
250
251         EINA_LIST_FOREACH(page_list, item, page) {
252                 if (!page) {
253                         LOGE("Failed to get page");
254                         continue;
255                 }
256                 elm_box_pack_end(box, page);
257                 evas_object_size_hint_weight_set(page, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
258                 evas_object_size_hint_align_set(page, EVAS_HINT_FILL, EVAS_HINT_FILL);
259         }
260         elm_box_recalculate(box);
261 }
262
263
264 HAPI Evas_Object* page_scroller_get_page_thumbnail(Evas_Object *page, unsigned int w, unsigned int h)
265 {
266         LOGD("");
267         Evas_Object *image = NULL;
268
269         if (!page) {
270                 LOGE("Invalid page number");
271                 return NULL;
272         }
273
274         image = evas_object_image_filled_add(evas_object_evas_get(home_screen_get_win()));
275         if (!image) {
276                 LOGE("Could not create image proxy object");
277                 return NULL;
278         }
279
280         /*set image proxy*/
281         if (!evas_object_image_source_set(image, page)) {
282                 evas_object_del(image);
283                 LOGE("Could not set proxy image source");
284                 return NULL;
285         }
286
287         evas_object_image_fill_set(image, 0, 0, w, h);
288         evas_object_move(image, 0, 0);
289         evas_object_show(image);
290
291         return image;
292 }
293
294 HAPI int page_scroller_get_current_page(Evas_Object *page_scroller)
295 {
296         int h_page = -1;
297
298         if (!page_scroller) {
299                 LOGE("Invalid param : page_scroller is NULL");
300                 return -1;
301         }
302
303         elm_scroller_current_page_get(page_scroller, &h_page, NULL);
304
305         return h_page;
306 }
307
308 HAPI bool page_scroller_set_current_page(Evas_Object *page_scroller, int idx)
309 {
310         if (!page_scroller || idx < 0) {
311                 LOGE("[INVALID_PARAM][page_scroller='%p'][idx='%d']", page_scroller, idx);
312                 return false;
313         }
314
315
316         elm_scroller_page_bring_in(page_scroller, idx, 0);
317         return true;
318 }
319
320 HAPI void page_scroller_show_page(Evas_Object *page_scroller, int idx)
321 {
322         if (!page_scroller || idx < 0) {
323                 LOGE("[INVALID_PARAM][page_scroller='%p'][idx='%d']", page_scroller, idx);
324                 return;
325         }
326
327         elm_scroller_page_show(page_scroller, idx, 0);
328 }
329
330 static Evas_Object* __page_scroller_create_scroller(void)
331 {
332         Evas_Object *win = home_screen_get_win();
333         Evas_Object *scroller = NULL;
334         Evas_Object *box = NULL;
335
336         if (!win) {
337                 print_log(DLOG_ERROR, LOG_TAG, "Window doesn't exist");
338                 return NULL;
339         }
340
341         scroller = elm_scroller_add(win);
342         if (!scroller) {
343                 LOGE("Cannot create scroller");
344                 return NULL;
345         }
346
347         elm_scroller_content_min_limit(scroller, EINA_FALSE, EINA_FALSE);
348         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
349         elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
350         elm_scroller_page_scroll_limit_set(scroller, 1, 1);
351
352         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
353
354         box = elm_box_add(scroller);
355         if (!box) {
356                 LOGE("Cannot create box");
357                 evas_object_del(scroller);
358                 return NULL;
359         }
360         elm_box_horizontal_set(box, EINA_TRUE);
361         elm_box_align_set(box, 0.5, 0.5);
362         evas_object_show(scroller);
363         elm_object_content_set(scroller, box);
364
365         return scroller;
366 }
367
368 static void __page_scroller_change_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
369 {
370         int cnt = -1, curr = -1, dest = -1;
371
372         cnt = page_scroller_get_page_count(obj);
373         curr = page_scroller_get_current_page(obj);
374
375         if (s_info.blocker)
376                 return;
377
378         if (!strncmp(emission, SIGNAL_NEXT_PAGE_CHANGE, strlen(emission))) {
379                 if (curr == cnt - 1) {
380                         dest = 0;
381                 } else {
382                         dest = ++curr;
383                 }
384                 page_scroller_set_current_page(obj, dest);
385         } else if (!strncmp(emission, SIGNAL_PREV_PAGE_CHANGE, strlen(emission))) {
386                 if (curr == 0) {
387                         dest = cnt - 1;
388                 } else {
389                         dest = --curr;
390                 }
391                 page_scroller_set_current_page(obj, dest);
392         }
393
394         s_info.blocker = ecore_timer_add(0.5, __page_scroller_blocker_cb, NULL);
395 }
396
397 static Eina_Bool __page_scroller_blocker_cb(void *data)
398 {
399         s_info.blocker = NULL;
400         return ECORE_CALLBACK_CANCEL;
401 }