0810 version
[apps/native/sample/adventure.git] / src / scroller.c
1 #include <Elementary.h>
2
3 #include "util.h"
4 #include "log.h"
5 #include "scroller.h"
6
7 #define PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING "p_is_sc"
8 #define PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST "pdkec"
9
10
11
12 struct _event_cb {
13         int event_type;
14         void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data);
15         void *user_data;
16 };
17 typedef struct _event_cb event_cb_s;
18
19
20
21 int scroller_is_scrolling(Evas_Object *scroller)
22 {
23         retv_if(!scroller, 0);
24         return (int) evas_object_data_get(scroller, PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING);
25 }
26
27
28
29 static void __scroller_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
30 {
31         Evas_Object *scroller = obj;
32
33         ret_if(!scroller);
34
35         evas_object_data_set(scroller, PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING, NULL);
36 }
37
38
39
40 static void __anim_start_cb(void *data, Evas_Object *scroller, void *event_info)
41 {
42         _D("start the scroller(%p) animation", scroller);
43         evas_object_data_set(scroller, PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING, (void *) 1);
44 }
45
46
47
48 static void __anim_stop_cb(void *data, Evas_Object *scroller, void *event_info)
49 {
50         _D("stop the scroller(%p) animation", scroller);
51 }
52
53
54
55 static void __drag_start_cb(void *data, Evas_Object *scroller, void *event_info)
56 {
57         _D("start to drag the scroller(%p)", scroller);
58         evas_object_data_set(scroller, PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING, (void *) 1);
59 }
60
61
62
63 static void __drag_stop_cb(void *data, Evas_Object *scroller, void *event_info)
64 {
65         _D("stop to drag the scroller(%p)", scroller);
66 }
67
68
69
70 Evas_Object *scroller_create(Evas_Object *parent)
71 {
72         Evas_Object *box = NULL;
73         Evas_Object *scroller = NULL;
74
75         retv_if(!parent, NULL);
76
77         scroller = elm_scroller_add(parent);
78         retv_if(!scroller, NULL);
79
80         elm_scroller_bounce_set(scroller, EINA_FALSE, EINA_TRUE);
81         elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
82         elm_scroller_page_scroll_limit_set(scroller, 0, 0);
83         elm_scroller_content_min_limit(scroller, EINA_TRUE, EINA_FALSE);
84         elm_scroller_single_direction_set(scroller, ELM_SCROLLER_SINGLE_DIRECTION_HARD);
85
86         evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
87         evas_object_size_hint_align_set(scroller, 0.0, EVAS_HINT_EXPAND);
88         evas_object_size_hint_min_set(scroller, 0, 0);
89
90         elm_object_style_set(scroller, "effect");
91         evas_object_show(scroller);
92         elm_object_scroll_lock_y_set(scroller, EINA_FALSE);
93
94         evas_object_smart_callback_add(scroller, "scroll,anim,start", __anim_start_cb, NULL);
95         evas_object_smart_callback_add(scroller, "scroll,anim,stop", __anim_stop_cb, NULL);
96         evas_object_smart_callback_add(scroller, "scroll,drag,start", __drag_start_cb, NULL);
97         evas_object_smart_callback_add(scroller, "scroll,drag,stop", __drag_stop_cb, NULL);
98         evas_object_event_callback_add(scroller, EVAS_CALLBACK_MOUSE_DOWN, __scroller_mouse_down_cb, NULL);
99
100         box = elm_box_add(scroller);
101         goto_if(!box, ERROR);
102
103         elm_box_horizontal_set(box, EINA_FALSE);
104         elm_box_homogeneous_set(box, EINA_FALSE);
105         elm_box_align_set(box, 0.0, 0.0);
106         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, 0.0);
107         evas_object_show(box);
108
109         elm_object_content_set(scroller, box);
110
111         return scroller;
112
113 ERROR:
114         if (scroller) {
115                 evas_object_del(scroller);
116         }
117
118         return NULL;
119 }
120
121
122
123 void scroller_destroy(Evas_Object *scroller)
124 {
125         Evas_Object *box = NULL;
126
127         ret_if(!scroller);
128
129         box = elm_object_content_unset(scroller);
130         if (box) {
131                 evas_object_del(box);
132         }
133
134         evas_object_data_del(scroller, PRIVATE_DATA_KEY_SCROLLER_IS_SCROLLING);
135         evas_object_del(scroller);
136 }
137
138
139
140 void scroller_append_item(Evas_Object *scroller, Evas_Object *item)
141 {
142         Evas_Object *box = NULL;
143
144         box = elm_object_content_get(scroller);
145         ret_if(!box);
146
147         elm_box_pack_end(box, item);
148 }
149
150
151
152 void scroller_remove_item(Evas_Object *scroller, Evas_Object *item)
153 {
154         Evas_Object *box = NULL;
155         Evas_Object *tmp = NULL;
156         Eina_List *list = NULL;
157
158         int is_item_exist = 0;
159
160         box = elm_object_content_get(scroller);
161         ret_if(!box);
162
163         list = elm_box_children_get(box);
164         EINA_LIST_FREE(list, tmp) {
165                 continue_if(!tmp);
166                 if (item == tmp) {
167                         is_item_exist = 1;
168                 }
169         }
170
171         if (!is_item_exist) {
172                 _D("No item to remove");
173                 return;
174         }
175
176         elm_box_unpack(box, item);
177 }
178
179
180
181 void scroller_clear_item(Evas_Object *scroller)
182 {
183         Evas_Object *box = NULL;
184         Evas_Object *item = NULL;
185         Eina_List *list = NULL;
186
187         ret_if(!scroller);
188
189         box = elm_object_content_get(scroller);
190         ret_if(!box);
191
192         list = elm_box_children_get(box);
193         ret_if(!list);
194
195         EINA_LIST_FREE(list, item) {
196                 evas_object_del(item);
197         }
198 }
199
200
201
202 int scroller_count_item(Evas_Object *scroller)
203 {
204         Evas_Object *box = NULL;
205         Eina_List *list = NULL;
206         int count = 0;
207
208         retv_if(!scroller, 0);
209
210         box = elm_object_content_get(scroller);
211         retv_if(!box, 0);
212
213         list = elm_box_children_get(box);
214         if (!list)
215                 return 0;
216
217         count = eina_list_count(list);
218         eina_list_free(list);
219
220         return count;
221 }
222
223
224
225 void scroller_bring_in_item(Evas_Object *scroller, Evas_Object *item)
226 {
227         Evas_Object *box = NULL;
228         Evas_Object *tmp = NULL;
229         Eina_List *list = NULL;
230         int y = 0;
231         int exist = 0;
232
233         ret_if(!scroller);
234         ret_if(!item);
235
236         box = elm_object_content_get(scroller);
237         ret_if(!box);
238
239         list = elm_box_children_get(box);
240         ret_if(!list);
241
242         EINA_LIST_FREE(list, tmp) {
243                 continue_if(!tmp);
244                 if (item == tmp) {
245                         evas_object_geometry_get(item, NULL, &y, NULL, NULL);
246                         exist = 1;
247                 }
248         }
249
250         if (exist) {
251                 elm_scroller_region_bring_in(scroller, 0, y, 0, 0);
252         }
253 }
254
255
256
257 int scroller_register_event_cb(Evas_Object *scroller, int event_type, void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data), void *user_data)
258 {
259         Eina_List *event_cb_list = NULL;
260         event_cb_s *event_cb_info = NULL;
261
262         retv_if(!scroller, APPL_ERROR_INVALID_PARAMETER);
263         retv_if(event_type <= SCROLLER_EVENT_TYPE_INVALID, APPL_ERROR_INVALID_PARAMETER);
264         retv_if(event_type >= SCROLLER_EVENT_TYPE_MAX, APPL_ERROR_INVALID_PARAMETER);
265         retv_if(!event_cb, APPL_ERROR_INVALID_PARAMETER);
266
267         event_cb_info = calloc(1, sizeof(event_cb_s));
268         retv_if(!event_cb_info, APPL_ERROR_OUT_OF_MEMORY);
269
270         event_cb_info->event_type = event_type;
271         event_cb_info->event_cb = event_cb;
272         event_cb_info->user_data = user_data;
273
274         event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST);
275         event_cb_list = eina_list_append(event_cb_list, event_cb_info);
276         evas_object_data_set(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST, event_cb_list);
277
278         return APPL_ERROR_NONE;
279 }
280
281
282
283 int scroller_unregister_event_cb(Evas_Object *scroller, int event_type, void (*event_cb)(Evas_Object *scroller, int event_type, void *event_info, void *user_data))
284 {
285         Eina_List *event_cb_list = NULL;
286         const Eina_List *l = NULL;
287         const Eina_List *ln = NULL;
288         event_cb_s *event_cb_info = NULL;
289
290         retv_if(!scroller, APPL_ERROR_INVALID_PARAMETER);
291         retv_if(event_type <= SCROLLER_EVENT_TYPE_INVALID, APPL_ERROR_INVALID_PARAMETER);
292         retv_if(event_type >= SCROLLER_EVENT_TYPE_MAX, APPL_ERROR_INVALID_PARAMETER);
293         retv_if(!event_cb, APPL_ERROR_INVALID_PARAMETER);
294
295         event_cb_list = evas_object_data_get(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST);
296         retv_if(!event_cb_list, APPL_ERROR_FAIL);
297
298         EINA_LIST_FOREACH_SAFE(event_cb_list, l, ln, event_cb_info) {
299                 if (event_cb_info->event_type == event_type
300                         && event_cb_info->event_cb == event_cb) {
301                         event_cb_list = eina_list_remove(event_cb_list, event_cb_info);
302                         break;
303                 }
304         }
305
306         evas_object_data_set(scroller, PRIVATE_DATA_KEY_EVENT_CALLBACK_LIST, event_cb_list);
307
308         return APPL_ERROR_NONE;
309 }