blob: 45b8dc5a537b04baba5015eee0aeecf71efeeb04 [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
Pekka Paalanenae8c3d82016-03-15 17:39:21 +020026#include "config.h"
27
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090028#include <time.h>
29#include <assert.h>
30#include <stdlib.h>
31#include <stdio.h>
Lucas Tanure9b5fe422015-09-21 14:10:32 -030032#include <stdbool.h>
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090033
34#include "ivi-layout-export.h"
35#include "ivi-layout-private.h"
36
37struct ivi_layout_transition;
38
39typedef void (*ivi_layout_transition_frame_func)(
40 struct ivi_layout_transition *transition);
41typedef void (*ivi_layout_transition_destroy_func)(
42 struct ivi_layout_transition *transition);
43typedef int32_t (*ivi_layout_is_transition_func)(void *private_data, void *id);
44
45struct ivi_layout_transition {
46 enum ivi_layout_transition_type type;
47 void *private_data;
48 void *user_data;
49
50 uint32_t time_start;
51 uint32_t time_duration;
52 uint32_t time_elapsed;
53 uint32_t is_done;
54 ivi_layout_is_transition_func is_transition_func;
55 ivi_layout_transition_frame_func frame_func;
56 ivi_layout_transition_destroy_func destroy_func;
57};
58
59struct transition_node {
60 struct ivi_layout_transition *transition;
61 struct wl_list link;
62};
63
64static void layout_transition_destroy(struct ivi_layout_transition *transition);
65
66static struct ivi_layout_transition *
67get_transition_from_type_and_id(enum ivi_layout_transition_type type,
68 void *id_data)
69{
70 struct ivi_layout *layout = get_instance();
71 struct transition_node *node;
72 struct ivi_layout_transition *tran;
73
74 wl_list_for_each(node, &layout->transitions->transition_list, link) {
75 tran = node->transition;
76
77 if (tran->type == type &&
78 tran->is_transition_func(tran->private_data, id_data))
79 return tran;
80 }
81
82 return NULL;
83}
84
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +090085int32_t
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +090086is_surface_transition(struct ivi_layout_surface *surface)
87{
88 struct ivi_layout *layout = get_instance();
89 struct transition_node *node;
90 struct ivi_layout_transition *tran;
91
92 wl_list_for_each(node, &layout->transitions->transition_list, link) {
93 tran = node->transition;
94
95 if ((tran->type == IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE ||
96 tran->type == IVI_LAYOUT_TRANSITION_VIEW_RESIZE) &&
97 tran->is_transition_func(tran->private_data, surface))
98 return 1;
99 }
100
101 return 0;
102}
103
Mateusz Polroladada6e32016-03-09 09:13:26 +0000104void
105ivi_layout_remove_all_surface_transitions(struct ivi_layout_surface *surface)
106{
107 struct ivi_layout *layout = get_instance();
108 struct transition_node *node;
109 struct transition_node *tmp;
110 struct ivi_layout_transition *tran;
111
112 wl_list_for_each_safe(node, tmp, &layout->transitions->transition_list, link) {
113 tran = node->transition;
114 if (tran->is_transition_func(tran->private_data, surface)) {
115 layout_transition_destroy(tran);
116 }
117 };
118}
119
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900120static void
121tick_transition(struct ivi_layout_transition *transition, uint32_t timestamp)
122{
123 const double t = timestamp - transition->time_start;
124
125 if (transition->time_duration <= t) {
126 transition->time_elapsed = transition->time_duration;
127 transition->is_done = 1;
128 } else {
129 transition->time_elapsed = t;
130 }
131}
132
133static float time_to_nowpos(struct ivi_layout_transition *transition)
134{
135 return sin((float)transition->time_elapsed /
136 (float)transition->time_duration * M_PI_2);
137}
138
139static void
140do_transition_frame(struct ivi_layout_transition *transition,
141 uint32_t timestamp)
142{
143 if (0 == transition->time_start)
144 transition->time_start = timestamp;
145
146 tick_transition(transition, timestamp);
147 transition->frame_func(transition);
148
149 if (transition->is_done)
150 layout_transition_destroy(transition);
151}
152
153static int32_t
154layout_transition_frame(void *data)
155{
156 struct ivi_layout_transition_set *transitions = data;
157 uint32_t fps = 30;
158 struct timespec timestamp = {};
159 uint32_t msec = 0;
160 struct transition_node *node = NULL;
161 struct transition_node *next = NULL;
162
163 if (wl_list_empty(&transitions->transition_list)) {
164 wl_event_source_timer_update(transitions->event_source, 0);
165 return 1;
166 }
167
168 wl_event_source_timer_update(transitions->event_source, 1000 / fps);
169
170 clock_gettime(CLOCK_MONOTONIC, &timestamp);/* FIXME */
171 msec = (1e+3 * timestamp.tv_sec + 1e-6 * timestamp.tv_nsec);
172
173 wl_list_for_each_safe(node, next, &transitions->transition_list, link) {
174 do_transition_frame(node->transition, msec);
175 }
176
177 ivi_layout_commit_changes();
178 return 1;
179}
180
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900181struct ivi_layout_transition_set *
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900182ivi_layout_transition_set_create(struct weston_compositor *ec)
183{
184 struct ivi_layout_transition_set *transitions;
185 struct wl_event_loop *loop;
186
187 transitions = malloc(sizeof(*transitions));
188 if (transitions == NULL) {
189 weston_log("%s: memory allocation fails\n", __func__);
190 return NULL;
191 }
192
193 wl_list_init(&transitions->transition_list);
194
195 loop = wl_display_get_event_loop(ec->wl_display);
196 transitions->event_source =
197 wl_event_loop_add_timer(loop, layout_transition_frame,
198 transitions);
199
200 return transitions;
201}
202
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300203static bool
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900204layout_transition_register(struct ivi_layout_transition *trans)
205{
206 struct ivi_layout *layout = get_instance();
207 struct transition_node *node;
208
209 node = malloc(sizeof(*node));
210 if (node == NULL) {
211 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300212 return false;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900213 }
214
215 node->transition = trans;
216 wl_list_insert(&layout->pending_transition_list, &node->link);
Lucas Tanure9b5fe422015-09-21 14:10:32 -0300217 return true;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900218}
219
220static void
221remove_transition(struct ivi_layout *layout,
222 struct ivi_layout_transition *trans)
223{
224 struct transition_node *node;
225 struct transition_node *next;
226
227 wl_list_for_each_safe(node, next,
228 &layout->transitions->transition_list, link) {
229 if (node->transition == trans) {
230 wl_list_remove(&node->link);
231 free(node);
232 return;
233 }
234 }
235
236 wl_list_for_each_safe(node, next,
237 &layout->pending_transition_list, link) {
238 if (node->transition == trans) {
239 wl_list_remove(&node->link);
240 free(node);
241 return;
242 }
243 }
244}
245
246static void
247layout_transition_destroy(struct ivi_layout_transition *transition)
248{
249 struct ivi_layout *layout = get_instance();
250
251 remove_transition(layout, transition);
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300252 if (transition->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900253 transition->destroy_func(transition);
254 free(transition);
255}
256
257static struct ivi_layout_transition *
258create_layout_transition(void)
259{
260 struct ivi_layout_transition *transition = malloc(sizeof(*transition));
261
262 if (transition == NULL) {
263 weston_log("%s: memory allocation fails\n", __func__);
264 return NULL;
265 }
266
267 transition->type = IVI_LAYOUT_TRANSITION_MAX;
268 transition->time_start = 0;
269 transition->time_duration = 300; /* 300ms */
270 transition->time_elapsed = 0;
271
272 transition->is_done = 0;
273
John-John Tedro9d7aff02015-09-20 02:47:37 +0200274 transition->is_transition_func = NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900275 transition->private_data = NULL;
276 transition->user_data = NULL;
277
278 transition->frame_func = NULL;
279 transition->destroy_func = NULL;
280
281 return transition;
282}
283
284/* move and resize view transition */
285
286struct move_resize_view_data {
287 struct ivi_layout_surface *surface;
288 int32_t start_x;
289 int32_t start_y;
290 int32_t end_x;
291 int32_t end_y;
292 int32_t start_width;
293 int32_t start_height;
294 int32_t end_width;
295 int32_t end_height;
296};
297
298static void
299transition_move_resize_view_destroy(struct ivi_layout_transition *transition)
300{
301 struct move_resize_view_data *data =
302 (struct move_resize_view_data *)transition->private_data;
303 struct ivi_layout_surface *layout_surface = data->surface;
304
305 wl_signal_emit(&layout_surface->configured, layout_surface);
306
307 if (transition->private_data) {
308 free(transition->private_data);
309 transition->private_data = NULL;
310 }
311}
312
313static void
314transition_move_resize_view_user_frame(struct ivi_layout_transition *transition)
315{
316 struct move_resize_view_data *mrv = transition->private_data;
317 const double current = time_to_nowpos(transition);
318
319 const int32_t destx = mrv->start_x +
320 (mrv->end_x - mrv->start_x) * current;
321
322 const int32_t desty = mrv->start_y +
323 (mrv->end_y - mrv->start_y) * current;
324
325 const int32_t dest_width = mrv->start_width +
326 (mrv->end_width - mrv->start_width) * current;
327
328 const int32_t dest_height = mrv->start_height +
329 (mrv->end_height - mrv->start_height) * current;
330
331 ivi_layout_surface_set_destination_rectangle(mrv->surface,
332 destx, desty,
333 dest_width, dest_height);
334}
335
336static int32_t
337is_transition_move_resize_view_func(struct move_resize_view_data *data,
338 struct ivi_layout_surface *view)
339{
340 return data->surface == view;
341}
342
343static struct ivi_layout_transition *
344create_move_resize_view_transition(
345 struct ivi_layout_surface *surface,
346 int32_t start_x, int32_t start_y,
347 int32_t end_x, int32_t end_y,
348 int32_t start_width, int32_t start_height,
349 int32_t end_width, int32_t end_height,
350 ivi_layout_transition_frame_func frame_func,
351 ivi_layout_transition_destroy_func destroy_func,
352 uint32_t duration)
353{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100354 struct ivi_layout_transition *transition;
355 struct move_resize_view_data *data;
356
357 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100358 if (transition == NULL)
359 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900360
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100361 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900362 if (data == NULL) {
363 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300364 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900365 return NULL;
366 }
367
368 transition->type = IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE;
369 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_resize_view_func;
370
371 transition->frame_func = frame_func;
372 transition->destroy_func = destroy_func;
373 transition->private_data = data;
374
375 if (duration != 0)
376 transition->time_duration = duration;
377
378 data->surface = surface;
379 data->start_x = start_x;
380 data->start_y = start_y;
381 data->end_x = end_x;
382 data->end_y = end_y;
383
384 data->start_width = start_width;
385 data->start_height = start_height;
386 data->end_width = end_width;
387 data->end_height = end_height;
388
389 return transition;
390}
391
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900392void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900393ivi_layout_transition_move_resize_view(struct ivi_layout_surface *surface,
394 int32_t dest_x, int32_t dest_y,
395 int32_t dest_width, int32_t dest_height,
396 uint32_t duration)
397{
398 struct ivi_layout_transition *transition;
399 int32_t start_pos[2] = {
400 surface->pending.prop.start_x,
401 surface->pending.prop.start_y
402 };
403
404 int32_t start_size[2] = {
405 surface->pending.prop.start_width,
406 surface->pending.prop.start_height
407 };
408
409 transition = get_transition_from_type_and_id(
410 IVI_LAYOUT_TRANSITION_VIEW_MOVE_RESIZE,
411 surface);
412 if (transition) {
413 struct move_resize_view_data *data = transition->private_data;
414 transition->time_start = 0;
415 transition->time_duration = duration;
416
417 data->start_x = start_pos[0];
418 data->start_y = start_pos[1];
419 data->end_x = dest_x;
420 data->end_y = dest_y;
421
422 data->start_width = start_size[0];
423 data->start_height = start_size[1];
424 data->end_width = dest_width;
425 data->end_height = dest_height;
426 return;
427 }
428
429 transition = create_move_resize_view_transition(
430 surface,
431 start_pos[0], start_pos[1],
432 dest_x, dest_y,
433 start_size[0], start_size[1],
434 dest_width, dest_height,
435 transition_move_resize_view_user_frame,
436 transition_move_resize_view_destroy,
437 duration);
438
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300439 if(transition && layout_transition_register(transition))
440 return;
441 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900442}
443
444/* fade transition */
445struct fade_view_data {
446 struct ivi_layout_surface *surface;
447 double start_alpha;
448 double end_alpha;
449};
450
451struct store_alpha{
452 double alpha;
453};
454
455static void
456fade_view_user_frame(struct ivi_layout_transition *transition)
457{
458 struct fade_view_data *fade = transition->private_data;
459 struct ivi_layout_surface *surface = fade->surface;
460
461 const double current = time_to_nowpos(transition);
462 const double alpha = fade->start_alpha +
463 (fade->end_alpha - fade->start_alpha) * current;
464
465 ivi_layout_surface_set_opacity(surface, wl_fixed_from_double(alpha));
466 ivi_layout_surface_set_visibility(surface, true);
467}
468
469static int32_t
470is_transition_fade_view_func(struct fade_view_data *data,
471 struct ivi_layout_surface *view)
472{
473 return data->surface == view;
474}
475
476static struct ivi_layout_transition *
477create_fade_view_transition(
478 struct ivi_layout_surface *surface,
479 double start_alpha, double end_alpha,
480 ivi_layout_transition_frame_func frame_func,
481 void *user_data,
482 ivi_layout_transition_destroy_func destroy_func,
483 uint32_t duration)
484{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100485 struct ivi_layout_transition *transition;
486 struct fade_view_data *data;
487
488 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100489 if (transition == NULL)
490 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900491
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100492 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900493 if (data == NULL) {
494 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300495 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900496 return NULL;
497 }
498
499 transition->type = IVI_LAYOUT_TRANSITION_VIEW_FADE;
500 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_view_func;
501
502 transition->user_data = user_data;
503 transition->private_data = data;
504 transition->frame_func = frame_func;
505 transition->destroy_func = destroy_func;
506
507 if (duration != 0)
508 transition->time_duration = duration;
509
510 data->surface = surface;
511 data->start_alpha = start_alpha;
512 data->end_alpha = end_alpha;
513
514 return transition;
515}
516
517static void
518create_visibility_transition(struct ivi_layout_surface *surface,
519 double start_alpha,
520 double dest_alpha,
521 void *user_data,
522 ivi_layout_transition_destroy_func destroy_func,
523 uint32_t duration)
524{
525 struct ivi_layout_transition *transition = NULL;
526
527 transition = create_fade_view_transition(
528 surface,
529 start_alpha, dest_alpha,
530 fade_view_user_frame,
531 user_data,
532 destroy_func,
533 duration);
534
Lucas Tanurea3377cd2015-09-30 09:38:37 -0300535 if (transition && layout_transition_register(transition))
536 return;
537 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900538}
539
540static void
541visibility_on_transition_destroy(struct ivi_layout_transition *transition)
542{
543 struct fade_view_data *data = transition->private_data;
544 struct store_alpha *user_data = transition->user_data;
545
546 ivi_layout_surface_set_visibility(data->surface, true);
547
548 free(data);
549 transition->private_data = NULL;
550
551 free(user_data);
552 transition->user_data = NULL;
553}
554
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900555void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900556ivi_layout_transition_visibility_on(struct ivi_layout_surface *surface,
557 uint32_t duration)
558{
559 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)c6a138c2016-03-04 12:50:06 +0000560 bool is_visible = surface->prop.visibility;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000561 wl_fixed_t dest_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900562 struct store_alpha *user_data = NULL;
563 wl_fixed_t start_alpha = 0.0;
564 struct fade_view_data *data = NULL;
565
566 transition = get_transition_from_type_and_id(
567 IVI_LAYOUT_TRANSITION_VIEW_FADE,
568 surface);
569 if (transition) {
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000570 start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900571 user_data = transition->user_data;
572 data = transition->private_data;
573
574 transition->time_start = 0;
575 transition->time_duration = duration;
576 transition->destroy_func = visibility_on_transition_destroy;
577
578 data->start_alpha = wl_fixed_to_double(start_alpha);
579 data->end_alpha = user_data->alpha;
580 return;
581 }
582
583 if (is_visible)
584 return;
585
586 user_data = malloc(sizeof(*user_data));
587 if (user_data == NULL) {
588 weston_log("%s: memory allocation fails\n", __func__);
589 return;
590 }
591
592 user_data->alpha = wl_fixed_to_double(dest_alpha);
593
594 create_visibility_transition(surface,
595 0.0, // start_alpha
596 wl_fixed_to_double(dest_alpha),
597 user_data,
598 visibility_on_transition_destroy,
599 duration);
600}
601
602static void
603visibility_off_transition_destroy(struct ivi_layout_transition *transition)
604{
605 struct fade_view_data *data = transition->private_data;
606 struct store_alpha *user_data = transition->user_data;
607
608 ivi_layout_surface_set_visibility(data->surface, false);
609
610 ivi_layout_surface_set_opacity(data->surface,
611 wl_fixed_from_double(user_data->alpha));
612
613 free(data);
614 transition->private_data = NULL;
615
616 free(user_data);
617 transition->user_data= NULL;
618}
619
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900620void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900621ivi_layout_transition_visibility_off(struct ivi_layout_surface *surface,
622 uint32_t duration)
623{
624 struct ivi_layout_transition *transition;
Ucan, Emre \(ADITG/SW1\)995e6fb2016-03-04 12:50:12 +0000625 wl_fixed_t start_alpha = surface->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900626 struct store_alpha* user_data = NULL;
627 struct fade_view_data* data = NULL;
628
629 transition =
630 get_transition_from_type_and_id(IVI_LAYOUT_TRANSITION_VIEW_FADE,
631 surface);
632 if (transition) {
633 data = transition->private_data;
634
635 transition->time_start = 0;
636 transition->time_duration = duration;
637 transition->destroy_func = visibility_off_transition_destroy;
638
639 data->start_alpha = wl_fixed_to_double(start_alpha);
640 data->end_alpha = 0;
641 return;
642 }
643
644 user_data = malloc(sizeof(*user_data));
645 if (user_data == NULL) {
646 weston_log("%s: memory allocation fails\n", __func__);
647 return;
648 }
649
650 user_data->alpha = wl_fixed_to_double(start_alpha);
651
652 create_visibility_transition(surface,
653 wl_fixed_to_double(start_alpha),
654 0.0, // dest_alpha
655 user_data,
656 visibility_off_transition_destroy,
657 duration);
658}
659
660/* move layer transition */
661
662struct move_layer_data {
663 struct ivi_layout_layer *layer;
664 int32_t start_x;
665 int32_t start_y;
666 int32_t end_x;
667 int32_t end_y;
668 ivi_layout_transition_destroy_user_func destroy_func;
669};
670
671static void
672transition_move_layer_user_frame(struct ivi_layout_transition *transition)
673{
674 struct move_layer_data *data = transition->private_data;
675 struct ivi_layout_layer *layer = data->layer;
676
677 const float current = time_to_nowpos(transition);
678
679 const int32_t dest_x = data->start_x +
680 (data->end_x - data->start_x) * current;
681
682 const int32_t dest_y = data->start_y +
683 (data->end_y - data->start_y) * current;
684
Ucan, Emre \(ADITG/SW1\)e62bfd82016-03-04 12:50:46 +0000685 ivi_layout_layer_set_destination_rectangle(layer, dest_x, dest_y,
686 layer->prop.dest_width, layer->prop.dest_height);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900687}
688
689static void
690transition_move_layer_destroy(struct ivi_layout_transition *transition)
691{
692 struct move_layer_data *data = transition->private_data;
693
Dawid Gajownik74a635b2015-08-06 17:12:19 -0300694 if (data->destroy_func)
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900695 data->destroy_func(transition->user_data);
696
697 free(data);
698 transition->private_data = NULL;
699}
700
701static int32_t
702is_transition_move_layer_func(struct move_layer_data *data,
703 struct ivi_layout_layer *layer)
704{
705 return data->layer == layer;
706}
707
708
709static struct ivi_layout_transition *
710create_move_layer_transition(
711 struct ivi_layout_layer *layer,
712 int32_t start_x, int32_t start_y,
713 int32_t end_x, int32_t end_y,
714 void *user_data,
715 ivi_layout_transition_destroy_user_func destroy_user_func,
716 uint32_t duration)
717{
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100718 struct ivi_layout_transition *transition;
719 struct move_layer_data *data;
720
721 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100722 if (transition == NULL)
723 return NULL;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900724
Carlos Olmedo Escobar703f5022015-03-02 13:24:36 +0100725 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900726 if (data == NULL) {
727 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanure9af00172015-09-21 11:24:35 -0300728 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900729 return NULL;
730 }
731
732 transition->type = IVI_LAYOUT_TRANSITION_LAYER_MOVE;
733 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_move_layer_func;
734
735 transition->frame_func = transition_move_layer_user_frame;
736 transition->destroy_func = transition_move_layer_destroy;
737 transition->private_data = data;
738 transition->user_data = user_data;
739
740 if (duration != 0)
741 transition->time_duration = duration;
742
743 data->layer = layer;
744 data->start_x = start_x;
745 data->start_y = start_y;
746 data->end_x = end_x;
747 data->end_y = end_y;
748 data->destroy_func = destroy_user_func;
749
750 return transition;
751}
752
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900753void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900754ivi_layout_transition_move_layer(struct ivi_layout_layer *layer,
755 int32_t dest_x, int32_t dest_y,
756 uint32_t duration)
757{
Ucan, Emre \(ADITG/SW1\)dfc2d762016-03-04 12:50:24 +0000758 int32_t start_pos_x = layer->prop.dest_x;
759 int32_t start_pos_y = layer->prop.dest_y;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900760 struct ivi_layout_transition *transition = NULL;
761
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900762 transition = create_move_layer_transition(
763 layer,
764 start_pos_x, start_pos_y,
765 dest_x, dest_y,
766 NULL, NULL,
767 duration);
768
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300769 if (transition && layout_transition_register(transition))
770 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900771
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300772 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900773}
774
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900775void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900776ivi_layout_transition_move_layer_cancel(struct ivi_layout_layer *layer)
777{
778 struct ivi_layout_transition *transition =
779 get_transition_from_type_and_id(
780 IVI_LAYOUT_TRANSITION_LAYER_MOVE,
781 layer);
782 if (transition) {
783 layout_transition_destroy(transition);
784 }
785}
786
787/* fade layer transition */
788struct fade_layer_data {
789 struct ivi_layout_layer *layer;
790 uint32_t is_fade_in;
791 double start_alpha;
792 double end_alpha;
793 ivi_layout_transition_destroy_user_func destroy_func;
794};
795
796static void
797transition_fade_layer_destroy(struct ivi_layout_transition *transition)
798{
799 struct fade_layer_data *data = transition->private_data;
800 transition->private_data = NULL;
801
802 free(data);
803}
804
805static void
806transition_fade_layer_user_frame(struct ivi_layout_transition *transition)
807{
808 double current = time_to_nowpos(transition);
809 struct fade_layer_data *data = transition->private_data;
810 double alpha = data->start_alpha +
811 (data->end_alpha - data->start_alpha) * current;
812 wl_fixed_t fixed_alpha = wl_fixed_from_double(alpha);
813
814 int32_t is_done = transition->is_done;
815 bool is_visible = !is_done || data->is_fade_in;
816
817 ivi_layout_layer_set_opacity(data->layer, fixed_alpha);
818 ivi_layout_layer_set_visibility(data->layer, is_visible);
819}
820
821static int32_t
822is_transition_fade_layer_func(struct fade_layer_data *data,
823 struct ivi_layout_layer *layer)
824{
825 return data->layer == layer;
826}
827
Nobuhiko Tanibataee8e5832014-12-15 13:25:39 +0900828void
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900829ivi_layout_transition_fade_layer(
830 struct ivi_layout_layer *layer,
831 uint32_t is_fade_in,
832 double start_alpha, double end_alpha,
833 void* user_data,
834 ivi_layout_transition_destroy_user_func destroy_func,
835 uint32_t duration)
836{
837 struct ivi_layout_transition *transition;
838 struct fade_layer_data *data = NULL;
839 wl_fixed_t fixed_opacity = 0.0;
840 double now_opacity = 0.0;
841 double remain = 0.0;
842
843 transition = get_transition_from_type_and_id(
844 IVI_LAYOUT_TRANSITION_LAYER_FADE,
845 layer);
846 if (transition) {
847 /* transition update */
848 data = transition->private_data;
849
850 /* FIXME */
Ucan, Emre \(ADITG/SW1\)c3aee1f2016-03-04 12:50:16 +0000851 fixed_opacity = layer->prop.opacity;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900852 now_opacity = wl_fixed_to_double(fixed_opacity);
853 remain = 0.0;
854
855 data->is_fade_in = is_fade_in;
856 data->start_alpha = now_opacity;
857 data->end_alpha = end_alpha;
858
859 remain = is_fade_in? 1.0 - now_opacity : now_opacity;
860 transition->time_start = 0;
861 transition->time_elapsed = 0;
862 transition->time_duration = duration * remain;
863
864 return;
865 }
866
867 transition = create_layout_transition();
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100868 if (transition == NULL)
869 return;
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900870
Carlos Olmedo Escobare82ba532015-01-17 19:43:02 +0100871 data = malloc(sizeof(*data));
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900872 if (data == NULL) {
873 weston_log("%s: memory allocation fails\n", __func__);
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300874 free(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900875 return;
876 }
877
878 transition->type = IVI_LAYOUT_TRANSITION_LAYER_FADE;
879 transition->is_transition_func = (ivi_layout_is_transition_func)is_transition_fade_layer_func;
880
881 transition->private_data = data;
882 transition->user_data = user_data;
883
884 transition->frame_func = transition_fade_layer_user_frame;
885 transition->destroy_func = transition_fade_layer_destroy;
886
887 if (duration != 0)
888 transition->time_duration = duration;
889
890 data->layer = layer;
891 data->is_fade_in = is_fade_in;
892 data->start_alpha = start_alpha;
893 data->end_alpha = end_alpha;
894 data->destroy_func = destroy_func;
895
Lucas Tanurec8dcd162015-09-23 10:33:21 -0300896 if (!layout_transition_register(transition))
897 layout_transition_destroy(transition);
Nobuhiko Tanibata6f9df652014-11-27 13:22:00 +0900898
899 return;
900}
901