/* * Copyright (C) 2013 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. */ const Lang = imports.lang; const Mainloop = imports.mainloop; const Gettext = imports.gettext; const _ = imports.gettext.gettext; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Clutter = imports.gi.Clutter; const ClutterGst = imports.gi.ClutterGst; const COLUMNS = 3; const ROWS = 3; if (ARGV.length < 2) throw "Need 2 arguments : video-wall.js videofile1 videofile2"; Clutter.init(null, null); ClutterGst.init(null, null); let stage = new Clutter.Stage(); stage.set_background_color(new Clutter.Color({ red: 0, green: 0, blue: 0, alpha: 0xff })); stage.connect('destroy', Lang.bind(this, function() { Clutter.main_quit(); })); let player1 = new ClutterGst.Playback(); player1.set_filename(ARGV[0]); player1.set_audio_volume(0); player1.set_progress(0.20); let player2 = new ClutterGst.Playback(); player2.set_filename(ARGV[1]); player2.set_audio_volume(0); player2.set_progress(0.20); let animateActor = function(actor, params) { let diffPropName = null; actor.save_easing_state(); actor.set_easing_duration(params.duration); actor.set_easing_mode(params.mode); for (let p in params.properties) { let t = actor.get_transition(p); if (t != null && t.is_playing()) return true; if (actor[p] != params.properties[p]) { actor[p] = params.properties[p]; diffPropName = p; } } actor.restore_easing_state(); if (diffPropName != null && params.onCompleted) { let transition = actor.get_transition(diffPropName); actor.connect('transition-stopped::' + diffPropName, Lang.bind(params.scope, function() { params.onCompleted(actor); })); } return (diffPropName != null); }; let actors = []; let positionActor = function(actorId) { let actor = actors[actorId % actors.length]; let stageWidth = stage.get_width(); let stageHeight = stage.get_height(); animateActor(actor, { duration: 500, mode: Clutter.AnimationMode.EASE_OUT_CUBIC, properties: { 'x': actor._myXPos * actor.width + (stageWidth / 2) - (COLUMNS * actor.width) / 2, 'y': actor._myYPos * actor.height + (stageHeight / 2) - (ROWS * actor.height) / 2, }, }); animateActor(actor._backActor, { duration: 500, mode: Clutter.AnimationMode.EASE_OUT_CUBIC, properties: { 'x': actor._myXPos * actor.width + (stageWidth / 2) - (COLUMNS * actor.width) / 2, 'y': actor._myYPos * actor.height + (stageHeight / 2) - (ROWS * actor.height) / 2, }, }); }; let positionActors = function() { for (let i = 0; i < actors.length; i++) positionActor(i); }; for (let i = 0; i < ROWS; i++) { for (let j = 0; j < COLUMNS; j++) { let input = new ClutterGst.Box({ x1: j / COLUMNS, x2: (j + 1) / COLUMNS, y1: i / ROWS, y2: (i + 1) / ROWS, }) let actor = new Clutter.Actor({ reactive: true, pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }), width: 200, height: 200, x: -200, y: -200, content: new ClutterGst.Crop({ cull_backface: true, input_region: input, player: player1, }), }); actor._backActor = new Clutter.Actor({ reactive: false, pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }), rotation_angle_y: 180, width: 200, height: 200, x: -200, y: -200, content: new ClutterGst.Crop({ cull_backface: true, input_region: input, player: player2, }), }); stage.add_child(actor); stage.add_child(actor._backActor); actor._myXPos = j; actor._myYPos = i; actor._backActor._myXPos = j; actor._backActor._myYPos = i; actors.push(actor); let animEnterParams = { duration: 350, mode: Clutter.AnimationMode.EASE_OUT_CUBIC, properties: { 'rotation-angle-y': 180, }, scope: this, onCompleted: function(actor) { if (actor._nextParams) { actor._inAnimation = animateActor(actor, actor._nextParams); actor._nextParams = null; } else { actor._inAnimation = false; } }, }; let animLeaveParams = { duration: 350, mode: Clutter.AnimationMode.EASE_OUT_CUBIC, properties: { 'rotation-angle-y': 0, }, scope: this, onCompleted: function(actor) { if (actor._nextParams) { actor._inAnimation = animateActor(actor, actor._nextParams); actor._nextParams = null; } else { actor._inAnimation = false; } }, }; actor.connect('enter-event', Lang.bind(this, function(actor, event) { if (!actor._inAnimation) { actor._inAnimation = animateActor(actor, animEnterParams); actor._backActor._inAnimation = animateActor(actor._backActor, animLeaveParams); } else { actor._nextParams = animEnterParams; actor._backActor._nextParams = animLeaveParams; } })); actor.connect('leave-event', Lang.bind(this, function(actor, event) { if (!actor._inAnimation) { actor._inAnimation = animateActor(actor, animLeaveParams); actor._backActor._inAnimation = animateActor(actor._backActor, animEnterParams); } else { actor._nextParams = animLeaveParams; actor._backActor._nextParams = animEnterParams; } })); } } stage.connect('allocation-changed', Lang.bind(this, function() { positionActors(); })); stage.set_user_resizable(true); player1.set_playing(true); player2.set_playing(true); stage.show(); Clutter.main();