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