180b0435f77c12f26013e1c3e0e916452581e6c4
[platform/core/uifw/libscl-ui-nui.git] / scl / sclanimator.cpp
1 /*
2  * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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
18 #include "sclanimator.h"
19 #ifdef  __WIN32__
20 #include "sclanimator-win32.h"
21 #elif defined(__EFL__)
22 #include "sclanimator-efl.h"
23 #elif defined(__NUI__)
24 #include "sclanimator-nui.h"
25 #elif __GTK__
26 #include "sclanimator-gtk.h"
27 #else
28 #include "sclanimator-cairo.h"
29 #endif
30 #include "scldebug.h"
31
32 #include "sclevents.h"
33 #include "sclwindows.h"
34
35 using namespace scl;
36
37 CSCLAnimator::CSCLAnimator()
38 {
39     SCL_DEBUG();
40     m_impl = NULL;
41 }
42
43 CSCLAnimator::~CSCLAnimator()
44 {
45     SCL_DEBUG();
46
47     if (m_impl) {
48         delete m_impl;
49         m_impl = NULL;
50     }
51 }
52
53 void CSCLAnimator::init()
54 {
55     CSCLAnimatorImpl *impl = get_scl_animator_impl();
56     if (impl) {
57         impl->init();
58     }
59 }
60
61 void CSCLAnimator::fini()
62 {
63     CSCLAnimatorImpl *impl = get_scl_animator_impl();
64     if (impl) {
65         impl->fini();
66     }
67 }
68
69 sclboolean CSCLAnimator::check_animation_supported()
70 {
71     sclboolean ret = FALSE;
72
73     CSCLAnimatorImpl *impl = get_scl_animator_impl();
74     if (impl) {
75         ret = impl->check_animation_supported();
76     }
77     return ret;
78 }
79
80 CSCLAnimatorImpl* CSCLAnimator::get_scl_animator_impl()
81 {
82     SCL_DEBUG();
83     if (m_impl == 0) {
84 #ifdef  __WIN32__
85         m_impl = new CSCLAnimatorImplWin32;
86 #elif defined(__EFL__)
87         m_impl = new CSCLAnimatorImplEfl;
88 #elif defined(__NUI__)
89         m_impl = new CSCLAnimatorImplNui;
90 #elif __GTK__
91         m_impl = new CSCLAnimatorImplGtk;
92 #else
93         m_impl = new CSCLAnimatorImplCairo;
94 #endif
95     }
96     return m_impl;
97 }
98
99 CSCLAnimator* CSCLAnimator::get_instance()
100 {
101     static CSCLAnimator instance;
102     return &instance;
103 }
104
105 sclint
106 CSCLAnimator::create_animator(SclAnimationDesc *desc)
107 {
108     static sclint animator_id = 0;
109
110     if (desc) {
111         animator_id++;
112         /* Just in case for overflow */
113         if (animator_id < 0) animator_id = 0;
114
115         SclAnimationState state;
116         state.active = FALSE;
117         state.rect_cur = desc->rect_from;
118         state.step = 0;
119
120         state.desc = *desc;
121
122         destroy_animator(animator_id);
123         m_animators[animator_id] = state;
124     } else {
125         return NOT_USED;
126     }
127
128     return animator_id;
129 }
130
131 sclboolean
132 CSCLAnimator::destroy_animator(sclint id)
133 {
134     sclboolean ret = TRUE;
135
136     std::map<sclint, SclAnimationState>::iterator iter;
137     iter = m_animators.find(id);
138     if (iter != m_animators.end()) {
139         SclAnimationState *state = &(iter->second);
140         state->active = FALSE;
141         m_animators.erase(iter->first);
142     } else {
143         ret = FALSE;
144     }
145
146     sclboolean destroy_timer = TRUE;
147     for (iter = m_animators.begin();iter != m_animators.end();std::advance(iter, 1)) {
148         if (iter != m_animators.end()) {
149             SclAnimationState *state = &(iter->second);
150             if (state->active) {
151                 destroy_timer = FALSE;
152             }
153         }
154     }
155
156     if (destroy_timer) {
157         CSCLEvents *events = CSCLEvents::get_instance();
158         if (events) {
159             events->destroy_timer(SCL_TIMER_ANIMATION);
160         }
161     }
162
163     return ret;
164 }
165
166 sclint
167 CSCLAnimator::find_animator_by_type(SCLAnimationType type)
168 {
169     sclint ret = NOT_USED;
170
171     for (std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
172         iter != m_animators.end();std::advance(iter, 1)) {
173             if (iter != m_animators.end()) {
174                 SclAnimationState *state = &(iter->second);
175                 if (state->desc.type == type) {
176                     ret = iter->first;
177                 }
178             }
179     }
180
181     return ret;
182 }
183
184
185 SclAnimationState*
186 CSCLAnimator::get_animation_state(sclint id)
187 {
188     SclAnimationState *ret = NULL;
189
190     std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
191     if (iter != m_animators.end()) {
192         ret = &(iter->second);
193     } else {
194         ret = NULL;
195     }
196
197     return ret;
198 }
199
200 sclboolean
201 CSCLAnimator::start_animator(sclint id)
202 {
203     sclboolean ret = TRUE;
204
205     std::map<sclint, SclAnimationState>::iterator iter = m_animators.find(id);
206     if (iter != m_animators.end()) {
207         SclAnimationState *state = &(iter->second);
208         state->active = TRUE;
209     } else {
210         ret = FALSE;
211     }
212
213     /*
214     sclboolean start_timer = TRUE;
215     for(std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
216         iter != m_animators.end();std::advance(iter, 1)) {
217             if (iter != m_animators.end()) {
218                 SclAnimationState *state = &(iter->second);
219                 if (state->active) {
220                     start_timer = FALSE;
221                 }
222             }
223     }
224
225     if (start_timer) {
226         CSCLEvents *events = CSCLEvents::get_instance();
227         if (events) {
228             events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
229         }
230     }
231     */
232     CSCLEvents *events = CSCLEvents::get_instance();
233     if (events) {
234         events->destroy_timer(SCL_TIMER_ANIMATION);
235         events->create_timer(SCL_TIMER_ANIMATION, SCL_ANIMATION_TIMER_INTERVAL, 0);
236     }
237
238     return ret;
239 }
240
241 sclboolean
242 CSCLAnimator::stop_animator(sclint id)
243 {
244     sclboolean ret = TRUE;
245
246     std::map<sclint, SclAnimationState>::iterator iter;
247     iter = m_animators.find(id);
248     if (iter != m_animators.end()) {
249         SclAnimationState *state = &(iter->second);
250         state->active = FALSE;
251         m_animators.erase(iter->first);
252     } else {
253         ret = FALSE;
254     }
255
256     sclboolean destroy_timer = TRUE;
257     for (iter = m_animators.begin();iter != m_animators.end();std::advance(iter, 1)) {
258         if (iter != m_animators.end()) {
259             SclAnimationState *state = &(iter->second);
260             if (state->active) {
261                 destroy_timer = FALSE;
262             }
263         }
264     }
265
266     if (destroy_timer) {
267         CSCLEvents *events = CSCLEvents::get_instance();
268         if (events) {
269             events->destroy_timer(SCL_TIMER_ANIMATION);
270         }
271     }
272
273     return ret;
274 }
275
276 sclboolean
277 CSCLAnimator::animator_timer_highlight_ui(SclAnimationState *state)
278 {
279     sclboolean ret = TRUE;
280
281     CSCLWindows *windows = CSCLWindows::get_instance();
282
283     if (state && windows) {
284         SclRectangle rect_from = state->desc.rect_from;
285         SclRectangle rect_to = state->desc.rect_to;
286
287         sclint delta_x = 0; /* We will calculate the X considering circulation */
288         sclint delta_y = rect_to.y - rect_from.y;
289         sclint delta_width = rect_to.width - rect_from.width;
290         sclint delta_height = rect_to.height - rect_from.height;
291
292         state->rect_cur.y = rect_from.y +
293             ((delta_y) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
294         state->rect_cur.width = rect_from.width +
295             ((delta_width) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
296         state->rect_cur.height = rect_from.height +
297             ((delta_height) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
298
299         if (state->desc.circular) {
300             SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
301             if (base_window_context) {
302                 if (rect_from.x > rect_to.x) {
303                     delta_x = rect_to.x;
304                     delta_x += (base_window_context->geometry.width - rect_from.x);
305                 } else {
306                     delta_x = -(rect_from.x);
307                     delta_x -= (base_window_context->geometry.width - rect_to.x);
308                 }
309
310                 state->rect_cur.x = rect_from.x +
311                     ((delta_x) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
312
313                 if (state->rect_cur.x + state->rect_cur.width <= 0) {
314                     /* Make the highlight UI come out from the right side of the window */
315                     state->rect_cur.x += base_window_context->geometry.width;
316                 } else if (state->rect_cur.x > base_window_context->geometry.width) {
317                     state->rect_cur.x -= base_window_context->geometry.width;
318                 }
319             }
320         } else {
321             delta_x = rect_to.x - rect_from.x;
322
323             state->rect_cur.x = rect_from.x +
324                 ((delta_x) * state->step * SCL_ANIMATION_TIMER_INTERVAL) / state->desc.length;
325         }
326     }
327
328     return ret;
329 }
330 sclboolean
331 CSCLAnimator::animator_timer()
332 {
333     sclboolean destroy_timer = TRUE;
334     for (std::map<sclint, SclAnimationState>::iterator iter = m_animators.begin();
335         iter != m_animators.end();std::advance(iter, 1)) {
336             if (iter != m_animators.end()) {
337                 CSCLWindows *windows = CSCLWindows::get_instance();
338                 SclAnimationState *state = &(iter->second);
339                 if (state && state->active && windows) {
340                     state->step++;
341                     if (SCL_ANIMATION_TIMER_INTERVAL * state->step >= state->desc.length) {
342                         state->active = FALSE;
343                     } else {
344                         if (state->desc.type == ANIMATION_TYPE_HIGHLIGHT_UI) {
345                             animator_timer_highlight_ui(state);
346                         }
347                     }
348
349                     CSCLAnimatorImpl *impl = get_scl_animator_impl();
350                     if (impl) {
351                         impl->animator_timer(state);
352                     }
353
354                     if (state->active == FALSE) {
355                         windows->update_window(state->desc.window_to,
356                             state->desc.rect_to.x, state->desc.rect_to.y,
357                             state->desc.rect_to.width, state->desc.rect_to.height);
358                     } else {
359                         destroy_timer = FALSE;
360                     }
361                 }
362             }
363     }
364     if (destroy_timer) {
365         CSCLEvents *events = CSCLEvents::get_instance();
366         if (events) {
367             events->destroy_timer(SCL_TIMER_ANIMATION);
368         }
369     }
370     return TRUE;
371 }
372