blob: 6370e8f6db935633d57b7a092ae78151ea5e66d6 [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>
30
31#include "ivi-layout-export.h"
32#include "ivi-layout-private.h"
33
34struct ivi_layout_transition;
35
36typedef void (*ivi_layout_transition_frame_func)(
37 struct ivi_layout_transition *transition);
38typedef void (*ivi_layout_transition_destroy_func)(
39 struct ivi_layout_transition *transition);
40typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
41
42struct ivi_layout_transition {
43 enum ivi_layout_transition_type type;
44 void *private_data;
45 void *user_data;
46
47 uint32_t time_start;
48 uint32_t time_duration;
49 uint32_t time_elapsed;
50 uint32_t is_done;
51 ivi_layout_is_transition_func is_transition_func;
52 ivi_layout_transition_frame_func frame_func;
53 ivi_layout_transition_destroy_func destroy_func;
54};
55
56struct transition_node {
57 struct ivi_layout_transition *transition;
58 struct wl_list link;
59};
60
61static void layout_transition_destroy(struct ivi_layout_transition *transition);
62
63static struct ivi_layout_transition *
64get_transition_from_type_and_id(enum ivi_layout_transition_type type,
65 void *id_data)
66{
67 struct ivi_layout *layout = get_instance();
68 struct transition_node *node;
69 struct ivi_layout_transition *tran;
70
71 wl_list_for_each(node, &layout->transitions->transition_list, link) {
72 tran = node->transition;
73
74 if (tran->type == type &&
75 tran->is_transition_func(tran->private_data, id_data))
76 return tran;
77 }
78
79 return NULL;
80}
81
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090082int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090083is_surface_transition(struct ivi_layout_surface *surface)
84{
85 struct ivi_layout *layout = get_instance();
86 struct transition_node *node;
87 struct ivi_layout_transition *tran;
88
89 wl_list_for_each(node, &layout->transitions->transition_list, link) {
90 tran = node->transition;
91
92 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
93 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
94 tran->is_transition_func(tran->private_data, surface))
95 return 1;
96 }
97
98 return 0;
99}
100
101static void
102tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
103{
104 const double t = timestamp - transition->time_start;
105
106 if (transition->time_duration <= t) {
107 transition->time_elapsed = transition->time_duration;
108 transition->is_done = 1;
109 } else {
110 transition->time_elapsed = t;
111 }
112}
113
114static float time_to_nowpos(struct ivi_layout_transition *transition)
115{
116 return sin((float)transition->time_elapsed /
117 (float)transition->time_duration * M_PI_2);
118}
119
120static void
121do_transition_frame(struct ivi_layout_transition *transition,
122 uint32_t timestamp)
123{
124 if (0 == transition->time_start)
125 transition->time_start = timestamp;
126
127 tick_transition(transition, timestamp);
128 transition->frame_func(transition);
129
130 if (transition->is_done)
131 layout_transition_destroy(transition);
132}
133
134static int32_t
135layout_transition_frame(void *data)
136{
137 struct ivi_layout_transition_set *transitions = data;
138 uint32_t fps = 30;
139 struct timespec timestamp = {};
140 uint32_t msec = 0;
141 struct transition_node *node = NULL;
142 struct transition_node *next = NULL;
143
144 if (wl_list_empty(&transitions->transition_list)) {
145 wl_event_source_timer_update(transitions->event_source, 0);
146 return 1;
147 }
148
149 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
150
151 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
152 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
153
154 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
155 do_transition_frame(node->transition, msec);
156 }
157
158 ivi_layout_commit_changes();
159 return 1;
160}
161
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900162struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900163ivi_layout_transition_set_create(struct weston_compositor *ec)
164{
165 struct ivi_layout_transition_set *transitions;
166 struct wl_event_loop *loop;
167
168 transitions = malloc(sizeof(*transitions));
169 if (transitions == NULL) {
170 weston_log("%s: memory allocation fails\n", __func__);
171 return NULL;
172 }
173
174 wl_list_init(&transitions->transition_list);
175
176 loop = wl_display_get_event_loop(ec->wl_display);
177 transitions->event_source =
178 wl_event_loop_add_timer(loop, layout_transition_frame,
179 transitions);
180
181 return transitions;
182}
183
184static void
185layout_transition_register(struct ivi_layout_transition *trans)
186{
187 struct ivi_layout *layout = get_instance();
188 struct transition_node *node;
189
190 node = malloc(sizeof(*node));
191 if (node == NULL) {
192 weston_log("%s: memory allocation fails\n", __func__);
193 return;
194 }
195
196 node->transition = trans;
197 wl_list_insert(&layout->pending_transition_list, &node->link);
198}
199
200static void
201remove_transition(struct ivi_layout *layout,
202 struct ivi_layout_transition *trans)
203{
204 struct transition_node *node;
205 struct transition_node *next;
206
207 wl_list_for_each_safe(node, next,
208 &layout->transitions->transition_list, link) {
209 if (node->transition == trans) {
210 wl_list_remove(&node->link);
211 free(node);
212 return;
213 }
214 }
215
216 wl_list_for_each_safe(node, next,
217 &layout->pending_transition_list, link) {
218 if (node->transition == trans) {
219 wl_list_remove(&node->link);
220 free(node);
221 return;
222 }
223 }
224}
225
226static void
227layout_transition_destroy(struct ivi_layout_transition *transition)
228{
229 struct ivi_layout *layout = get_instance();
230
231 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300232 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900233 transition->destroy_func(transition);
234 free(transition);
235}
236
237static struct ivi_layout_transition *
238create_layout_transition(void)
239{
240 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
241
242 if (transition == NULL) {
243 weston_log("%s: memory allocation fails\n", __func__);
244 return NULL;
245 }
246
247 transition->type = IVI_LAYOUT_TRANSITION_MAX;
248 transition->time_start = 0;
249 transition->time_duration = 300; /* 300ms */
250 transition->time_elapsed = 0;
251
252 transition->is_done = 0;
253
254 transition->private_data = NULL;
255 transition->user_data = NULL;
256
257 transition->frame_func = NULL;
258 transition->destroy_func = NULL;
259
260 return transition;
261}
262
263/* move and resize view transition */
264
265struct move_resize_view_data {
266 struct ivi_layout_surface *surface;
267 int32_t start_x;
268 int32_t start_y;
269 int32_t end_x;
270 int32_t end_y;
271 int32_t start_width;
272 int32_t start_height;
273 int32_t end_width;
274 int32_t end_height;
275};
276
277static void
278transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
279{
280 struct move_resize_view_data *data =
281 (struct move_resize_view_data *)transition->private_data;
282 struct ivi_layout_surface *layout_surface = data->surface;
283
284 wl_signal_emit(&layout_surface->configured, layout_surface);
285
286 if (transition->private_data) {
287 free(transition->private_data);
288 transition->private_data = NULL;
289 }
290}
291
292static void
293transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
294{
295 struct move_resize_view_data *mrv = transition->private_data;
296 const double current = time_to_nowpos(transition);
297
298 const int32_t destx = mrv->start_x +
299 (mrv->end_x - mrv->start_x) * current;
300
301 const int32_t desty = mrv->start_y +
302 (mrv->end_y - mrv->start_y) * current;
303
304 const int32_t dest_width = mrv->start_width +
305 (mrv->end_width - mrv->start_width) * current;
306
307 const int32_t dest_height = mrv->start_height +
308 (mrv->end_height - mrv->start_height) * current;
309
310 ivi_layout_surface_set_destination_rectangle(mrv->surface,
311 destx, desty,
312 dest_width, dest_height);
313}
314
315static int32_t
316is_transition_move_resize_view_func(struct move_resize_view_data *data,
317 struct ivi_layout_surface *view)
318{
319 return data->surface == view;
320}
321
322static struct ivi_layout_transition *
323create_move_resize_view_transition(
324 struct ivi_layout_surface *surface,
325 int32_t start_x, int32_t start_y,
326 int32_t end_x, int32_t end_y,
327 int32_t start_width, int32_t start_height,
328 int32_t end_width, int32_t end_height,
329 ivi_layout_transition_frame_func frame_func,
330 ivi_layout_transition_destroy_func destroy_func,
331 uint32_t duration)
332{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100333 struct ivi_layout_transition *transition;
334 struct move_resize_view_data *data;
335
336 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100337 if (transition == NULL)
338 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900339
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100340 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900341 if (data == NULL) {
342 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300343 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900344 return NULL;
345 }
346
347 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
348 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
349
350 transition->frame_func = frame_func;
351 transition->destroy_func = destroy_func;
352 transition->private_data = data;
353
354 if (duration != 0)
355 transition->time_duration = duration;
356
357 data->surface = surface;
358 data->start_x = start_x;
359 data->start_y = start_y;
360 data->end_x = end_x;
361 data->end_y = end_y;
362
363 data->start_width = start_width;
364 data->start_height = start_height;
365 data->end_width = end_width;
366 data->end_height = end_height;
367
368 return transition;
369}
370
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900371void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900372ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
373 int32_t dest_x, int32_t dest_y,
374 int32_t dest_width, int32_t dest_height,
375 uint32_t duration)
376{
377 struct ivi_layout_transition *transition;
378 int32_t start_pos[2] = {
379 surface->pending.prop.start_x,
380 surface->pending.prop.start_y
381 };
382
383 int32_t start_size[2] = {
384 surface->pending.prop.start_width,
385 surface->pending.prop.start_height
386 };
387
388 transition = get_transition_from_type_and_id(
389 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
390 surface);
391 if (transition) {
392 struct move_resize_view_data *data = transition->private_data;
393 transition->time_start = 0;
394 transition->time_duration = duration;
395
396 data->start_x = start_pos[0];
397 data->start_y = start_pos[1];
398 data->end_x = dest_x;
399 data->end_y = dest_y;
400
401 data->start_width = start_size[0];
402 data->start_height = start_size[1];
403 data->end_width = dest_width;
404 data->end_height = dest_height;
405 return;
406 }
407
408 transition = create_move_resize_view_transition(
409 surface,
410 start_pos[0], start_pos[1],
411 dest_x, dest_y,
412 start_size[0], start_size[1],
413 dest_width, dest_height,
414 transition_move_resize_view_user_frame,
415 transition_move_resize_view_destroy,
416 duration);
417
418 layout_transition_register(transition);
419}
420
421/* fade transition */
422struct fade_view_data {
423 struct ivi_layout_surface *surface;
424 double start_alpha;
425 double end_alpha;
426};
427
428struct store_alpha{
429 double alpha;
430};
431
432static void
433fade_view_user_frame(struct ivi_layout_transition *transition)
434{
435 struct fade_view_data *fade = transition->private_data;
436 struct ivi_layout_surface *surface = fade->surface;
437
438 const double current = time_to_nowpos(transition);
439 const double alpha = fade->start_alpha +
440 (fade->end_alpha - fade->start_alpha) * current;
441
442 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
443 ivi_layout_surface_set_visibility(surface, true);
444}
445
446static int32_t
447is_transition_fade_view_func(struct fade_view_data *data,
448 struct ivi_layout_surface *view)
449{
450 return data->surface == view;
451}
452
453static struct ivi_layout_transition *
454create_fade_view_transition(
455 struct ivi_layout_surface *surface,
456 double start_alpha, double end_alpha,
457 ivi_layout_transition_frame_func frame_func,
458 void *user_data,
459 ivi_layout_transition_destroy_func destroy_func,
460 uint32_t duration)
461{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100462 struct ivi_layout_transition *transition;
463 struct fade_view_data *data;
464
465 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100466 if (transition == NULL)
467 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900468
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100469 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900470 if (data == NULL) {
471 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300472 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900473 return NULL;
474 }
475
476 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
477 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
478
479 transition->user_data = user_data;
480 transition->private_data = data;
481 transition->frame_func = frame_func;
482 transition->destroy_func = destroy_func;
483
484 if (duration != 0)
485 transition->time_duration = duration;
486
487 data->surface = surface;
488 data->start_alpha = start_alpha;
489 data->end_alpha = end_alpha;
490
491 return transition;
492}
493
494static void
495create_visibility_transition(struct ivi_layout_surface *surface,
496 double start_alpha,
497 double dest_alpha,
498 void *user_data,
499 ivi_layout_transition_destroy_func destroy_func,
500 uint32_t duration)
501{
502 struct ivi_layout_transition *transition = NULL;
503
504 transition = create_fade_view_transition(
505 surface,
506 start_alpha, dest_alpha,
507 fade_view_user_frame,
508 user_data,
509 destroy_func,
510 duration);
511
512 layout_transition_register(transition);
513}
514
515static void
516visibility_on_transition_destroy(struct ivi_layout_transition *transition)
517{
518 struct fade_view_data *data = transition->private_data;
519 struct store_alpha *user_data = transition->user_data;
520
521 ivi_layout_surface_set_visibility(data->surface, true);
522
523 free(data);
524 transition->private_data = NULL;
525
526 free(user_data);
527 transition->user_data = NULL;
528}
529
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900530void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900531ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
532 uint32_t duration)
533{
534 struct ivi_layout_transition *transition;
535 bool is_visible = ivi_layout_surface_get_visibility(surface);
536 wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
537 struct store_alpha *user_data = NULL;
538 wl_fixed_t start_alpha = 0.0;
539 struct fade_view_data *data = NULL;
540
541 transition = get_transition_from_type_and_id(
542 IVI_LAYOUT_TRANSITION_VIEW_FADE,
543 surface);
544 if (transition) {
545 start_alpha = ivi_layout_surface_get_opacity(surface);
546 user_data = transition->user_data;
547 data = transition->private_data;
548
549 transition->time_start = 0;
550 transition->time_duration = duration;
551 transition->destroy_func = visibility_on_transition_destroy;
552
553 data->start_alpha = wl_fixed_to_double(start_alpha);
554 data->end_alpha = user_data->alpha;
555 return;
556 }
557
558 if (is_visible)
559 return;
560
561 user_data = malloc(sizeof(*user_data));
562 if (user_data == NULL) {
563 weston_log("%s: memory allocation fails\n", __func__);
564 return;
565 }
566
567 user_data->alpha = wl_fixed_to_double(dest_alpha);
568
569 create_visibility_transition(surface,
570 0.0, // start_alpha
571 wl_fixed_to_double(dest_alpha),
572 user_data,
573 visibility_on_transition_destroy,
574 duration);
575}
576
577static void
578visibility_off_transition_destroy(struct ivi_layout_transition *transition)
579{
580 struct fade_view_data *data = transition->private_data;
581 struct store_alpha *user_data = transition->user_data;
582
583 ivi_layout_surface_set_visibility(data->surface, false);
584
585 ivi_layout_surface_set_opacity(data->surface,
586 wl_fixed_from_double(user_data->alpha));
587
588 free(data);
589 transition->private_data = NULL;
590
591 free(user_data);
592 transition->user_data= NULL;
593}
594
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900595void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900596ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
597 uint32_t duration)
598{
599 struct ivi_layout_transition *transition;
600 wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
601 struct store_alpha* user_data = NULL;
602 struct fade_view_data* data = NULL;
603
604 transition =
605 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
606 surface);
607 if (transition) {
608 data = transition->private_data;
609
610 transition->time_start = 0;
611 transition->time_duration = duration;
612 transition->destroy_func = visibility_off_transition_destroy;
613
614 data->start_alpha = wl_fixed_to_double(start_alpha);
615 data->end_alpha = 0;
616 return;
617 }
618
619 user_data = malloc(sizeof(*user_data));
620 if (user_data == NULL) {
621 weston_log("%s: memory allocation fails\n", __func__);
622 return;
623 }
624
625 user_data->alpha = wl_fixed_to_double(start_alpha);
626
627 create_visibility_transition(surface,
628 wl_fixed_to_double(start_alpha),
629 0.0, // dest_alpha
630 user_data,
631 visibility_off_transition_destroy,
632 duration);
633}
634
635/* move layer transition */
636
637struct move_layer_data {
638 struct ivi_layout_layer *layer;
639 int32_t start_x;
640 int32_t start_y;
641 int32_t end_x;
642 int32_t end_y;
643 ivi_layout_transition_destroy_user_func destroy_func;
644};
645
646static void
647transition_move_layer_user_frame(struct ivi_layout_transition *transition)
648{
649 struct move_layer_data *data = transition->private_data;
650 struct ivi_layout_layer *layer = data->layer;
651
652 const float current = time_to_nowpos(transition);
653
654 const int32_t dest_x = data->start_x +
655 (data->end_x - data->start_x) * current;
656
657 const int32_t dest_y = data->start_y +
658 (data->end_y - data->start_y) * current;
659
660 ivi_layout_layer_set_position(layer, dest_x, dest_y);
661}
662
663static void
664transition_move_layer_destroy(struct ivi_layout_transition *transition)
665{
666 struct move_layer_data *data = transition->private_data;
667
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300668 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900669 data->destroy_func(transition->user_data);
670
671 free(data);
672 transition->private_data = NULL;
673}
674
675static int32_t
676is_transition_move_layer_func(struct move_layer_data *data,
677 struct ivi_layout_layer *layer)
678{
679 return data->layer == layer;
680}
681
682
683static struct ivi_layout_transition *
684create_move_layer_transition(
685 struct ivi_layout_layer *layer,
686 int32_t start_x, int32_t start_y,
687 int32_t end_x, int32_t end_y,
688 void *user_data,
689 ivi_layout_transition_destroy_user_func destroy_user_func,
690 uint32_t duration)
691{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100692 struct ivi_layout_transition *transition;
693 struct move_layer_data *data;
694
695 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100696 if (transition == NULL)
697 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900698
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100699 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900700 if (data == NULL) {
701 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300702 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900703 return NULL;
704 }
705
706 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
707 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
708
709 transition->frame_func = transition_move_layer_user_frame;
710 transition->destroy_func = transition_move_layer_destroy;
711 transition->private_data = data;
712 transition->user_data = user_data;
713
714 if (duration != 0)
715 transition->time_duration = duration;
716
717 data->layer = layer;
718 data->start_x = start_x;
719 data->start_y = start_y;
720 data->end_x = end_x;
721 data->end_y = end_y;
722 data->destroy_func = destroy_user_func;
723
724 return transition;
725}
726
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900727void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900728ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
729 int32_t dest_x, int32_t dest_y,
730 uint32_t duration)
731{
732 int32_t start_pos_x = 0;
733 int32_t start_pos_y = 0;
734 struct ivi_layout_transition *transition = NULL;
735
736 ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
737
738 transition = create_move_layer_transition(
739 layer,
740 start_pos_x, start_pos_y,
741 dest_x, dest_y,
742 NULL, NULL,
743 duration);
744
745 layout_transition_register(transition);
746
747 return;
748}
749
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900750void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900751ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
752{
753 struct ivi_layout_transition *transition =
754 get_transition_from_type_and_id(
755 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
756 layer);
757 if (transition) {
758 layout_transition_destroy(transition);
759 }
760}
761
762/* fade layer transition */
763struct fade_layer_data {
764 struct ivi_layout_layer *layer;
765 uint32_t is_fade_in;
766 double start_alpha;
767 double end_alpha;
768 ivi_layout_transition_destroy_user_func destroy_func;
769};
770
771static void
772transition_fade_layer_destroy(struct ivi_layout_transition *transition)
773{
774 struct fade_layer_data *data = transition->private_data;
775 transition->private_data = NULL;
776
777 free(data);
778}
779
780static void
781transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
782{
783 double current = time_to_nowpos(transition);
784 struct fade_layer_data *data = transition->private_data;
785 double alpha = data->start_alpha +
786 (data->end_alpha - data->start_alpha) * current;
787 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
788
789 int32_t is_done = transition->is_done;
790 bool is_visible = !is_done || data->is_fade_in;
791
792 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
793 ivi_layout_layer_set_visibility(data->layer, is_visible);
794}
795
796static int32_t
797is_transition_fade_layer_func(struct fade_layer_data *data,
798 struct ivi_layout_layer *layer)
799{
800 return data->layer == layer;
801}
802
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900803void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900804ivi_layout_transition_fade_layer(
805 struct ivi_layout_layer *layer,
806 uint32_t is_fade_in,
807 double start_alpha, double end_alpha,
808 void* user_data,
809 ivi_layout_transition_destroy_user_func destroy_func,
810 uint32_t duration)
811{
812 struct ivi_layout_transition *transition;
813 struct fade_layer_data *data = NULL;
814 wl_fixed_t fixed_opacity = 0.0;
815 double now_opacity = 0.0;
816 double remain = 0.0;
817
818 transition = get_transition_from_type_and_id(
819 IVI_LAYOUT_TRANSITION_LAYER_FADE,
820 layer);
821 if (transition) {
822 /* transition update */
823 data = transition->private_data;
824
825 /* FIXME */
826 fixed_opacity = ivi_layout_layer_get_opacity(layer);
827 now_opacity = wl_fixed_to_double(fixed_opacity);
828 remain = 0.0;
829
830 data->is_fade_in = is_fade_in;
831 data->start_alpha = now_opacity;
832 data->end_alpha = end_alpha;
833
834 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
835 transition->time_start = 0;
836 transition->time_elapsed = 0;
837 transition->time_duration = duration * remain;
838
839 return;
840 }
841
842 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100843 if (transition == NULL)
844 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900845
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100846 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900847 if (data == NULL) {
848 weston_log("%s: memory allocation fails\n", __func__);
849 return;
850 }
851
852 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
853 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
854
855 transition->private_data = data;
856 transition->user_data = user_data;
857
858 transition->frame_func = transition_fade_layer_user_frame;
859 transition->destroy_func = transition_fade_layer_destroy;
860
861 if (duration != 0)
862 transition->time_duration = duration;
863
864 data->layer = layer;
865 data->is_fade_in = is_fade_in;
866 data->start_alpha = start_alpha;
867 data->end_alpha = end_alpha;
868 data->destroy_func = destroy_func;
869
870 layout_transition_register(transition);
871
872 return;
873}
874