blob: f691d35c3b0f49dc150fa1f5c76a13a4505a26fc [file] [log] [blame]
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +09001/*
2 * Copyright (C) 2014 DENSO CORPORATION
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include <time.h>
24#include <assert.h>
25#include <stdlib.h>
26#include <stdio.h>
27
28#include "ivi-layout-export.h"
29#include "ivi-layout-private.h"
30
31struct ivi_layout_transition;
32
33typedef void (*ivi_layout_transition_frame_func)(
34 struct ivi_layout_transition *transition);
35typedef void (*ivi_layout_transition_destroy_func)(
36 struct ivi_layout_transition *transition);
37typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
38
39struct ivi_layout_transition {
40 enum ivi_layout_transition_type type;
41 void *private_data;
42 void *user_data;
43
44 uint32_t time_start;
45 uint32_t time_duration;
46 uint32_t time_elapsed;
47 uint32_t is_done;
48 ivi_layout_is_transition_func is_transition_func;
49 ivi_layout_transition_frame_func frame_func;
50 ivi_layout_transition_destroy_func destroy_func;
51};
52
53struct transition_node {
54 struct ivi_layout_transition *transition;
55 struct wl_list link;
56};
57
58static void layout_transition_destroy(struct ivi_layout_transition *transition);
59
60static struct ivi_layout_transition *
61get_transition_from_type_and_id(enum ivi_layout_transition_type type,
62 void *id_data)
63{
64 struct ivi_layout *layout = get_instance();
65 struct transition_node *node;
66 struct ivi_layout_transition *tran;
67
68 wl_list_for_each(node, &layout->transitions->transition_list, link) {
69 tran = node->transition;
70
71 if (tran->type == type &&
72 tran->is_transition_func(tran->private_data, id_data))
73 return tran;
74 }
75
76 return NULL;
77}
78
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090079int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090080is_surface_transition(struct ivi_layout_surface *surface)
81{
82 struct ivi_layout *layout = get_instance();
83 struct transition_node *node;
84 struct ivi_layout_transition *tran;
85
86 wl_list_for_each(node, &layout->transitions->transition_list, link) {
87 tran = node->transition;
88
89 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
90 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
91 tran->is_transition_func(tran->private_data, surface))
92 return 1;
93 }
94
95 return 0;
96}
97
98static void
99tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
100{
101 const double t = timestamp - transition->time_start;
102
103 if (transition->time_duration <= t) {
104 transition->time_elapsed = transition->time_duration;
105 transition->is_done = 1;
106 } else {
107 transition->time_elapsed = t;
108 }
109}
110
111static float time_to_nowpos(struct ivi_layout_transition *transition)
112{
113 return sin((float)transition->time_elapsed /
114 (float)transition->time_duration * M_PI_2);
115}
116
117static void
118do_transition_frame(struct ivi_layout_transition *transition,
119 uint32_t timestamp)
120{
121 if (0 == transition->time_start)
122 transition->time_start = timestamp;
123
124 tick_transition(transition, timestamp);
125 transition->frame_func(transition);
126
127 if (transition->is_done)
128 layout_transition_destroy(transition);
129}
130
131static int32_t
132layout_transition_frame(void *data)
133{
134 struct ivi_layout_transition_set *transitions = data;
135 uint32_t fps = 30;
136 struct timespec timestamp = {};
137 uint32_t msec = 0;
138 struct transition_node *node = NULL;
139 struct transition_node *next = NULL;
140
141 if (wl_list_empty(&transitions->transition_list)) {
142 wl_event_source_timer_update(transitions->event_source, 0);
143 return 1;
144 }
145
146 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
147
148 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
149 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
150
151 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
152 do_transition_frame(node->transition, msec);
153 }
154
155 ivi_layout_commit_changes();
156 return 1;
157}
158
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900159struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900160ivi_layout_transition_set_create(struct weston_compositor *ec)
161{
162 struct ivi_layout_transition_set *transitions;
163 struct wl_event_loop *loop;
164
165 transitions = malloc(sizeof(*transitions));
166 if (transitions == NULL) {
167 weston_log("%s: memory allocation fails\n", __func__);
168 return NULL;
169 }
170
171 wl_list_init(&transitions->transition_list);
172
173 loop = wl_display_get_event_loop(ec->wl_display);
174 transitions->event_source =
175 wl_event_loop_add_timer(loop, layout_transition_frame,
176 transitions);
177
178 return transitions;
179}
180
181static void
182layout_transition_register(struct ivi_layout_transition *trans)
183{
184 struct ivi_layout *layout = get_instance();
185 struct transition_node *node;
186
187 node = malloc(sizeof(*node));
188 if (node == NULL) {
189 weston_log("%s: memory allocation fails\n", __func__);
190 return;
191 }
192
193 node->transition = trans;
194 wl_list_insert(&layout->pending_transition_list, &node->link);
195}
196
197static void
198remove_transition(struct ivi_layout *layout,
199 struct ivi_layout_transition *trans)
200{
201 struct transition_node *node;
202 struct transition_node *next;
203
204 wl_list_for_each_safe(node, next,
205 &layout->transitions->transition_list, link) {
206 if (node->transition == trans) {
207 wl_list_remove(&node->link);
208 free(node);
209 return;
210 }
211 }
212
213 wl_list_for_each_safe(node, next,
214 &layout->pending_transition_list, link) {
215 if (node->transition == trans) {
216 wl_list_remove(&node->link);
217 free(node);
218 return;
219 }
220 }
221}
222
223static void
224layout_transition_destroy(struct ivi_layout_transition *transition)
225{
226 struct ivi_layout *layout = get_instance();
227
228 remove_transition(layout, transition);
229 if(transition->destroy_func)
230 transition->destroy_func(transition);
231 free(transition);
232}
233
234static struct ivi_layout_transition *
235create_layout_transition(void)
236{
237 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
238
239 if (transition == NULL) {
240 weston_log("%s: memory allocation fails\n", __func__);
241 return NULL;
242 }
243
244 transition->type = IVI_LAYOUT_TRANSITION_MAX;
245 transition->time_start = 0;
246 transition->time_duration = 300; /* 300ms */
247 transition->time_elapsed = 0;
248
249 transition->is_done = 0;
250
251 transition->private_data = NULL;
252 transition->user_data = NULL;
253
254 transition->frame_func = NULL;
255 transition->destroy_func = NULL;
256
257 return transition;
258}
259
260/* move and resize view transition */
261
262struct move_resize_view_data {
263 struct ivi_layout_surface *surface;
264 int32_t start_x;
265 int32_t start_y;
266 int32_t end_x;
267 int32_t end_y;
268 int32_t start_width;
269 int32_t start_height;
270 int32_t end_width;
271 int32_t end_height;
272};
273
274static void
275transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
276{
277 struct move_resize_view_data *data =
278 (struct move_resize_view_data *)transition->private_data;
279 struct ivi_layout_surface *layout_surface = data->surface;
280
281 wl_signal_emit(&layout_surface->configured, layout_surface);
282
283 if (transition->private_data) {
284 free(transition->private_data);
285 transition->private_data = NULL;
286 }
287}
288
289static void
290transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
291{
292 struct move_resize_view_data *mrv = transition->private_data;
293 const double current = time_to_nowpos(transition);
294
295 const int32_t destx = mrv->start_x +
296 (mrv->end_x - mrv->start_x) * current;
297
298 const int32_t desty = mrv->start_y +
299 (mrv->end_y - mrv->start_y) * current;
300
301 const int32_t dest_width = mrv->start_width +
302 (mrv->end_width - mrv->start_width) * current;
303
304 const int32_t dest_height = mrv->start_height +
305 (mrv->end_height - mrv->start_height) * current;
306
307 ivi_layout_surface_set_destination_rectangle(mrv->surface,
308 destx, desty,
309 dest_width, dest_height);
310}
311
312static int32_t
313is_transition_move_resize_view_func(struct move_resize_view_data *data,
314 struct ivi_layout_surface *view)
315{
316 return data->surface == view;
317}
318
319static struct ivi_layout_transition *
320create_move_resize_view_transition(
321 struct ivi_layout_surface *surface,
322 int32_t start_x, int32_t start_y,
323 int32_t end_x, int32_t end_y,
324 int32_t start_width, int32_t start_height,
325 int32_t end_width, int32_t end_height,
326 ivi_layout_transition_frame_func frame_func,
327 ivi_layout_transition_destroy_func destroy_func,
328 uint32_t duration)
329{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100330 struct ivi_layout_transition *transition;
331 struct move_resize_view_data *data;
332
333 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100334 if (transition == NULL)
335 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900336
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100337 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900338 if (data == NULL) {
339 weston_log("%s: memory allocation fails\n", __func__);
340 return NULL;
341 }
342
343 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
344 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
345
346 transition->frame_func = frame_func;
347 transition->destroy_func = destroy_func;
348 transition->private_data = data;
349
350 if (duration != 0)
351 transition->time_duration = duration;
352
353 data->surface = surface;
354 data->start_x = start_x;
355 data->start_y = start_y;
356 data->end_x = end_x;
357 data->end_y = end_y;
358
359 data->start_width = start_width;
360 data->start_height = start_height;
361 data->end_width = end_width;
362 data->end_height = end_height;
363
364 return transition;
365}
366
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900367void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900368ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
369 int32_t dest_x, int32_t dest_y,
370 int32_t dest_width, int32_t dest_height,
371 uint32_t duration)
372{
373 struct ivi_layout_transition *transition;
374 int32_t start_pos[2] = {
375 surface->pending.prop.start_x,
376 surface->pending.prop.start_y
377 };
378
379 int32_t start_size[2] = {
380 surface->pending.prop.start_width,
381 surface->pending.prop.start_height
382 };
383
384 transition = get_transition_from_type_and_id(
385 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
386 surface);
387 if (transition) {
388 struct move_resize_view_data *data = transition->private_data;
389 transition->time_start = 0;
390 transition->time_duration = duration;
391
392 data->start_x = start_pos[0];
393 data->start_y = start_pos[1];
394 data->end_x = dest_x;
395 data->end_y = dest_y;
396
397 data->start_width = start_size[0];
398 data->start_height = start_size[1];
399 data->end_width = dest_width;
400 data->end_height = dest_height;
401 return;
402 }
403
404 transition = create_move_resize_view_transition(
405 surface,
406 start_pos[0], start_pos[1],
407 dest_x, dest_y,
408 start_size[0], start_size[1],
409 dest_width, dest_height,
410 transition_move_resize_view_user_frame,
411 transition_move_resize_view_destroy,
412 duration);
413
414 layout_transition_register(transition);
415}
416
417/* fade transition */
418struct fade_view_data {
419 struct ivi_layout_surface *surface;
420 double start_alpha;
421 double end_alpha;
422};
423
424struct store_alpha{
425 double alpha;
426};
427
428static void
429fade_view_user_frame(struct ivi_layout_transition *transition)
430{
431 struct fade_view_data *fade = transition->private_data;
432 struct ivi_layout_surface *surface = fade->surface;
433
434 const double current = time_to_nowpos(transition);
435 const double alpha = fade->start_alpha +
436 (fade->end_alpha - fade->start_alpha) * current;
437
438 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
439 ivi_layout_surface_set_visibility(surface, true);
440}
441
442static int32_t
443is_transition_fade_view_func(struct fade_view_data *data,
444 struct ivi_layout_surface *view)
445{
446 return data->surface == view;
447}
448
449static struct ivi_layout_transition *
450create_fade_view_transition(
451 struct ivi_layout_surface *surface,
452 double start_alpha, double end_alpha,
453 ivi_layout_transition_frame_func frame_func,
454 void *user_data,
455 ivi_layout_transition_destroy_func destroy_func,
456 uint32_t duration)
457{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100458 struct ivi_layout_transition *transition;
459 struct fade_view_data *data;
460
461 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100462 if (transition == NULL)
463 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900464
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100465 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900466 if (data == NULL) {
467 weston_log("%s: memory allocation fails\n", __func__);
468 return NULL;
469 }
470
471 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
472 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
473
474 transition->user_data = user_data;
475 transition->private_data = data;
476 transition->frame_func = frame_func;
477 transition->destroy_func = destroy_func;
478
479 if (duration != 0)
480 transition->time_duration = duration;
481
482 data->surface = surface;
483 data->start_alpha = start_alpha;
484 data->end_alpha = end_alpha;
485
486 return transition;
487}
488
489static void
490create_visibility_transition(struct ivi_layout_surface *surface,
491 double start_alpha,
492 double dest_alpha,
493 void *user_data,
494 ivi_layout_transition_destroy_func destroy_func,
495 uint32_t duration)
496{
497 struct ivi_layout_transition *transition = NULL;
498
499 transition = create_fade_view_transition(
500 surface,
501 start_alpha, dest_alpha,
502 fade_view_user_frame,
503 user_data,
504 destroy_func,
505 duration);
506
507 layout_transition_register(transition);
508}
509
510static void
511visibility_on_transition_destroy(struct ivi_layout_transition *transition)
512{
513 struct fade_view_data *data = transition->private_data;
514 struct store_alpha *user_data = transition->user_data;
515
516 ivi_layout_surface_set_visibility(data->surface, true);
517
518 free(data);
519 transition->private_data = NULL;
520
521 free(user_data);
522 transition->user_data = NULL;
523}
524
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900525void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900526ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
527 uint32_t duration)
528{
529 struct ivi_layout_transition *transition;
530 bool is_visible = ivi_layout_surface_get_visibility(surface);
531 wl_fixed_t dest_alpha = ivi_layout_surface_get_opacity(surface);
532 struct store_alpha *user_data = NULL;
533 wl_fixed_t start_alpha = 0.0;
534 struct fade_view_data *data = NULL;
535
536 transition = get_transition_from_type_and_id(
537 IVI_LAYOUT_TRANSITION_VIEW_FADE,
538 surface);
539 if (transition) {
540 start_alpha = ivi_layout_surface_get_opacity(surface);
541 user_data = transition->user_data;
542 data = transition->private_data;
543
544 transition->time_start = 0;
545 transition->time_duration = duration;
546 transition->destroy_func = visibility_on_transition_destroy;
547
548 data->start_alpha = wl_fixed_to_double(start_alpha);
549 data->end_alpha = user_data->alpha;
550 return;
551 }
552
553 if (is_visible)
554 return;
555
556 user_data = malloc(sizeof(*user_data));
557 if (user_data == NULL) {
558 weston_log("%s: memory allocation fails\n", __func__);
559 return;
560 }
561
562 user_data->alpha = wl_fixed_to_double(dest_alpha);
563
564 create_visibility_transition(surface,
565 0.0, // start_alpha
566 wl_fixed_to_double(dest_alpha),
567 user_data,
568 visibility_on_transition_destroy,
569 duration);
570}
571
572static void
573visibility_off_transition_destroy(struct ivi_layout_transition *transition)
574{
575 struct fade_view_data *data = transition->private_data;
576 struct store_alpha *user_data = transition->user_data;
577
578 ivi_layout_surface_set_visibility(data->surface, false);
579
580 ivi_layout_surface_set_opacity(data->surface,
581 wl_fixed_from_double(user_data->alpha));
582
583 free(data);
584 transition->private_data = NULL;
585
586 free(user_data);
587 transition->user_data= NULL;
588}
589
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900590void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900591ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
592 uint32_t duration)
593{
594 struct ivi_layout_transition *transition;
595 wl_fixed_t start_alpha = ivi_layout_surface_get_opacity(surface);
596 struct store_alpha* user_data = NULL;
597 struct fade_view_data* data = NULL;
598
599 transition =
600 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
601 surface);
602 if (transition) {
603 data = transition->private_data;
604
605 transition->time_start = 0;
606 transition->time_duration = duration;
607 transition->destroy_func = visibility_off_transition_destroy;
608
609 data->start_alpha = wl_fixed_to_double(start_alpha);
610 data->end_alpha = 0;
611 return;
612 }
613
614 user_data = malloc(sizeof(*user_data));
615 if (user_data == NULL) {
616 weston_log("%s: memory allocation fails\n", __func__);
617 return;
618 }
619
620 user_data->alpha = wl_fixed_to_double(start_alpha);
621
622 create_visibility_transition(surface,
623 wl_fixed_to_double(start_alpha),
624 0.0, // dest_alpha
625 user_data,
626 visibility_off_transition_destroy,
627 duration);
628}
629
630/* move layer transition */
631
632struct move_layer_data {
633 struct ivi_layout_layer *layer;
634 int32_t start_x;
635 int32_t start_y;
636 int32_t end_x;
637 int32_t end_y;
638 ivi_layout_transition_destroy_user_func destroy_func;
639};
640
641static void
642transition_move_layer_user_frame(struct ivi_layout_transition *transition)
643{
644 struct move_layer_data *data = transition->private_data;
645 struct ivi_layout_layer *layer = data->layer;
646
647 const float current = time_to_nowpos(transition);
648
649 const int32_t dest_x = data->start_x +
650 (data->end_x - data->start_x) * current;
651
652 const int32_t dest_y = data->start_y +
653 (data->end_y - data->start_y) * current;
654
655 ivi_layout_layer_set_position(layer, dest_x, dest_y);
656}
657
658static void
659transition_move_layer_destroy(struct ivi_layout_transition *transition)
660{
661 struct move_layer_data *data = transition->private_data;
662
663 if(data->destroy_func)
664 data->destroy_func(transition->user_data);
665
666 free(data);
667 transition->private_data = NULL;
668}
669
670static int32_t
671is_transition_move_layer_func(struct move_layer_data *data,
672 struct ivi_layout_layer *layer)
673{
674 return data->layer == layer;
675}
676
677
678static struct ivi_layout_transition *
679create_move_layer_transition(
680 struct ivi_layout_layer *layer,
681 int32_t start_x, int32_t start_y,
682 int32_t end_x, int32_t end_y,
683 void *user_data,
684 ivi_layout_transition_destroy_user_func destroy_user_func,
685 uint32_t duration)
686{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100687 struct ivi_layout_transition *transition;
688 struct move_layer_data *data;
689
690 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100691 if (transition == NULL)
692 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900693
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100694 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900695 if (data == NULL) {
696 weston_log("%s: memory allocation fails\n", __func__);
697 return NULL;
698 }
699
700 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
701 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
702
703 transition->frame_func = transition_move_layer_user_frame;
704 transition->destroy_func = transition_move_layer_destroy;
705 transition->private_data = data;
706 transition->user_data = user_data;
707
708 if (duration != 0)
709 transition->time_duration = duration;
710
711 data->layer = layer;
712 data->start_x = start_x;
713 data->start_y = start_y;
714 data->end_x = end_x;
715 data->end_y = end_y;
716 data->destroy_func = destroy_user_func;
717
718 return transition;
719}
720
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900721void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900722ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
723 int32_t dest_x, int32_t dest_y,
724 uint32_t duration)
725{
726 int32_t start_pos_x = 0;
727 int32_t start_pos_y = 0;
728 struct ivi_layout_transition *transition = NULL;
729
730 ivi_layout_layer_get_position(layer, &start_pos_x, &start_pos_y);
731
732 transition = create_move_layer_transition(
733 layer,
734 start_pos_x, start_pos_y,
735 dest_x, dest_y,
736 NULL, NULL,
737 duration);
738
739 layout_transition_register(transition);
740
741 return;
742}
743
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900744void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900745ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
746{
747 struct ivi_layout_transition *transition =
748 get_transition_from_type_and_id(
749 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
750 layer);
751 if (transition) {
752 layout_transition_destroy(transition);
753 }
754}
755
756/* fade layer transition */
757struct fade_layer_data {
758 struct ivi_layout_layer *layer;
759 uint32_t is_fade_in;
760 double start_alpha;
761 double end_alpha;
762 ivi_layout_transition_destroy_user_func destroy_func;
763};
764
765static void
766transition_fade_layer_destroy(struct ivi_layout_transition *transition)
767{
768 struct fade_layer_data *data = transition->private_data;
769 transition->private_data = NULL;
770
771 free(data);
772}
773
774static void
775transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
776{
777 double current = time_to_nowpos(transition);
778 struct fade_layer_data *data = transition->private_data;
779 double alpha = data->start_alpha +
780 (data->end_alpha - data->start_alpha) * current;
781 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
782
783 int32_t is_done = transition->is_done;
784 bool is_visible = !is_done || data->is_fade_in;
785
786 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
787 ivi_layout_layer_set_visibility(data->layer, is_visible);
788}
789
790static int32_t
791is_transition_fade_layer_func(struct fade_layer_data *data,
792 struct ivi_layout_layer *layer)
793{
794 return data->layer == layer;
795}
796
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900797void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900798ivi_layout_transition_fade_layer(
799 struct ivi_layout_layer *layer,
800 uint32_t is_fade_in,
801 double start_alpha, double end_alpha,
802 void* user_data,
803 ivi_layout_transition_destroy_user_func destroy_func,
804 uint32_t duration)
805{
806 struct ivi_layout_transition *transition;
807 struct fade_layer_data *data = NULL;
808 wl_fixed_t fixed_opacity = 0.0;
809 double now_opacity = 0.0;
810 double remain = 0.0;
811
812 transition = get_transition_from_type_and_id(
813 IVI_LAYOUT_TRANSITION_LAYER_FADE,
814 layer);
815 if (transition) {
816 /* transition update */
817 data = transition->private_data;
818
819 /* FIXME */
820 fixed_opacity = ivi_layout_layer_get_opacity(layer);
821 now_opacity = wl_fixed_to_double(fixed_opacity);
822 remain = 0.0;
823
824 data->is_fade_in = is_fade_in;
825 data->start_alpha = now_opacity;
826 data->end_alpha = end_alpha;
827
828 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
829 transition->time_start = 0;
830 transition->time_elapsed = 0;
831 transition->time_duration = duration * remain;
832
833 return;
834 }
835
836 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100837 if (transition == NULL)
838 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900839
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100840 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900841 if (data == NULL) {
842 weston_log("%s: memory allocation fails\n", __func__);
843 return;
844 }
845
846 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
847 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
848
849 transition->private_data = data;
850 transition->user_data = user_data;
851
852 transition->frame_func = transition_fade_layer_user_frame;
853 transition->destroy_func = transition_fade_layer_destroy;
854
855 if (duration != 0)
856 transition->time_duration = duration;
857
858 data->layer = layer;
859 data->is_fade_in = is_fade_in;
860 data->start_alpha = start_alpha;
861 data->end_alpha = end_alpha;
862 data->destroy_func = destroy_func;
863
864 layout_transition_register(transition);
865
866 return;
867}
868