The source code moved from the SPIN with license changed to Flora 1.1
[apps/native/home/homescreen-efl.git] / src / livebox / livebox_animator.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 <Elementary.h>
18
19 #include <stdbool.h>
20
21 #include "livebox/livebox_animator.h"
22 #include "util.h"
23 #include "livebox/livebox_panel.h"
24 #include "homescreen-efl.h"
25 #include "page_scroller.h"
26 #include "popup.h"
27
28 #define FRAME (1.0/30.0)
29 #define FPS 30
30
31 static Eina_Bool __livebox_animator_set_grid_frame(void *data, double pos);
32 static Eina_Bool __livebox_animator_set_geometry_frame(void *data, double pos);
33 static void __livebox_animator_create(Evas_Object *obj,
34                 float anim_time,
35                 Ecore_Pos_Map map, float map_var_1, float map_var_2,
36                 Eina_Rectangle *geometry_start, Eina_Rectangle *geometry_end,
37                 Anim_Grid_End on_end,
38                 Anim_Data_t **ad_out);
39
40
41 void livebox_animator_del_grid(Anim_Data_t **ad)
42 {
43         if (!(*ad)) {
44                 LOGE("(*ad) == NULL");
45                 return;
46         }
47
48         (*ad)->on_end = NULL;
49         ecore_animator_del((*ad)->animator);
50         (*ad)->animator = NULL;
51         (*ad)->anim_is_running = false;
52         eina_rectangle_free((*ad)->geometry_start);
53         eina_rectangle_free((*ad)->geometry_end);
54         free((*ad));
55
56         (*ad) = NULL;
57 }
58
59 void livebox_animator_play_grid_pack_set(Evas_Object *obj,
60                 float anim_time,
61                 Ecore_Pos_Map map, float map_var_1, float map_var_2,
62                 Eina_Rectangle *geometry_start, Eina_Rectangle *geometry_end,
63                 Anim_Grid_End on_end,
64                 Anim_Data_t **ad_out)
65 {
66         __livebox_animator_create(obj, anim_time, map, map_var_1, map_var_2,
67                         geometry_start, geometry_end, on_end, ad_out);
68
69         if (!(*ad_out)) {
70                 LOGE("Failed to create animation");
71                 return;
72         }
73
74         (*ad_out)->animator = ecore_animator_timeline_add(anim_time,
75                 __livebox_animator_set_grid_frame, ad_out);
76
77         if (!(*ad_out)->animator) {
78                 LOGE("Failed to create animator");
79                 livebox_animator_del_grid(ad_out);
80                 return;
81         }
82 }
83
84 void livebox_animator_play_geometry_set(Evas_Object *obj,
85                 float anim_time,
86                 Ecore_Pos_Map map, float map_var_1, float map_var_2,
87                 Eina_Rectangle *geometry_start, Eina_Rectangle *geometry_end,
88                 Anim_Grid_End on_end,
89                 Anim_Data_t **ad_out)
90 {
91         __livebox_animator_create(obj, anim_time, map, map_var_1, map_var_2,
92                         geometry_start, geometry_end, on_end, ad_out);
93
94         if (!(*ad_out)) {
95                 LOGE("Failed to create animation");
96                 return;
97         }
98
99         (*ad_out)->animator = ecore_animator_timeline_add(anim_time,
100                 __livebox_animator_set_geometry_frame, ad_out);
101
102         if (!(*ad_out)->animator) {
103                 LOGE("Failed to create animator");
104                 livebox_animator_del_grid(ad_out);
105                 return;
106         }
107 }
108
109 static void __livebox_animator_create(Evas_Object *obj,
110                 float anim_time,
111                 Ecore_Pos_Map map, float map_var_1, float map_var_2,
112                 Eina_Rectangle *geometry_start, Eina_Rectangle *geometry_end,
113                 Anim_Grid_End on_end,
114                 Anim_Data_t **ad_out)
115 {
116         *ad_out = (Anim_Data_t *) calloc(1, sizeof(Anim_Data_t));
117         if (!*ad_out) {
118                 LOGE("Failed to allocate ad_out");
119                 return;
120         }
121
122         (*ad_out)->anim_time = anim_time;
123         (*ad_out)->obj = obj;
124         (*ad_out)->map = map;
125         (*ad_out)->map_var_1 = map_var_1;
126         (*ad_out)->map_var_2 = map_var_2;
127         (*ad_out)->geometry_start = geometry_start;
128         (*ad_out)->geometry_end   = geometry_end;
129         (*ad_out)->on_end = on_end;
130         (*ad_out)->anim_is_running = true;
131 }
132
133
134 static Eina_Bool __livebox_animator_set_geometry_frame(void *data, double pos)
135 {
136         double frame = pos;
137
138         Anim_Data_t **ad = (Anim_Data_t **)data;
139         if (!(*ad)) {
140                 LOGE("(*ad) == NULL");
141                 return ECORE_CALLBACK_CANCEL;
142         }
143
144         int xs = (*ad)->geometry_start->x;
145         int ys = (*ad)->geometry_start->y;
146         int ws = (*ad)->geometry_start->w;
147         int hs = (*ad)->geometry_start->h;
148
149         int xe = (*ad)->geometry_end->x;
150         int ye = (*ad)->geometry_end->y;
151         int we = (*ad)->geometry_end->w;
152         int he = (*ad)->geometry_end->h;
153
154         int xd = xe - xs;
155         int yd = ye - ys;
156         int wd = we - ws;
157         int hd = he - hs;
158
159         frame = ecore_animator_pos_map(pos, (*ad)->map, (*ad)->map_var_1,
160                 (*ad)->map_var_2);
161
162         evas_object_move((*ad)->obj, xs + xd * frame, ys + yd * frame);
163         evas_object_resize((*ad)->obj, ws + wd * frame, hs + hd * frame);
164
165         if (pos >= 1.0) {
166                 /*last frame*/
167                 if ((*ad)->on_end) {
168                         (*ad)->on_end(ad);
169                 } else {
170                         livebox_animator_del_grid(ad);
171                 }
172
173                 return ECORE_CALLBACK_CANCEL;
174         }
175
176         return ECORE_CALLBACK_RENEW;
177 }
178
179
180 static Eina_Bool __livebox_animator_set_grid_frame(void *data, double pos)
181 {
182         double frame = pos;
183
184         Anim_Data_t **ad = (Anim_Data_t **)data;
185         if (!(*ad)) {
186                 LOGE("(*ad) == NULL");
187                 return ECORE_CALLBACK_CANCEL;
188         }
189
190         int xs = (*ad)->geometry_start->x;
191         int ys = (*ad)->geometry_start->y;
192         int ws = (*ad)->geometry_start->w;
193         int hs = (*ad)->geometry_start->h;
194
195         int xe = (*ad)->geometry_end->x;
196         int ye = (*ad)->geometry_end->y;
197         int we = (*ad)->geometry_end->w;
198         int he = (*ad)->geometry_end->h;
199
200         int xd = xe - xs;
201         int yd = ye - ys;
202         int wd = we - ws;
203         int hd = he - hs;
204
205         frame = ecore_animator_pos_map(pos, (*ad)->map, (*ad)->map_var_1,
206                 (*ad)->map_var_2);
207
208         elm_grid_pack_set((*ad)->obj,
209                 xs + xd * frame,
210                 ys + yd * frame,
211                 ws + wd * frame,
212                 hs + hd * frame);
213
214
215         if (pos >= 1.0) {
216                 /*last frame*/
217                 if ((*ad)->on_end) {
218                         (*ad)->on_end(ad);
219                 } else {
220                         livebox_animator_del_grid(ad);
221                 }
222
223                 return ECORE_CALLBACK_CANCEL;
224         }
225
226         return ECORE_CALLBACK_RENEW;
227 }