blob: 8d477b49db313e26b4bc4ff2bb53c48b374b226a [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -07004 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090011 *
Bryce Harringtonaf637c22015-06-11 12:55:55 -070012 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090024 */
25
26#include <time.h>
27#include <assert.h>
28#include <stdlib.h>
29#include <stdio.h>
Lucas Tanure9b5fe422015-09-21 14:10:32 -030030#include <stdbool.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090031
32#include "ivi-layout-export.h"
33#include "ivi-layout-private.h"
34
35struct ivi_layout_transition;
36
37typedef void (*ivi_layout_transition_frame_func)(
38 struct ivi_layout_transition *transition);
39typedef void (*ivi_layout_transition_destroy_func)(
40 struct ivi_layout_transition *transition);
41typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
42
43struct ivi_layout_transition {
44 enum ivi_layout_transition_type type;
45 void *private_data;
46 void *user_data;
47
48 uint32_t time_start;
49 uint32_t time_duration;
50 uint32_t time_elapsed;
51 uint32_t is_done;
52 ivi_layout_is_transition_func is_transition_func;
53 ivi_layout_transition_frame_func frame_func;
54 ivi_layout_transition_destroy_func destroy_func;
55};
56
57struct transition_node {
58 struct ivi_layout_transition *transition;
59 struct wl_list link;
60};
61
62static void layout_transition_destroy(struct ivi_layout_transition *transition);
63
64static struct ivi_layout_transition *
65get_transition_from_type_and_id(enum ivi_layout_transition_type type,
66 void *id_data)
67{
68 struct ivi_layout *layout = get_instance();
69 struct transition_node *node;
70 struct ivi_layout_transition *tran;
71
72 wl_list_for_each(node, &layout->transitions->transition_list, link) {
73 tran = node->transition;
74
75 if (tran->type == type &&
76 tran->is_transition_func(tran->private_data, id_data))
77 return tran;
78 }
79
80 return NULL;
81}
82
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090083int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090084is_surface_transition(struct ivi_layout_surface *surface)
85{
86 struct ivi_layout *layout = get_instance();
87 struct transition_node *node;
88 struct ivi_layout_transition *tran;
89
90 wl_list_for_each(node, &layout->transitions->transition_list, link) {
91 tran = node->transition;
92
93 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
94 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
95 tran->is_transition_func(tran->private_data, surface))
96 return 1;
97 }
98
99 return 0;
100}
101
102static void
103tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
104{
105 const double t = timestamp - transition->time_start;
106
107 if (transition->time_duration <= t) {
108 transition->time_elapsed = transition->time_duration;
109 transition->is_done = 1;
110 } else {
111 transition->time_elapsed = t;
112 }
113}
114
115static float time_to_nowpos(struct ivi_layout_transition *transition)
116{
117 return sin((float)transition->time_elapsed /
118 (float)transition->time_duration * M_PI_2);
119}
120
121static void
122do_transition_frame(struct ivi_layout_transition *transition,
123 uint32_t timestamp)
124{
125 if (0 == transition->time_start)
126 transition->time_start = timestamp;
127
128 tick_transition(transition, timestamp);
129 transition->frame_func(transition);
130
131 if (transition->is_done)
132 layout_transition_destroy(transition);
133}
134
135static int32_t
136layout_transition_frame(void *data)
137{
138 struct ivi_layout_transition_set *transitions = data;
139 uint32_t fps = 30;
140 struct timespec timestamp = {};
141 uint32_t msec = 0;
142 struct transition_node *node = NULL;
143 struct transition_node *next = NULL;
144
145 if (wl_list_empty(&transitions->transition_list)) {
146 wl_event_source_timer_update(transitions->event_source, 0);
147 return 1;
148 }
149
150 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
151
152 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
153 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
154
155 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
156 do_transition_frame(node->transition, msec);
157 }
158
159 ivi_layout_commit_changes();
160 return 1;
161}
162
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900163struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900164ivi_layout_transition_set_create(struct weston_compositor *ec)
165{
166 struct ivi_layout_transition_set *transitions;
167 struct wl_event_loop *loop;
168
169 transitions = malloc(sizeof(*transitions));
170 if (transitions == NULL) {
171 weston_log("%s: memory allocation fails\n", __func__);
172 return NULL;
173 }
174
175 wl_list_init(&transitions->transition_list);
176
177 loop = wl_display_get_event_loop(ec->wl_display);
178 transitions->event_source =
179 wl_event_loop_add_timer(loop, layout_transition_frame,
180 transitions);
181
182 return transitions;
183}
184
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300185static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900186layout_transition_register(struct ivi_layout_transition *trans)
187{
188 struct ivi_layout *layout = get_instance();
189 struct transition_node *node;
190
191 node = malloc(sizeof(*node));
192 if (node == NULL) {
193 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300194 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900195 }
196
197 node->transition = trans;
198 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300199 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900200}
201
202static void
203remove_transition(struct ivi_layout *layout,
204 struct ivi_layout_transition *trans)
205{
206 struct transition_node *node;
207 struct transition_node *next;
208
209 wl_list_for_each_safe(node, next,
210 &layout->transitions->transition_list, link) {
211 if (node->transition == trans) {
212 wl_list_remove(&node->link);
213 free(node);
214 return;
215 }
216 }
217
218 wl_list_for_each_safe(node, next,
219 &layout->pending_transition_list, link) {
220 if (node->transition == trans) {
221 wl_list_remove(&node->link);
222 free(node);
223 return;
224 }
225 }
226}
227
228static void
229layout_transition_destroy(struct ivi_layout_transition *transition)
230{
231 struct ivi_layout *layout = get_instance();
232
233 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300234 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900235 transition->destroy_func(transition);
236 free(transition);
237}
238
239static struct ivi_layout_transition *
240create_layout_transition(void)
241{
242 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
243
244 if (transition == NULL) {
245 weston_log("%s: memory allocation fails\n", __func__);
246 return NULL;
247 }
248
249 transition->type = IVI_LAYOUT_TRANSITION_MAX;
250 transition->time_start = 0;
251 transition->time_duration = 300; /* 300ms */
252 transition->time_elapsed = 0;
253
254 transition->is_done = 0;
255
256 transition->private_data = NULL;
257 transition->user_data = NULL;
258
259 transition->frame_func = NULL;
260 transition->destroy_func = NULL;
261
262 return transition;
263}
264
265/* move and resize view transition */
266
267struct move_resize_view_data {
268 struct ivi_layout_surface *surface;
269 int32_t start_x;
270 int32_t start_y;
271 int32_t end_x;
272 int32_t end_y;
273 int32_t start_width;
274 int32_t start_height;
275 int32_t end_width;
276 int32_t end_height;
277};
278
279static void
280transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
281{
282 struct move_resize_view_data *data =
283 (struct move_resize_view_data *)transition->private_data;
284 struct ivi_layout_surface *layout_surface = data->surface;
285
286 wl_signal_emit(&layout_surface->configured, layout_surface);
287
288 if (transition->private_data) {
289 free(transition->private_data);
290 transition->private_data = NULL;
291 }
292}
293
294static void
295transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
296{
297 struct move_resize_view_data *mrv = transition->private_data;
298 const double current = time_to_nowpos(transition);
299
300 const int32_t destx = mrv->start_x +
301 (mrv->end_x - mrv->start_x) * current;
302
303 const int32_t desty = mrv->start_y +
304 (mrv->end_y - mrv->start_y) * current;
305
306 const int32_t dest_width = mrv->start_width +
307 (mrv->end_width - mrv->start_width) * current;
308
309 const int32_t dest_height = mrv->start_height +
310 (mrv->end_height - mrv->start_height) * current;
311
312 ivi_layout_surface_set_destination_rectangle(mrv->surface,
313 destx, desty,
314 dest_width, dest_height);
315}
316
317static int32_t
318is_transition_move_resize_view_func(struct move_resize_view_data *data,
319 struct ivi_layout_surface *view)
320{
321 return data->surface == view;
322}
323
324static struct ivi_layout_transition *
325create_move_resize_view_transition(
326 struct ivi_layout_surface *surface,
327 int32_t start_x, int32_t start_y,
328 int32_t end_x, int32_t end_y,
329 int32_t start_width, int32_t start_height,
330 int32_t end_width, int32_t end_height,
331 ivi_layout_transition_frame_func frame_func,
332 ivi_layout_transition_destroy_func destroy_func,
333 uint32_t duration)
334{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100335 struct ivi_layout_transition *transition;
336 struct move_resize_view_data *data;
337
338 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100339 if (transition == NULL)
340 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900341
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100342 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900343 if (data == NULL) {
344 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300345 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900346 return NULL;
347 }
348
349 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
350 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
351
352 transition->frame_func = frame_func;
353 transition->destroy_func = destroy_func;
354 transition->private_data = data;
355
356 if (duration != 0)
357 transition->time_duration = duration;
358
359 data->surface = surface;
360 data->start_x = start_x;
361 data->start_y = start_y;
362 data->end_x = end_x;
363 data->end_y = end_y;
364
365 data->start_width = start_width;
366 data->start_height = start_height;
367 data->end_width = end_width;
368 data->end_height = end_height;
369
370 return transition;
371}
372
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900373void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900374ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
375 int32_t dest_x, int32_t dest_y,
376 int32_t dest_width, int32_t dest_height,
377 uint32_t duration)
378{
379 struct ivi_layout_transition *transition;
380 int32_t start_pos[2] = {
381 surface->pending.prop.start_x,
382 surface->pending.prop.start_y
383 };
384
385 int32_t start_size[2] = {
386 surface->pending.prop.start_width,
387 surface->pending.prop.start_height
388 };
389
390 transition = get_transition_from_type_and_id(
391 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
392 surface);
393 if (transition) {
394 struct move_resize_view_data *data = transition->private_data;
395 transition->time_start = 0;
396 transition->time_duration = duration;
397
398 data->start_x = start_pos[0];
399 data->start_y = start_pos[1];
400 data->end_x = dest_x;
401 data->end_y = dest_y;
402
403 data->start_width = start_size[0];
404 data->start_height = start_size[1];
405 data->end_width = dest_width;
406 data->end_height = dest_height;
407 return;
408 }
409
410 transition = create_move_resize_view_transition(
411 surface,
412 start_pos[0], start_pos[1],
413 dest_x, dest_y,
414 start_size[0], start_size[1],
415 dest_width, dest_height,
416 transition_move_resize_view_user_frame,
417 transition_move_resize_view_destroy,
418 duration);
419
420 layout_transition_register(transition);
421}
422
423/* fade transition */
424struct fade_view_data {
425 struct ivi_layout_surface *surface;
426 double start_alpha;
427 double end_alpha;
428};
429
430struct store_alpha{
431 double alpha;
432};
433
434static void
435fade_view_user_frame(struct ivi_layout_transition *transition)
436{
437 struct fade_view_data *fade = transition->private_data;
438 struct ivi_layout_surface *surface = fade->surface;
439
440 const double current = time_to_nowpos(transition);
441 const double alpha = fade->start_alpha +
442 (fade->end_alpha - fade->start_alpha) * current;
443
444 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
445 ivi_layout_surface_set_visibility(surface, true);
446}
447
448static int32_t
449is_transition_fade_view_func(struct fade_view_data *data,
450 struct ivi_layout_surface *view)
451{
452 return data->surface == view;
453}
454
455static struct ivi_layout_transition *
456create_fade_view_transition(
457 struct ivi_layout_surface *surface,
458 double start_alpha, double end_alpha,
459 ivi_layout_transition_frame_func frame_func,
460 void *user_data,
461 ivi_layout_transition_destroy_func destroy_func,
462 uint32_t duration)
463{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100464 struct ivi_layout_transition *transition;
465 struct fade_view_data *data;
466
467 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100468 if (transition == NULL)
469 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900470
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100471 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900472 if (data == NULL) {
473 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300474 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900475 return NULL;
476 }
477
478 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
479 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
480
481 transition->user_data = user_data;
482 transition->private_data = data;
483 transition->frame_func = frame_func;
484 transition->destroy_func = destroy_func;
485
486 if (duration != 0)
487 transition->time_duration = duration;
488
489 data->surface = surface;
490 data->start_alpha = start_alpha;
491 data->end_alpha = end_alpha;
492
493 return transition;
494}
495
496static void
497create_visibility_transition(struct ivi_layout_surface *surface,
498 double start_alpha,
499 double dest_alpha,
500 void *user_data,
501 ivi_layout_transition_destroy_func destroy_func,
502 uint32_t duration)
503{
504 struct ivi_layout_transition *transition = NULL;
505
506 transition = create_fade_view_transition(
507 surface,
508 start_alpha, dest_alpha,
509 fade_view_user_frame,
510 user_data,
511 destroy_func,
512 duration);
513
514 layout_transition_register(transition);
515}
516
517static void
518visibility_on_transition_destroy(struct ivi_layout_transition *transition)
519{
520 struct fade_view_data *data = transition->private_data;
521 struct store_alpha *user_data = transition->user_data;
522
523 ivi_layout_surface_set_visibility(data->surface, true);
524
525 free(data);
526 transition->private_data = NULL;
527
528 free(user_data);
529 transition->user_data = NULL;
530}
531
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900532void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900533ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
534 uint32_t duration)
535{
536 struct ivi_layout_transition *transition;
537 bool is_visible = ivi_layout_surface_get_visibility(surface);
538 wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
539 struct store_alpha *user_data = NULL;
540 wl_fixed_t start_alpha = 0.0;
541 struct fade_view_data *data = NULL;
542
543 transition = get_transition_from_type_and_id(
544 IVI_LAYOUT_TRANSITION_VIEW_FADE,
545 surface);
546 if (transition) {
547 start_alpha = ivi_layout_surface_get_opacity(surface);
548 user_data = transition->user_data;
549 data = transition->private_data;
550
551 transition->time_start = 0;
552 transition->time_duration = duration;
553 transition->destroy_func = visibility_on_transition_destroy;
554
555 data->start_alpha = wl_fixed_to_double(start_alpha);
556 data->end_alpha = user_data->alpha;
557 return;
558 }
559
560 if (is_visible)
561 return;
562
563 user_data = malloc(sizeof(*user_data));
564 if (user_data == NULL) {
565 weston_log("%s: memory allocation fails\n", __func__);
566 return;
567 }
568
569 user_data->alpha = wl_fixed_to_double(dest_alpha);
570
571 create_visibility_transition(surface,
572 0.0, // start_alpha
573 wl_fixed_to_double(dest_alpha),
574 user_data,
575 visibility_on_transition_destroy,
576 duration);
577}
578
579static void
580visibility_off_transition_destroy(struct ivi_layout_transition *transition)
581{
582 struct fade_view_data *data = transition->private_data;
583 struct store_alpha *user_data = transition->user_data;
584
585 ivi_layout_surface_set_visibility(data->surface, false);
586
587 ivi_layout_surface_set_opacity(data->surface,
588 wl_fixed_from_double(user_data->alpha));
589
590 free(data);
591 transition->private_data = NULL;
592
593 free(user_data);
594 transition->user_data= NULL;
595}
596
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900597void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900598ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
599 uint32_t duration)
600{
601 struct ivi_layout_transition *transition;
602 wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
603 struct store_alpha* user_data = NULL;
604 struct fade_view_data* data = NULL;
605
606 transition =
607 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
608 surface);
609 if (transition) {
610 data = transition->private_data;
611
612 transition->time_start = 0;
613 transition->time_duration = duration;
614 transition->destroy_func = visibility_off_transition_destroy;
615
616 data->start_alpha = wl_fixed_to_double(start_alpha);
617 data->end_alpha = 0;
618 return;
619 }
620
621 user_data = malloc(sizeof(*user_data));
622 if (user_data == NULL) {
623 weston_log("%s: memory allocation fails\n", __func__);
624 return;
625 }
626
627 user_data->alpha = wl_fixed_to_double(start_alpha);
628
629 create_visibility_transition(surface,
630 wl_fixed_to_double(start_alpha),
631 0.0, // dest_alpha
632 user_data,
633 visibility_off_transition_destroy,
634 duration);
635}
636
637/* move layer transition */
638
639struct move_layer_data {
640 struct ivi_layout_layer *layer;
641 int32_t start_x;
642 int32_t start_y;
643 int32_t end_x;
644 int32_t end_y;
645 ivi_layout_transition_destroy_user_func destroy_func;
646};
647
648static void
649transition_move_layer_user_frame(struct ivi_layout_transition *transition)
650{
651 struct move_layer_data *data = transition->private_data;
652 struct ivi_layout_layer *layer = data->layer;
653
654 const float current = time_to_nowpos(transition);
655
656 const int32_t dest_x = data->start_x +
657 (data->end_x - data->start_x) * current;
658
659 const int32_t dest_y = data->start_y +
660 (data->end_y - data->start_y) * current;
661
662 ivi_layout_layer_set_position(layer, dest_x, dest_y);
663}
664
665static void
666transition_move_layer_destroy(struct ivi_layout_transition *transition)
667{
668 struct move_layer_data *data = transition->private_data;
669
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300670 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900671 data->destroy_func(transition->user_data);
672
673 free(data);
674 transition->private_data = NULL;
675}
676
677static int32_t
678is_transition_move_layer_func(struct move_layer_data *data,
679 struct ivi_layout_layer *layer)
680{
681 return data->layer == layer;
682}
683
684
685static struct ivi_layout_transition *
686create_move_layer_transition(
687 struct ivi_layout_layer *layer,
688 int32_t start_x, int32_t start_y,
689 int32_t end_x, int32_t end_y,
690 void *user_data,
691 ivi_layout_transition_destroy_user_func destroy_user_func,
692 uint32_t duration)
693{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100694 struct ivi_layout_transition *transition;
695 struct move_layer_data *data;
696
697 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100698 if (transition == NULL)
699 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900700
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100701 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900702 if (data == NULL) {
703 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300704 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900705 return NULL;
706 }
707
708 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
709 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
710
711 transition->frame_func = transition_move_layer_user_frame;
712 transition->destroy_func = transition_move_layer_destroy;
713 transition->private_data = data;
714 transition->user_data = user_data;
715
716 if (duration != 0)
717 transition->time_duration = duration;
718
719 data->layer = layer;
720 data->start_x = start_x;
721 data->start_y = start_y;
722 data->end_x = end_x;
723 data->end_y = end_y;
724 data->destroy_func = destroy_user_func;
725
726 return transition;
727}
728
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900729void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900730ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
731 int32_t dest_x, int32_t dest_y,
732 uint32_t duration)
733{
734 int32_t start_pos_x = 0;
735 int32_t start_pos_y = 0;
736 struct ivi_layout_transition *transition = NULL;
737
738 ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
739
740 transition = create_move_layer_transition(
741 layer,
742 start_pos_x, start_pos_y,
743 dest_x, dest_y,
744 NULL, NULL,
745 duration);
746
747 layout_transition_register(transition);
748
749 return;
750}
751
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900752void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900753ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
754{
755 struct ivi_layout_transition *transition =
756 get_transition_from_type_and_id(
757 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
758 layer);
759 if (transition) {
760 layout_transition_destroy(transition);
761 }
762}
763
764/* fade layer transition */
765struct fade_layer_data {
766 struct ivi_layout_layer *layer;
767 uint32_t is_fade_in;
768 double start_alpha;
769 double end_alpha;
770 ivi_layout_transition_destroy_user_func destroy_func;
771};
772
773static void
774transition_fade_layer_destroy(struct ivi_layout_transition *transition)
775{
776 struct fade_layer_data *data = transition->private_data;
777 transition->private_data = NULL;
778
779 free(data);
780}
781
782static void
783transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
784{
785 double current = time_to_nowpos(transition);
786 struct fade_layer_data *data = transition->private_data;
787 double alpha = data->start_alpha +
788 (data->end_alpha - data->start_alpha) * current;
789 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
790
791 int32_t is_done = transition->is_done;
792 bool is_visible = !is_done || data->is_fade_in;
793
794 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
795 ivi_layout_layer_set_visibility(data->layer, is_visible);
796}
797
798static int32_t
799is_transition_fade_layer_func(struct fade_layer_data *data,
800 struct ivi_layout_layer *layer)
801{
802 return data->layer == layer;
803}
804
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900805void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900806ivi_layout_transition_fade_layer(
807 struct ivi_layout_layer *layer,
808 uint32_t is_fade_in,
809 double start_alpha, double end_alpha,
810 void* user_data,
811 ivi_layout_transition_destroy_user_func destroy_func,
812 uint32_t duration)
813{
814 struct ivi_layout_transition *transition;
815 struct fade_layer_data *data = NULL;
816 wl_fixed_t fixed_opacity = 0.0;
817 double now_opacity = 0.0;
818 double remain = 0.0;
819
820 transition = get_transition_from_type_and_id(
821 IVI_LAYOUT_TRANSITION_LAYER_FADE,
822 layer);
823 if (transition) {
824 /* transition update */
825 data = transition->private_data;
826
827 /* FIXME */
828 fixed_opacity = ivi_layout_layer_get_opacity(layer);
829 now_opacity = wl_fixed_to_double(fixed_opacity);
830 remain = 0.0;
831
832 data->is_fade_in = is_fade_in;
833 data->start_alpha = now_opacity;
834 data->end_alpha = end_alpha;
835
836 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
837 transition->time_start = 0;
838 transition->time_elapsed = 0;
839 transition->time_duration = duration * remain;
840
841 return;
842 }
843
844 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100845 if (transition == NULL)
846 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900847
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100848 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900849 if (data == NULL) {
850 weston_log("%s: memory allocation fails\n", __func__);
851 return;
852 }
853
854 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
855 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
856
857 transition->private_data = data;
858 transition->user_data = user_data;
859
860 transition->frame_func = transition_fade_layer_user_frame;
861 transition->destroy_func = transition_fade_layer_destroy;
862
863 if (duration != 0)
864 transition->time_duration = duration;
865
866 data->layer = layer;
867 data->is_fade_in = is_fade_in;
868 data->start_alpha = start_alpha;
869 data->end_alpha = end_alpha;
870 data->destroy_func = destroy_func;
871
872 layout_transition_register(transition);
873
874 return;
875}
876